diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index bbfbf9ae..c9422715 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,6 +1,10 @@
 name: Build
 
-on: [ pull_request ]
+on:
+  pull_request:
+  push:
+    branches:
+      - main
 
 jobs:
   Linux-Build:
@@ -8,8 +12,8 @@ jobs:
     strategy:
       matrix:
         command: [
-          './gradlew :app:platform:jvm:assemble',
-          './gradlew :app:platform:android:assembleRealRelease',
+          './gradlew :app:platform:jvm:packageReleaseDistributionForCurrentOS',
+          './gradlew :app:platform:android:bundleRealRelease',
         ]
     steps:
       - name: Checkout repository
@@ -83,35 +87,35 @@ jobs:
           echo '${{ secrets.APPLE_REAL_DEBUG_GOOGLE_SERVICE_INFO_PLIST }}' >> Diary/Secret/RealDebug/GoogleService-Info.plist
           echo '${{ secrets.APPLE_REAL_RELEASE_GOOGLE_SERVICE_INFO_PLIST }}' >> Diary/Secret/RealRelease/GoogleService-Info.plist
 
-      - name: Install the build certificate and provisioning profile
+      - name: Install the build Apple certificate and build provisioning profile
         env:
-          BUILD_CERTIFICATE_BASE64: ${{ secrets.APPLE_BUILD_CERTIFICATE }}
-          BUILD_P12_PASSWORD: ${{ secrets.APPLE_BUILD_CERTIFICATE_PASSWORD }}
-          BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.APPLE_BUILD_PROFILE }}
-          KEYCHAIN_PASSWORD: ${{ secrets.APPLE_TEMPORARY_KEYCHAIN_PASSWORD }}
+          CERTIFICATE_BASE64: ${{ secrets.APPLE_BUILD_CERTIFICATE_BASE64 }}
+          P12_PASSWORD: ${{ secrets.APPLE_BUILD_P12_PASSWORD }}
+          PROVISION_PROFILE_BASE64: ${{ secrets.APPLE_BUILD_PROVISION_PROFILE_BASE64 }}
+          KEYCHAIN_PASSWORD: ${{ secrets.APPLE_BUILD_KEYCHAIN_PASSWORD }}
         run: |
           # create variables
-          BUILD_CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
-          BUILD_PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
+          CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
+          PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
           KEYCHAIN_PATH=$RUNNER_TEMP/build_app-signing.keychain-db
 
           # import certificate and provisioning profile from secrets
-          echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $BUILD_CERTIFICATE_PATH
-          echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $BUILD_PP_PATH
+          echo -n "$CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH
+          echo -n "$PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH
 
           # create temporary keychain
           security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
           security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
           security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
 
-          # import build certificate to keychain
-          security import $BUILD_CERTIFICATE_PATH -P "$BUILD_P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
+          # import certificate to keychain
+          security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
           security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
           security list-keychain -d user -s $KEYCHAIN_PATH
-          
+
           # apply provisioning profile
           mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
-          cp $BUILD_PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
+          cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
 
       - name: Build Cocoapods
         run: ./gradlew buildCocoapods
diff --git a/.github/workflows/check_code_style.yml b/.github/workflows/check_code_style.yml
index 304533d1..e129e136 100644
--- a/.github/workflows/check_code_style.yml
+++ b/.github/workflows/check_code_style.yml
@@ -1,6 +1,10 @@
 name: Check Code Style
 
-on: [ pull_request ]
+on:
+  pull_request:
+  push:
+    branches:
+      - main
 
 jobs:
   Spotless:
diff --git a/.github/workflows/dependency_guard.yml b/.github/workflows/dependency_guard.yml
index f8d9d26e..4c7dbb92 100644
--- a/.github/workflows/dependency_guard.yml
+++ b/.github/workflows/dependency_guard.yml
@@ -1,6 +1,10 @@
 name: Dependency Guard
 
-on: [ pull_request ]
+on:
+  pull_request:
+  push:
+    branches:
+      - main
 
 jobs:
   Dependency-Guard:
diff --git a/.github/workflows/firebase_app_distribution.yml b/.github/workflows/firebase_app_distribution.yml
index bc4b6fad..202b850c 100644
--- a/.github/workflows/firebase_app_distribution.yml
+++ b/.github/workflows/firebase_app_distribution.yml
@@ -91,35 +91,35 @@ jobs:
           echo '${{ secrets.APPLE_REAL_DEBUG_GOOGLE_SERVICE_INFO_PLIST }}' >> Diary/Secret/RealDebug/GoogleService-Info.plist
           echo '${{ secrets.APPLE_REAL_RELEASE_GOOGLE_SERVICE_INFO_PLIST }}' >> Diary/Secret/RealRelease/GoogleService-Info.plist
 
-      - name: Install the build certificate and provisioning profile
+      - name: Install the build Apple certificate and build provisioning profile
         env:
-          BUILD_CERTIFICATE_BASE64: ${{ secrets.APPLE_BUILD_CERTIFICATE }}
-          BUILD_P12_PASSWORD: ${{ secrets.APPLE_BUILD_CERTIFICATE_PASSWORD }}
-          BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.APPLE_BUILD_PROFILE }}
-          KEYCHAIN_PASSWORD: ${{ secrets.APPLE_TEMPORARY_KEYCHAIN_PASSWORD }}
+          CERTIFICATE_BASE64: ${{ secrets.APPLE_BUILD_CERTIFICATE_BASE64 }}
+          P12_PASSWORD: ${{ secrets.APPLE_BUILD_P12_PASSWORD }}
+          PROVISION_PROFILE_BASE64: ${{ secrets.APPLE_BUILD_PROVISION_PROFILE_BASE64 }}
+          KEYCHAIN_PASSWORD: ${{ secrets.APPLE_BUILD_KEYCHAIN_PASSWORD }}
         run: |
           # create variables
-          BUILD_CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
-          BUILD_PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
+          CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
+          PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
           KEYCHAIN_PATH=$RUNNER_TEMP/build_app-signing.keychain-db
 
           # import certificate and provisioning profile from secrets
-          echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $BUILD_CERTIFICATE_PATH
-          echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $BUILD_PP_PATH
+          echo -n "$CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH
+          echo -n "$PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH
 
           # create temporary keychain
           security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
           security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
           security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
 
-          # import build certificate to keychain
-          security import $BUILD_CERTIFICATE_PATH -P "$BUILD_P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
+          # import certificate to keychain
+          security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
           security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
           security list-keychain -d user -s $KEYCHAIN_PATH
-          
+
           # apply provisioning profile
           mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
-          cp $BUILD_PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
+          cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
 
       - name: Build Cocoapods
         run: ./gradlew buildCocoapods
@@ -127,35 +127,35 @@ jobs:
       - name: Archive xcarchive
         run: xcodebuild -project Diary/Diary.xcodeproj -scheme RealRelease archive -archivePath Diary/build/Diary.xcarchive -allowProvisioningUpdates
 
-      - name: Install the export certificate and provisioning profile
+      - name: Install the export Apple certificate and export provisioning profile
         env:
-          EXPORT_CERTIFICATE_BASE64: ${{ secrets.APPLE_EXPORT_CERTIFICATE }}
-          EXPORT_P12_PASSWORD: ${{ secrets.APPLE_EXPORT_CERTIFICATE_PASSWORD }}
-          EXPORT_PROVISION_PROFILE_BASE64: ${{ secrets.APPLE_EXPORT_PROFILE }}
-          KEYCHAIN_PASSWORD: ${{ secrets.APPLE_TEMPORARY_KEYCHAIN_PASSWORD }}
+          CERTIFICATE_BASE64: ${{ secrets.APPLE_EXPORT_CERTIFICATE_BASE64 }}
+          P12_PASSWORD: ${{ secrets.APPLE_EXPORT_P12_PASSWORD }}
+          PROVISION_PROFILE_BASE64: ${{ secrets.APPLE_EXPORT_PROVISION_PROFILE_BASE64 }}
+          KEYCHAIN_PASSWORD: ${{ secrets.APPLE_EXPORT_KEYCHAIN_PASSWORD }}
         run: |
           # create variables
-          EXPORT_CERTIFICATE_PATH=$RUNNER_TEMP/export_certificate.p12
-          EXPORT_PP_PATH=$RUNNER_TEMP/export_pp.mobileprovision
+          CERTIFICATE_PATH=$RUNNER_TEMP/export_certificate.p12
+          PP_PATH=$RUNNER_TEMP/export_pp.mobileprovision
           KEYCHAIN_PATH=$RUNNER_TEMP/export_app-signing.keychain-db
 
           # import certificate and provisioning profile from secrets
-          echo -n "$EXPORT_CERTIFICATE_BASE64" | base64 --decode -o $EXPORT_CERTIFICATE_PATH
-          echo -n "$EXPORT_PROVISION_PROFILE_BASE64" | base64 --decode -o $EXPORT_PP_PATH
+          echo -n "$CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH
+          echo -n "$PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH
 
           # create temporary keychain
           security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
           security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
           security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
 
-          # import build certificate to keychain
-          security import $EXPORT_CERTIFICATE_PATH -P "$EXPORT_P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
+          # import certificate to keychain
+          security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
           security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
           security list-keychain -d user -s $KEYCHAIN_PATH
-          
+
           # apply provisioning profile
           mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
-          cp $EXPORT_PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
+          cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
 
       - name: Export ipa
         run: xcodebuild -exportArchive -archivePath Diary/build/Diary.xcarchive -exportPath Diary/build -exportOptionsPlist Diary/ExportOptions.plist -allowProvisioningUpdates
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 00000000..b6e50905
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,51 @@
+name: Test
+
+on:
+  pull_request:
+  push:
+    branches:
+      - main
+
+jobs:
+  Linux-Build:
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        command: [
+          './gradlew jvmTest',
+        ]
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v4
+
+      - name: CI setup
+        uses: './.github/actions/ci-setup'
+
+      - name: Set local.properties
+        run: |
+          echo diary.dev.api.base.url=${{ secrets.DIARY_DEV_API_BASE_URL }} >> local.properties
+          echo diary.real.api.base.url=${{ secrets.DIARY_REAL_API_BASE_URL }} >> local.properties
+          echo holiday.dev.api.url=${{ secrets.HOLIDAY_DEV_API_URL }} >> local.properties
+          echo holiday.dev.api.key=${{ secrets.HOLIDAY_DEV_API_KEY }} >> local.properties
+          echo holiday.real.api.url=${{ secrets.HOLIDAY_REAL_API_URL }} >> local.properties
+          echo holiday.real.api.key=${{ secrets.HOLIDAY_REAL_API_KEY }} >> local.properties
+          echo android.dev.store.password=${{ secrets.ANDROID_DEV_STORE_PASSWORD }} >> local.properties
+          echo android.dev.key.alias=${{ secrets.ANDROID_DEV_KEY_ALIAS }} >> local.properties
+          echo android.dev.key.password=${{ secrets.ANDROID_DEV_KEY_PASSWORD }} >> local.properties
+          echo android.real.store.password=${{ secrets.ANDROID_REAL_STORE_PASSWORD }} >> local.properties
+          echo android.real.key.alias=${{ secrets.ANDROID_REAL_KEY_ALIAS }} >> local.properties
+          echo android.real.key.password=${{ secrets.ANDROID_REAL_KEY_PASSWORD }} >> local.properties
+
+      - name: Set Android google-services.json
+        run: |
+          echo '${{ secrets.ANDROID_DEV_GOOGLE_SERVICES_JSON }}' >> app/platform/android/src/dev/google-services.json
+          echo '${{ secrets.ANDROID_REAL_GOOGLE_SERVICES_JSON }}' >> app/platform/android/src/real/google-services.json
+
+      - name: Set Apple GoogleService-Info.plist
+        run: |
+          echo '${{ secrets.APPLE_DEV_DEBUG_GOOGLE_SERVICE_INFO_PLIST }}' >> Diary/Secret/DevDebug/GoogleService-Info.plist
+          echo '${{ secrets.APPLE_DEV_RELEASE_GOOGLE_SERVICE_INFO_PLIST }}' >> Diary/Secret/DevRelease/GoogleService-Info.plist
+          echo '${{ secrets.APPLE_REAL_DEBUG_GOOGLE_SERVICE_INFO_PLIST }}' >> Diary/Secret/RealDebug/GoogleService-Info.plist
+          echo '${{ secrets.APPLE_REAL_RELEASE_GOOGLE_SERVICE_INFO_PLIST }}' >> Diary/Secret/RealRelease/GoogleService-Info.plist
+      - name: Build ${{ matrix.command }}
+        run: ${{ matrix.command }}
\ No newline at end of file
diff --git a/Diary/Diary.xcodeproj/project.pbxproj b/Diary/Diary.xcodeproj/project.pbxproj
index aec03382..ef308e00 100644
--- a/Diary/Diary.xcodeproj/project.pbxproj
+++ b/Diary/Diary.xcodeproj/project.pbxproj
@@ -272,10 +272,10 @@
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CODE_SIGN_ENTITLEMENTS = Diary/Diary.entitlements;
 				CODE_SIGN_IDENTITY = "Apple Development";
-				CODE_SIGN_STYLE = Automatic;
+				CODE_SIGN_STYLE = Manual;
 				CURRENT_PROJECT_VERSION = 1;
 				DEVELOPMENT_ASSET_PATHS = "\"Diary/Preview Content\"";
-				DEVELOPMENT_TEAM = 4TV6L66XZ8;
+				DEVELOPMENT_TEAM = "";
 				ENABLE_PREVIEWS = YES;
 				ENABLE_USER_SCRIPT_SANDBOXING = NO;
 				GENERATE_INFOPLIST_FILE = YES;
@@ -292,7 +292,7 @@
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 1.2.1;
+				MARKETING_VERSION = 1.2.2;
 				PRODUCT_BUNDLE_IDENTIFIER = io.github.taetae98coding.diary.debug;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				PROVISIONING_PROFILE_SPECIFIER = "";
@@ -388,11 +388,11 @@
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 1.2.1;
+				MARKETING_VERSION = 1.2.2;
 				PRODUCT_BUNDLE_IDENTIFIER = io.github.taetae98coding.diary;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				PROVISIONING_PROFILE_SPECIFIER = "";
-				"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = RealReleaseBuild;
+				"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = DiaryBuild;
 				SWIFT_EMIT_LOC_STRINGS = YES;
 				SWIFT_VERSION = 5.0;
 				TARGETED_DEVICE_FAMILY = "1,2";
@@ -470,10 +470,10 @@
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CODE_SIGN_ENTITLEMENTS = Diary/Diary.entitlements;
 				CODE_SIGN_IDENTITY = "Apple Development";
-				CODE_SIGN_STYLE = Automatic;
+				CODE_SIGN_STYLE = Manual;
 				CURRENT_PROJECT_VERSION = 1;
 				DEVELOPMENT_ASSET_PATHS = "\"Diary/Preview Content\"";
-				DEVELOPMENT_TEAM = 4TV6L66XZ8;
+				DEVELOPMENT_TEAM = "";
 				ENABLE_PREVIEWS = YES;
 				ENABLE_USER_SCRIPT_SANDBOXING = NO;
 				GENERATE_INFOPLIST_FILE = YES;
@@ -490,7 +490,7 @@
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 1.2.1;
+				MARKETING_VERSION = 1.2.2;
 				PRODUCT_BUNDLE_IDENTIFIER = io.github.taetae98coding.diary.dev.debug;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				PROVISIONING_PROFILE_SPECIFIER = "";
@@ -564,10 +564,10 @@
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CODE_SIGN_ENTITLEMENTS = Diary/Diary.entitlements;
 				CODE_SIGN_IDENTITY = "Apple Development";
-				CODE_SIGN_STYLE = Automatic;
+				CODE_SIGN_STYLE = Manual;
 				CURRENT_PROJECT_VERSION = 1;
 				DEVELOPMENT_ASSET_PATHS = "\"Diary/Preview Content\"";
-				DEVELOPMENT_TEAM = 4TV6L66XZ8;
+				DEVELOPMENT_TEAM = "";
 				ENABLE_PREVIEWS = YES;
 				ENABLE_USER_SCRIPT_SANDBOXING = NO;
 				GENERATE_INFOPLIST_FILE = YES;
@@ -584,7 +584,7 @@
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 1.2.1;
+				MARKETING_VERSION = 1.2.2;
 				PRODUCT_BUNDLE_IDENTIFIER = io.github.taetae98coding.diary.dev;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				PROVISIONING_PROFILE_SPECIFIER = "";
diff --git a/Diary/ExportOptions.plist b/Diary/ExportOptions.plist
index 05fe0a40..51502ea9 100644
--- a/Diary/ExportOptions.plist
+++ b/Diary/ExportOptions.plist
@@ -9,10 +9,10 @@
 	<key>provisioningProfiles</key>
 	<dict>
 		<key>io.github.taetae98coding.diary</key>
-		<string>DiaryRealReleaseAdHoc</string>
+		<string>DiaryExport</string>
 	</dict>
 	<key>signingCertificate</key>
-	<string>FB549459D90CDC28F248EDA3AE6246EB856E77F9</string>
+	<string>68893A355C74683A1B64C16C2D460AA4AC8C2B94</string>
 	<key>signingStyle</key>
 	<string>manual</string>
 	<key>stripSwiftSymbols</key>
diff --git a/app/core/account-preferences-datastore/src/commonMain/kotlin/io/github/taetae98coding/diary/core/account/preferences/datastore/AccountDataStorePreferences.kt b/app/core/account-preferences-datastore/src/commonMain/kotlin/io/github/taetae98coding/diary/core/account/preferences/datastore/AccountDataStorePreferences.kt
index 48c5cb8a..c669ff29 100644
--- a/app/core/account-preferences-datastore/src/commonMain/kotlin/io/github/taetae98coding/diary/core/account/preferences/datastore/AccountDataStorePreferences.kt
+++ b/app/core/account-preferences-datastore/src/commonMain/kotlin/io/github/taetae98coding/diary/core/account/preferences/datastore/AccountDataStorePreferences.kt
@@ -10,7 +10,9 @@ import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.mapLatest
 
 @OptIn(ExperimentalCoroutinesApi::class)
-internal class AccountDataStorePreferences(private val dataStore: DataStore<Preferences>) : AccountPreferences {
+internal class AccountDataStorePreferences(
+	private val dataStore: DataStore<Preferences>,
+) : AccountPreferences {
 	override suspend fun save(email: String, uid: String, token: String) {
 		dataStore.edit {
 			it[stringPreferencesKey(EMAIL)] = email
diff --git a/app/core/backup-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/backup/database/room/dao/MemoBackupRoomDao.kt b/app/core/backup-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/backup/database/room/dao/MemoBackupRoomDao.kt
index 68bd7c9d..970bbda3 100644
--- a/app/core/backup-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/backup/database/room/dao/MemoBackupRoomDao.kt
+++ b/app/core/backup-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/backup/database/room/dao/MemoBackupRoomDao.kt
@@ -7,7 +7,9 @@ import kotlinx.coroutines.flow.Flow
 import org.koin.core.annotation.Factory
 
 @Factory
-internal class MemoBackupRoomDao(private val database: BackupDatabase) : MemoBackupDao {
+internal class MemoBackupRoomDao(
+	private val database: BackupDatabase,
+) : MemoBackupDao {
 	override suspend fun upsert(uid: String, id: String) {
 		database.memo().upsert(MemoBackupEntity(memoId = id, uid = uid))
 	}
diff --git a/app/core/backup-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/backup/database/room/dao/TagBackupRoomDao.kt b/app/core/backup-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/backup/database/room/dao/TagBackupRoomDao.kt
index c57b538c..063a044e 100644
--- a/app/core/backup-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/backup/database/room/dao/TagBackupRoomDao.kt
+++ b/app/core/backup-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/backup/database/room/dao/TagBackupRoomDao.kt
@@ -7,7 +7,9 @@ import kotlinx.coroutines.flow.Flow
 import org.koin.core.annotation.Factory
 
 @Factory
-internal class TagBackupRoomDao(private val database: BackupDatabase) : TagBackupDao {
+internal class TagBackupRoomDao(
+	private val database: BackupDatabase,
+) : TagBackupDao {
 	override suspend fun upsert(uid: String, id: String) {
 		database.tag().upsert(TagBackupEntity(tagId = id, uid = uid))
 	}
diff --git a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/Calendar.kt b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/Calendar.kt
index fd48d077..726dcbb8 100644
--- a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/Calendar.kt
+++ b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/Calendar.kt
@@ -39,22 +39,22 @@ public fun Calendar(
 	val coroutineScope = rememberCoroutineScope()
 
 	Surface(
-		modifier = modifier.onPreviewKeyEvent {
-			when {
-				!state.pagerState.isScrollInProgress && it.key == Key.DirectionRight -> {
-					coroutineScope.launch { state.animateScrollToForward() }
-					true
-				}
+		modifier = modifier
+			.onPreviewKeyEvent {
+				when {
+					!state.pagerState.isScrollInProgress && it.key == Key.DirectionRight -> {
+						coroutineScope.launch { state.animateScrollToForward() }
+						true
+					}
 
-				!state.pagerState.isScrollInProgress && it.key == Key.DirectionLeft -> {
-					coroutineScope.launch { state.animateScrollToBackward() }
-					true
-				}
+					!state.pagerState.isScrollInProgress && it.key == Key.DirectionLeft -> {
+						coroutineScope.launch { state.animateScrollToBackward() }
+						true
+					}
 
-				else -> false
-			}
-		}
-			.focusRequester(state.focusRequester)
+					else -> false
+				}
+			}.focusRequester(state.focusRequester)
 			.focusable(),
 		color = DiaryTheme.color.background,
 	) {
diff --git a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/color/CalendarColors.kt b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/color/CalendarColors.kt
index 38be6659..91ff5d59 100644
--- a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/color/CalendarColors.kt
+++ b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/color/CalendarColors.kt
@@ -2,4 +2,11 @@ package io.github.taetae98coding.diary.core.calendar.compose.color
 
 import androidx.compose.ui.graphics.Color
 
-public data class CalendarColors(val sundayColor: Color, val saturdayColor: Color, val dayColor: Color, val primaryColor: Color, val onPrimaryColor: Color, val selectColor: Color)
+public data class CalendarColors(
+	val sundayColor: Color,
+	val saturdayColor: Color,
+	val dayColor: Color,
+	val primaryColor: Color,
+	val onPrimaryColor: Color,
+	val selectColor: Color,
+)
diff --git a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/day/CalendarDayOfMonth.kt b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/day/CalendarDayOfMonth.kt
index 2ada4e0d..33b8b72c 100644
--- a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/day/CalendarDayOfMonth.kt
+++ b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/day/CalendarDayOfMonth.kt
@@ -53,11 +53,13 @@ internal fun CalendarDayOfMonth(
 			)
 		}
 		val size = with(LocalDensity.current) {
-			DiaryTheme.typography.labelMedium.fontSize.toDp() + 16.dp
+			DiaryTheme.typography.labelMedium.fontSize
+				.toDp() + 16.dp
 		}
 
 		Box(
-			modifier = Modifier.size(size)
+			modifier = Modifier
+				.size(size)
 				.run {
 					if (isPrimary) {
 						background(color = colors.primaryColor, shape = CircleShape)
diff --git a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/day/CalendarDayOfMonthState.kt b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/day/CalendarDayOfMonthState.kt
index 207e5c9a..c4c6ca26 100644
--- a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/day/CalendarDayOfMonthState.kt
+++ b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/day/CalendarDayOfMonthState.kt
@@ -5,7 +5,12 @@ import kotlinx.datetime.DayOfWeek
 import kotlinx.datetime.LocalDate
 import kotlinx.datetime.Month
 
-internal class CalendarDayOfMonthState(val year: Int, val month: Month, val weekOfMonth: Int, val dayOfWeek: DayOfWeek) {
+internal class CalendarDayOfMonthState(
+	val year: Int,
+	val month: Month,
+	val weekOfMonth: Int,
+	val dayOfWeek: DayOfWeek,
+) {
 	val localDate = LocalDate(year, month, weekOfMonth, dayOfWeek)
 	val isInMonth = year == localDate.year && month == localDate.month
 }
diff --git a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/item/CalendarItemUiState.kt b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/item/CalendarItemUiState.kt
index a309185f..373161dc 100644
--- a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/item/CalendarItemUiState.kt
+++ b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/item/CalendarItemUiState.kt
@@ -8,11 +8,21 @@ public sealed class CalendarItemUiState :
 	public abstract val key: Any
 	public abstract val text: String
 
-	public data class Holiday(override val text: String, override val start: LocalDate, override val endInclusive: LocalDate) : CalendarItemUiState() {
+	public data class Holiday(
+		override val text: String,
+		override val start: LocalDate,
+		override val endInclusive: LocalDate,
+	) : CalendarItemUiState() {
 		override val key: String = "$text($start~$endInclusive)"
 	}
 
-	public data class Text(override val key: Any, override val text: String, val color: Int, override val start: LocalDate, override val endInclusive: LocalDate) : CalendarItemUiState()
+	public data class Text(
+		override val key: Any,
+		override val text: String,
+		val color: Int,
+		override val start: LocalDate,
+		override val endInclusive: LocalDate,
+	) : CalendarItemUiState()
 
 	override fun compareTo(other: CalendarItemUiState): Int {
 		if (start != other.start) {
diff --git a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/month/CalendarMonthState.kt b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/month/CalendarMonthState.kt
index 016b22a7..e252ac29 100644
--- a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/month/CalendarMonthState.kt
+++ b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/month/CalendarMonthState.kt
@@ -6,7 +6,10 @@ import androidx.compose.runtime.setValue
 import kotlinx.datetime.LocalDate
 import kotlinx.datetime.Month
 
-internal class CalendarMonthState(val year: Int, val month: Month) {
+internal class CalendarMonthState(
+	val year: Int,
+	val month: Month,
+) {
 	var selectedDateRange: ClosedRange<LocalDate>? by mutableStateOf(null)
 		private set
 
diff --git a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/state/CalendarState.kt b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/state/CalendarState.kt
index 2a4e2257..f2080665 100644
--- a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/state/CalendarState.kt
+++ b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/state/CalendarState.kt
@@ -10,7 +10,9 @@ import kotlinx.datetime.LocalDate
 import kotlinx.datetime.Month
 import kotlinx.datetime.plus
 
-public class CalendarState internal constructor(internal val pagerState: PagerState) {
+public class CalendarState internal constructor(
+	internal val pagerState: PagerState,
+) {
 	internal val focusRequester = FocusRequester()
 
 	internal val localDate: LocalDate
diff --git a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/topbar/CalendarTopBar.kt b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/topbar/CalendarTopBar.kt
index 84f20573..499ec995 100644
--- a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/topbar/CalendarTopBar.kt
+++ b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/topbar/CalendarTopBar.kt
@@ -39,7 +39,8 @@ public fun CalendarTopBar(
 			var isDialogVisible by rememberSaveable { mutableStateOf(false) }
 
 			Row(
-				modifier = Modifier.clip(CircleShape)
+				modifier = Modifier
+					.clip(CircleShape)
 					.clickable { isDialogVisible = true }
 					.padding(horizontal = 8.dp, vertical = 4.dp)
 					.padding(start = 8.dp),
diff --git a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/topbar/TodayIcon.kt b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/topbar/TodayIcon.kt
index 8b32a5d8..b15fd1e4 100644
--- a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/topbar/TodayIcon.kt
+++ b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/topbar/TodayIcon.kt
@@ -25,7 +25,8 @@ public fun TodayIcon(
 	modifier: Modifier = Modifier,
 ) {
 	Box(
-		modifier = modifier.size(24.dp)
+		modifier = modifier
+			.size(24.dp)
 			.border(
 				width = 1.dp,
 				color = LocalContentColor.current,
diff --git a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/week/CalendarItemVerticalGrid.kt b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/week/CalendarItemVerticalGrid.kt
index 80e6e9b3..f21ce0ee 100644
--- a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/week/CalendarItemVerticalGrid.kt
+++ b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/week/CalendarItemVerticalGrid.kt
@@ -33,7 +33,8 @@ internal fun CalendarItemVerticalGrid(
 				addAll(textItemListProvider())
 			}.filter {
 				it.isOverlap(state.dateRange)
-			}.sorted().toMutableList()
+			}.sorted()
+				.toMutableList()
 
 			buildList {
 				while (itemList.isNotEmpty()) {
diff --git a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/week/CalendarWeekState.kt b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/week/CalendarWeekState.kt
index 07673114..fee273f1 100644
--- a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/week/CalendarWeekState.kt
+++ b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/week/CalendarWeekState.kt
@@ -9,7 +9,11 @@ import kotlinx.datetime.DayOfWeek
 import kotlinx.datetime.LocalDate
 import kotlinx.datetime.Month
 
-internal class CalendarWeekState(val year: Int, val month: Month, val weekOfMonth: Int) {
+internal class CalendarWeekState(
+	val year: Int,
+	val month: Month,
+	val weekOfMonth: Int,
+) {
 	val dateRange = LocalDate(year, month, weekOfMonth, DayOfWeek.SUNDAY)..LocalDate(year, month, weekOfMonth, DayOfWeek.SATURDAY)
 
 	var selectedDateRange: ClosedRange<LocalDate>? by mutableStateOf(null)
diff --git a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/week/WeekItem.kt b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/week/WeekItem.kt
index 2983e197..ebddef7b 100644
--- a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/week/WeekItem.kt
+++ b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/week/WeekItem.kt
@@ -5,9 +5,20 @@ import androidx.compose.ui.graphics.Color
 internal sealed class WeekItem {
 	abstract val weight: Float
 
-	data class Space(override val weight: Float) : WeekItem()
+	data class Space(
+		override val weight: Float,
+	) : WeekItem()
 
-	data class Holiday(val key: Any, val name: String, override val weight: Float) : WeekItem()
+	data class Holiday(
+		val key: Any,
+		val name: String,
+		override val weight: Float,
+	) : WeekItem()
 
-	data class Text(val key: Any, val name: String, val color: Color, override val weight: Float) : WeekItem()
+	data class Text(
+		val key: Any,
+		val name: String,
+		val color: Color,
+		override val weight: Float,
+	) : WeekItem()
 }
diff --git a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/week/WeekItemRow.kt b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/week/WeekItemRow.kt
index 3c68d558..d352fd46 100644
--- a/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/week/WeekItemRow.kt
+++ b/app/core/calendar-compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/calendar/compose/week/WeekItemRow.kt
@@ -47,7 +47,8 @@ internal fun WeekItemRow(
 						WeekTextItem(
 							text = it.name,
 							color = colors.sundayColor,
-							modifier = Modifier.weight(it.weight)
+							modifier = Modifier
+								.weight(it.weight)
 								.fillMaxHeight()
 								.padding(horizontal = 1.dp)
 								.clip(RoundedCornerShape(4.dp)),
@@ -60,7 +61,8 @@ internal fun WeekItemRow(
 						WeekTextItem(
 							text = it.name,
 							color = it.color,
-							modifier = Modifier.weight(it.weight)
+							modifier = Modifier
+								.weight(it.weight)
 								.fillMaxHeight()
 								.padding(horizontal = 1.dp)
 								.clip(RoundedCornerShape(4.dp))
@@ -85,7 +87,8 @@ private fun WeekTextItem(
 	) {
 		Text(
 			text = text,
-			modifier = Modifier.basicMarquee(iterations = Int.MAX_VALUE)
+			modifier = Modifier
+				.basicMarquee(iterations = Int.MAX_VALUE)
 				.padding(2.dp),
 			color = color.toContrastColor(),
 			textAlign = TextAlign.Center,
diff --git a/app/core/compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/compose/runtime/SkipProperty.kt b/app/core/compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/compose/runtime/SkipProperty.kt
index 75765ce4..a917ed00 100644
--- a/app/core/compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/compose/runtime/SkipProperty.kt
+++ b/app/core/compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/compose/runtime/SkipProperty.kt
@@ -3,7 +3,9 @@ package io.github.taetae98coding.diary.core.compose.runtime
 import androidx.compose.runtime.Immutable
 
 @Immutable
-public class SkipProperty<T>(public val value: T) {
+public class SkipProperty<T>(
+	public val value: T,
+) {
 	override fun equals(other: Any?): Boolean = true
 
 	override fun hashCode(): Int = 0
diff --git a/app/core/compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/compose/swipe/FinishAndDeleteSwipeBox.kt b/app/core/compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/compose/swipe/FinishAndDeleteSwipeBox.kt
index ae3ecd27..8a49690a 100644
--- a/app/core/compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/compose/swipe/FinishAndDeleteSwipeBox.kt
+++ b/app/core/compose/src/commonMain/kotlin/io/github/taetae98coding/diary/core/compose/swipe/FinishAndDeleteSwipeBox.kt
@@ -53,7 +53,8 @@ public fun FinishAndDeleteSwipeBox(
 				)
 
 				Box(
-					modifier = Modifier.align(Alignment.CenterStart)
+					modifier = Modifier
+						.align(Alignment.CenterStart)
 						.padding(horizontal = 4.dp)
 						.graphicsLayer {
 							scaleX = scale
@@ -68,7 +69,8 @@ public fun FinishAndDeleteSwipeBox(
 				}
 
 				Box(
-					modifier = Modifier.align(Alignment.CenterEnd)
+					modifier = Modifier
+						.align(Alignment.CenterEnd)
 						.padding(horizontal = 4.dp)
 						.graphicsLayer {
 							scaleX = scale
diff --git a/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/color/DiaryColor.kt b/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/color/DiaryColor.kt
index 033aa7e3..5225f4b2 100644
--- a/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/color/DiaryColor.kt
+++ b/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/color/DiaryColor.kt
@@ -2,4 +2,10 @@ package io.github.taetae98coding.diary.core.design.system.color
 
 import androidx.compose.ui.graphics.Color
 
-public data class DiaryColor(val primary: Color, val onPrimary: Color, val secondary: Color, val background: Color, val onSurface: Color)
+public data class DiaryColor(
+	val primary: Color,
+	val onPrimary: Color,
+	val secondary: Color,
+	val background: Color,
+	val onSurface: Color,
+)
diff --git a/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/color/DiaryColorPicker.kt b/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/color/DiaryColorPicker.kt
index 88efa534..168effc3 100644
--- a/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/color/DiaryColorPicker.kt
+++ b/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/color/DiaryColorPicker.kt
@@ -36,7 +36,8 @@ public fun DiaryColorPicker(
 
 		ColorBox(
 			state = state,
-			modifier = Modifier.fillMaxWidth()
+			modifier = Modifier
+				.fillMaxWidth()
 				.height(200.dp),
 		)
 
diff --git a/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/color/DiaryColorPickerDialog.kt b/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/color/DiaryColorPickerDialog.kt
index 7d21d2b6..7acc3bce 100644
--- a/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/color/DiaryColorPickerDialog.kt
+++ b/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/color/DiaryColorPickerDialog.kt
@@ -39,7 +39,8 @@ public fun DiaryColorPickerDialog(
 			DiaryColorPicker(state = state)
 
 			Row(
-				modifier = Modifier.fillMaxWidth()
+				modifier = Modifier
+					.fillMaxWidth()
 					.padding(horizontal = 6.dp),
 				horizontalArrangement = Arrangement.spacedBy(12.dp, Alignment.End),
 			) {
diff --git a/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/color/DiaryColorPickerState.kt b/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/color/DiaryColorPickerState.kt
index b1c2615f..92ac5878 100644
--- a/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/color/DiaryColorPickerState.kt
+++ b/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/color/DiaryColorPickerState.kt
@@ -10,7 +10,9 @@ import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.toArgb
 import io.github.taetae98coding.diary.library.color.randomArgb
 
-public class DiaryColorPickerState internal constructor(initialColor: Color) {
+public class DiaryColorPickerState internal constructor(
+	initialColor: Color,
+) {
 	public var color: Color by mutableStateOf(initialColor)
 		private set
 
diff --git a/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/diary/color/DiaryColorState.kt b/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/diary/color/DiaryColorState.kt
index 2ca545aa..d5f98c9d 100644
--- a/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/diary/color/DiaryColorState.kt
+++ b/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/diary/color/DiaryColorState.kt
@@ -8,7 +8,9 @@ import androidx.compose.runtime.setValue
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.toArgb
 
-public class DiaryColorState(initialColor: Color) {
+public class DiaryColorState(
+	initialColor: Color,
+) {
 	public var color: Color by mutableStateOf(initialColor)
 		private set
 
diff --git a/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/diary/component/DiaryComponent.kt b/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/diary/component/DiaryComponent.kt
index 8837d3bf..81c956d3 100644
--- a/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/diary/component/DiaryComponent.kt
+++ b/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/diary/component/DiaryComponent.kt
@@ -33,7 +33,8 @@ public fun DiaryComponent(
 		ClearTextField(
 			valueProvider = { state.title },
 			onValueChange = state::onTitleChange,
-			modifier = Modifier.fillMaxWidth()
+			modifier = Modifier
+				.fillMaxWidth()
 				.focusRequester(state.titleFocusRequester),
 			label = { Text(text = "제목") },
 			errorProvider = { state.isTitleError },
@@ -95,7 +96,8 @@ private fun DescriptionPager(
 
 			1 -> {
 				Column(
-					modifier = Modifier.fillMaxSize()
+					modifier = Modifier
+						.fillMaxSize()
 						.verticalScroll(rememberScrollState())
 						.padding(DiaryTheme.dimen.diaryPaddingValues),
 				) {
diff --git a/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/diary/component/DiaryComponentState.kt b/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/diary/component/DiaryComponentState.kt
index 7850f2c3..05bdc55c 100644
--- a/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/diary/component/DiaryComponentState.kt
+++ b/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/diary/component/DiaryComponentState.kt
@@ -8,7 +8,10 @@ import androidx.compose.runtime.saveable.listSaver
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.focus.FocusRequester
 
-public class DiaryComponentState internal constructor(initialTitle: String, initialDescription: String) {
+public class DiaryComponentState internal constructor(
+	initialTitle: String,
+	initialDescription: String,
+) {
 	internal var isTitleError by mutableStateOf(false)
 		private set
 	public var title: String by mutableStateOf(initialTitle)
@@ -19,11 +22,11 @@ public class DiaryComponentState internal constructor(initialTitle: String, init
 	internal val pagerState =
 		PagerState(
 			currentPage =
-			if (initialDescription.isBlank()) {
-				0
-			} else {
-				1
-			},
+				if (initialDescription.isBlank()) {
+					0
+				} else {
+					1
+				},
 		) {
 			2
 		}
diff --git a/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/diary/date/DiaryDate.kt b/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/diary/date/DiaryDate.kt
index f9dcc6e3..1cafb19d 100644
--- a/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/diary/date/DiaryDate.kt
+++ b/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/diary/date/DiaryDate.kt
@@ -56,7 +56,8 @@ private fun Title(
 	modifier: Modifier = Modifier,
 ) {
 	Row(
-		modifier = Modifier.toggleable(value = state.hasDate, onValueChange = state::onHasDateChange)
+		modifier = Modifier
+			.toggleable(value = state.hasDate, onValueChange = state::onHasDateChange)
 			.then(modifier),
 		horizontalArrangement = Arrangement.SpaceBetween,
 		verticalAlignment = Alignment.CenterVertically,
diff --git a/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/diary/date/DiaryDateState.kt b/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/diary/date/DiaryDateState.kt
index e45a3cad..fe504658 100644
--- a/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/diary/date/DiaryDateState.kt
+++ b/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/diary/date/DiaryDateState.kt
@@ -8,7 +8,10 @@ import androidx.compose.runtime.setValue
 import io.github.taetae98coding.diary.library.datetime.todayIn
 import kotlinx.datetime.LocalDate
 
-public class DiaryDateState internal constructor(initialStart: LocalDate?, initialEndInclusive: LocalDate?) : ClosedRange<LocalDate> {
+public class DiaryDateState internal constructor(
+	initialStart: LocalDate?,
+	initialEndInclusive: LocalDate?,
+) : ClosedRange<LocalDate> {
 	public var hasDate: Boolean by mutableStateOf(initialStart != null && initialEndInclusive != null)
 		private set
 	override var start: LocalDate by mutableStateOf(initialStart ?: LocalDate.todayIn())
diff --git a/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/dimen/DiaryDimen.kt b/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/dimen/DiaryDimen.kt
index e792ddfe..28ab1f23 100644
--- a/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/dimen/DiaryDimen.kt
+++ b/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/dimen/DiaryDimen.kt
@@ -4,7 +4,13 @@ import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 
-public data class DiaryDimen(val screenHorizontalPadding: Dp = 12.dp, val screenVerticalPadding: Dp = 12.dp, val diaryHorizontalPadding: Dp = 16.dp, val diaryVerticalPadding: Dp = 8.dp, val itemSpace: Dp = 4.dp) {
+public data class DiaryDimen(
+	val screenHorizontalPadding: Dp = 12.dp,
+	val screenVerticalPadding: Dp = 12.dp,
+	val diaryHorizontalPadding: Dp = 16.dp,
+	val diaryVerticalPadding: Dp = 8.dp,
+	val itemSpace: Dp = 4.dp,
+) {
 	val screenPaddingValues: PaddingValues =
 		PaddingValues(
 			horizontal = screenHorizontalPadding,
diff --git a/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/theme/DiaryTheme.kt b/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/theme/DiaryTheme.kt
index 6252f15f..5b46bd65 100644
--- a/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/theme/DiaryTheme.kt
+++ b/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/theme/DiaryTheme.kt
@@ -44,9 +44,11 @@ public fun DiaryTheme(
 		),
 		LocalDiaryTypography provides DiaryTypography(
 			headlineMedium = MaterialTheme.typography.headlineMedium,
-			labelSmall = MaterialTheme.typography.labelSmall,
-			labelMedium = MaterialTheme.typography.labelMedium,
+            titleLarge = MaterialTheme.typography.titleLarge,
+            titleMedium = MaterialTheme.typography.titleMedium,
 			labelLarge = MaterialTheme.typography.labelLarge,
+			labelMedium = MaterialTheme.typography.labelMedium,
+			labelSmall = MaterialTheme.typography.labelSmall,
 			bodySmall = MaterialTheme.typography.bodySmall,
 		),
 		LocalDiaryDimen provides DiaryDimen(),
diff --git a/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/typography/DiaryTypography.kt b/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/typography/DiaryTypography.kt
index 27748793..8ade938e 100644
--- a/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/typography/DiaryTypography.kt
+++ b/app/core/design-system/src/commonMain/kotlin/io/github/taetae98coding/diary/core/design/system/typography/DiaryTypography.kt
@@ -2,4 +2,12 @@ package io.github.taetae98coding.diary.core.design.system.typography
 
 import androidx.compose.ui.text.TextStyle
 
-public data class DiaryTypography(val headlineMedium: TextStyle, val labelSmall: TextStyle, val labelMedium: TextStyle, val labelLarge: TextStyle, val bodySmall: TextStyle)
+public data class DiaryTypography(
+	val headlineMedium: TextStyle,
+    val titleLarge: TextStyle,
+    val titleMedium: TextStyle,
+	val labelLarge: TextStyle,
+	val labelMedium: TextStyle,
+    val labelSmall: TextStyle,
+	val bodySmall: TextStyle,
+)
diff --git a/app/core/diary-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/room/dao/MemoRoomDao.kt b/app/core/diary-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/room/dao/MemoRoomDao.kt
index f0cd5bc7..d4d672b3 100644
--- a/app/core/diary-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/room/dao/MemoRoomDao.kt
+++ b/app/core/diary-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/room/dao/MemoRoomDao.kt
@@ -18,7 +18,10 @@ import org.koin.core.annotation.Factory
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @Factory
-internal class MemoRoomDao(private val clock: Clock, private val database: DiaryDatabase) : MemoDao {
+internal class MemoRoomDao(
+	private val clock: Clock,
+	private val database: DiaryDatabase,
+) : MemoDao {
 	override suspend fun upsert(dto: MemoAndTagIds) {
 		database.memo().upsertMemoAndTagIds(dto)
 	}
diff --git a/app/core/diary-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/room/dao/MemoTagRoomDao.kt b/app/core/diary-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/room/dao/MemoTagRoomDao.kt
index 71485865..06557a79 100644
--- a/app/core/diary-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/room/dao/MemoTagRoomDao.kt
+++ b/app/core/diary-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/room/dao/MemoTagRoomDao.kt
@@ -10,7 +10,9 @@ import org.koin.core.annotation.Factory
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @Factory
-internal class MemoTagRoomDao(private val database: DiaryDatabase) : MemoTagDao {
+internal class MemoTagRoomDao(
+	private val database: DiaryDatabase,
+) : MemoTagDao {
 	override fun findTagIdsByMemoId(memoId: String): Flow<Set<String>> =
 		database
 			.memoTag()
diff --git a/app/core/diary-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/room/dao/TagEntityDao.kt b/app/core/diary-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/room/dao/TagEntityDao.kt
index 028d595a..e1cfbc91 100644
--- a/app/core/diary-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/room/dao/TagEntityDao.kt
+++ b/app/core/diary-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/room/dao/TagEntityDao.kt
@@ -2,6 +2,7 @@ package io.github.taetae98coding.diary.core.diary.database.room.dao
 
 import androidx.room.Dao
 import androidx.room.Query
+import io.github.taetae98coding.diary.core.diary.database.room.entity.MemoEntity
 import io.github.taetae98coding.diary.core.diary.database.room.entity.TagEntity
 import io.github.taetae98coding.diary.library.room.dao.EntityDao
 import kotlinx.coroutines.flow.Flow
@@ -50,6 +51,18 @@ internal abstract class TagEntityDao : EntityDao<TagEntity>() {
 	)
 	abstract suspend fun updateDelete(tagId: String, isDelete: Boolean, updateAt: Instant)
 
+    @Query(
+        """
+		SELECT *
+		FROM TagEntity
+		WHERE isDelete = 0
+		AND isFinish = 0
+		AND (owner = :owner OR (owner IS NULL AND :owner IS NULL))
+		ORDER BY title
+	""",
+    )
+    abstract fun page(owner: String?): Flow<List<TagEntity>>
+
 	@Query(
 		"""
 		SELECT *
@@ -70,17 +83,19 @@ internal abstract class TagEntityDao : EntityDao<TagEntity>() {
 	)
 	abstract fun findByIds(tagIds: Set<String>, filterNotDelete: Boolean): Flow<List<TagEntity>>
 
-	@Query(
-		"""
-		SELECT *
-		FROM TagEntity
-		WHERE isDelete = 0
-		AND isFinish = 0
-		AND (owner = :owner OR (owner IS NULL AND :owner IS NULL))
-		ORDER BY title
-	""",
-	)
-	abstract fun page(owner: String?): Flow<List<TagEntity>>
+    @Query("""
+        SELECT *
+        FROM MemoEntity
+        WHERE isDelete = 0
+        AND isFinish = 0
+        AND id IN (
+            SELECT memoId
+            FROM MemoTagEntity
+            WHERE tagId = :tagId
+        )
+        ORDER BY title
+    """)
+    abstract fun findMemoByTagId(tagId: String): Flow<List<MemoEntity>>
 
 	@Query("SELECT MAX(serverUpdateAt) FROM TagEntity WHERE owner = :owner")
 	abstract fun getLastUpdateAt(owner: String?): Flow<Instant?>
diff --git a/app/core/diary-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/room/dao/TagRoomDao.kt b/app/core/diary-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/room/dao/TagRoomDao.kt
index 11a40461..4d41ba16 100644
--- a/app/core/diary-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/room/dao/TagRoomDao.kt
+++ b/app/core/diary-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/room/dao/TagRoomDao.kt
@@ -2,9 +2,11 @@ package io.github.taetae98coding.diary.core.diary.database.room.dao
 
 import io.github.taetae98coding.diary.core.diary.database.TagDao
 import io.github.taetae98coding.diary.core.diary.database.room.DiaryDatabase
+import io.github.taetae98coding.diary.core.diary.database.room.entity.MemoEntity
 import io.github.taetae98coding.diary.core.diary.database.room.entity.TagEntity
 import io.github.taetae98coding.diary.core.diary.database.room.mapper.toDto
 import io.github.taetae98coding.diary.core.diary.database.room.mapper.toEntity
+import io.github.taetae98coding.diary.core.model.memo.MemoDto
 import io.github.taetae98coding.diary.core.model.tag.TagDetail
 import io.github.taetae98coding.diary.core.model.tag.TagDto
 import io.github.taetae98coding.diary.library.coroutines.mapCollectionLatest
@@ -17,46 +19,54 @@ import org.koin.core.annotation.Factory
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @Factory
-internal class TagRoomDao(private val clock: Clock, private val database: DiaryDatabase) : TagDao {
-	override suspend fun upsert(tag: TagDto) {
-		database.tag().upsert(tag.toEntity())
-	}
-
-	override suspend fun upsert(tagList: List<TagDto>) {
-		database.tag().upsert(tagList.map(TagDto::toEntity))
-	}
-
-	override suspend fun update(tagId: String, detail: TagDetail) {
-		database.tag().update(
-			tagId = tagId,
-			title = detail.title,
-			description = detail.description,
-			color = detail.color,
-			updateAt = clock.now(),
-		)
-	}
-
-	override suspend fun updateFinish(tagId: String, isFinish: Boolean) {
-		database.tag().updateFinish(tagId, isFinish, clock.now())
-	}
-
-	override suspend fun updateDelete(tagId: String, isDelete: Boolean) {
-		database.tag().updateDelete(tagId, isDelete, clock.now())
-	}
-
-	override fun find(tagId: String, filterNotDelete: Boolean): Flow<TagDto?> = database.tag().find(tagId, filterNotDelete).mapLatest { it?.toDto() }
-
-	override fun findByIds(tagIds: Set<String>, filterNotDelete: Boolean): Flow<List<TagDto>> =
-		database
-			.tag()
-			.findByIds(tagIds, filterNotDelete)
-			.mapCollectionLatest(TagEntity::toDto)
-
-	override fun page(owner: String?): Flow<List<TagDto>> =
-		database
-			.tag()
-			.page(owner)
-			.mapCollectionLatest(TagEntity::toDto)
-
-	override fun getLastServerUpdateAt(owner: String?): Flow<Instant?> = database.tag().getLastUpdateAt(owner)
+internal class TagRoomDao(
+    private val clock: Clock,
+    private val database: DiaryDatabase,
+) : TagDao {
+    override suspend fun upsert(tag: TagDto) {
+        database.tag().upsert(tag.toEntity())
+    }
+
+    override suspend fun upsert(tagList: List<TagDto>) {
+        database.tag().upsert(tagList.map(TagDto::toEntity))
+    }
+
+    override suspend fun update(tagId: String, detail: TagDetail) {
+        database.tag().update(
+            tagId = tagId,
+            title = detail.title,
+            description = detail.description,
+            color = detail.color,
+            updateAt = clock.now(),
+        )
+    }
+
+    override suspend fun updateFinish(tagId: String, isFinish: Boolean) {
+        database.tag().updateFinish(tagId, isFinish, clock.now())
+    }
+
+    override suspend fun updateDelete(tagId: String, isDelete: Boolean) {
+        database.tag().updateDelete(tagId, isDelete, clock.now())
+    }
+
+    override fun page(owner: String?): Flow<List<TagDto>> =
+        database
+            .tag()
+            .page(owner)
+            .mapCollectionLatest(TagEntity::toDto)
+
+    override fun find(tagId: String, filterNotDelete: Boolean): Flow<TagDto?> = database.tag().find(tagId, filterNotDelete).mapLatest { it?.toDto() }
+
+    override fun findByIds(tagIds: Set<String>, filterNotDelete: Boolean): Flow<List<TagDto>> =
+        database
+            .tag()
+            .findByIds(tagIds, filterNotDelete)
+            .mapCollectionLatest(TagEntity::toDto)
+
+    override fun findMemoByTagId(tagId: String): Flow<List<MemoDto>> {
+        return database.tag().findMemoByTagId(tagId)
+            .mapCollectionLatest(MemoEntity::toDto)
+    }
+
+    override fun getLastServerUpdateAt(owner: String?): Flow<Instant?> = database.tag().getLastUpdateAt(owner)
 }
diff --git a/app/core/diary-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/room/mapper/MemoMapper.kt b/app/core/diary-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/room/mapper/MemoMapper.kt
index 611723a9..a8972059 100644
--- a/app/core/diary-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/room/mapper/MemoMapper.kt
+++ b/app/core/diary-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/room/mapper/MemoMapper.kt
@@ -24,13 +24,13 @@ internal fun MemoEntity.toDto(): MemoDto =
 	MemoDto(
 		id = id,
 		detail =
-		MemoDetail(
-			title = title,
-			description = description,
-			start = start,
-			endInclusive = endInclusive,
-			color = color,
-		),
+			MemoDetail(
+				title = title,
+				description = description,
+				start = start,
+				endInclusive = endInclusive,
+				color = color,
+			),
 		owner = owner,
 		primaryTag = primaryTag,
 		isFinish = isFinish,
diff --git a/app/core/diary-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/room/mapper/TagMapper.kt b/app/core/diary-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/room/mapper/TagMapper.kt
index c7102241..0600bcf1 100644
--- a/app/core/diary-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/room/mapper/TagMapper.kt
+++ b/app/core/diary-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/room/mapper/TagMapper.kt
@@ -21,11 +21,11 @@ internal fun TagEntity.toDto(): TagDto =
 	TagDto(
 		id = id,
 		detail =
-		TagDetail(
-			title = title,
-			description = description,
-			color = color,
-		),
+			TagDetail(
+				title = title,
+				description = description,
+				color = color,
+			),
 		owner = owner,
 		isFinish = isFinish,
 		isDelete = isDelete,
diff --git a/app/core/diary-database/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/TagDao.kt b/app/core/diary-database/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/TagDao.kt
index fa0da69d..bcc546bb 100644
--- a/app/core/diary-database/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/TagDao.kt
+++ b/app/core/diary-database/src/commonMain/kotlin/io/github/taetae98coding/diary/core/diary/database/TagDao.kt
@@ -1,5 +1,6 @@
 package io.github.taetae98coding.diary.core.diary.database
 
+import io.github.taetae98coding.diary.core.model.memo.MemoDto
 import io.github.taetae98coding.diary.core.model.tag.TagDetail
 import io.github.taetae98coding.diary.core.model.tag.TagDto
 import kotlinx.coroutines.flow.Flow
@@ -16,11 +17,13 @@ public interface TagDao {
 
 	public suspend fun updateDelete(tagId: String, isDelete: Boolean)
 
+    public fun page(owner: String?): Flow<List<TagDto>>
+
 	public fun find(tagId: String, filterNotDelete: Boolean): Flow<TagDto?>
 
 	public fun findByIds(tagIds: Set<String>, filterNotDelete: Boolean): Flow<List<TagDto>>
 
-	public fun page(owner: String?): Flow<List<TagDto>>
+    public fun findMemoByTagId(tagId: String): Flow<List<MemoDto>>
 
 	public fun getLastServerUpdateAt(owner: String?): Flow<Instant?>
 }
diff --git a/app/core/filter-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/filter/database/room/dao/CalendarFilterRoomDao.kt b/app/core/filter-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/filter/database/room/dao/CalendarFilterRoomDao.kt
index 989bcf92..7dc0fd70 100644
--- a/app/core/filter-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/filter/database/room/dao/CalendarFilterRoomDao.kt
+++ b/app/core/filter-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/filter/database/room/dao/CalendarFilterRoomDao.kt
@@ -10,7 +10,9 @@ import org.koin.core.annotation.Factory
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @Factory
-internal class CalendarFilterRoomDao(private val database: FilterDatabase) : CalendarFilterDao {
+internal class CalendarFilterRoomDao(
+	private val database: FilterDatabase,
+) : CalendarFilterDao {
 	override suspend fun upsert(uid: String?, tagId: String) {
 		database.calendar().upsert(CalendarFilterEntity(uid.orEmpty(), tagId))
 	}
diff --git a/app/core/filter-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/filter/database/room/entity/CalendarFilterEntity.kt b/app/core/filter-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/filter/database/room/entity/CalendarFilterEntity.kt
index aec4af29..c002fe0e 100644
--- a/app/core/filter-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/filter/database/room/entity/CalendarFilterEntity.kt
+++ b/app/core/filter-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/filter/database/room/entity/CalendarFilterEntity.kt
@@ -5,4 +5,7 @@ import androidx.room.Entity
 @Entity(
 	primaryKeys = ["uid", "tagId"],
 )
-internal data class CalendarFilterEntity(val uid: String, val tagId: String)
+internal data class CalendarFilterEntity(
+	val uid: String,
+	val tagId: String,
+)
diff --git a/app/core/holiday-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/holiday/database/room/HolidayRoomDao.kt b/app/core/holiday-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/holiday/database/room/HolidayRoomDao.kt
index 8664e3e6..ebed1c65 100644
--- a/app/core/holiday-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/holiday/database/room/HolidayRoomDao.kt
+++ b/app/core/holiday-database-room/src/commonMain/kotlin/io/github/taetae98coding/diary/core/holiday/database/room/HolidayRoomDao.kt
@@ -9,7 +9,9 @@ import kotlinx.datetime.number
 import org.koin.core.annotation.Factory
 
 @Factory
-internal class HolidayRoomDao(private val database: HolidayDatabase) : HolidayDao {
+internal class HolidayRoomDao(
+	private val database: HolidayDatabase,
+) : HolidayDao {
 	override fun findHoliday(year: Int, month: Month): Flow<List<Holiday>> =
 		database
 			.holidayDao()
diff --git a/app/core/holiday-preferences-datastore/src/commonMain/kotlin/io/github/taetae98coding/diary/core/holiday/preferences/datastore/HolidayDataStorePreferences.kt b/app/core/holiday-preferences-datastore/src/commonMain/kotlin/io/github/taetae98coding/diary/core/holiday/preferences/datastore/HolidayDataStorePreferences.kt
index dee54ce2..5634b1f9 100644
--- a/app/core/holiday-preferences-datastore/src/commonMain/kotlin/io/github/taetae98coding/diary/core/holiday/preferences/datastore/HolidayDataStorePreferences.kt
+++ b/app/core/holiday-preferences-datastore/src/commonMain/kotlin/io/github/taetae98coding/diary/core/holiday/preferences/datastore/HolidayDataStorePreferences.kt
@@ -16,7 +16,10 @@ import kotlinx.datetime.Month
 import kotlinx.datetime.monthsUntil
 import kotlinx.datetime.number
 
-internal class HolidayDataStorePreferences(private val clock: Clock, private val dataStore: DataStore<Preferences>) : HolidayPreferences {
+internal class HolidayDataStorePreferences(
+	private val clock: Clock,
+	private val dataStore: DataStore<Preferences>,
+) : HolidayPreferences {
 	private val memoryDirtyStore = mutableMapOf<Pair<Int, Month>, MutableStateFlow<Boolean>>()
 
 	override fun isDirty(year: Int, month: Month): Flow<Boolean> {
diff --git a/app/core/holiday-service/src/commonMain/kotlin/io/github/taetae98coding/diary/core/holiday/service/HolidayService.kt b/app/core/holiday-service/src/commonMain/kotlin/io/github/taetae98coding/diary/core/holiday/service/HolidayService.kt
index f36e1608..cf424e02 100644
--- a/app/core/holiday-service/src/commonMain/kotlin/io/github/taetae98coding/diary/core/holiday/service/HolidayService.kt
+++ b/app/core/holiday-service/src/commonMain/kotlin/io/github/taetae98coding/diary/core/holiday/service/HolidayService.kt
@@ -16,7 +16,10 @@ import kotlinx.datetime.number
 import kotlinx.serialization.json.Json
 import kotlinx.serialization.json.decodeFromJsonElement
 
-public class HolidayService internal constructor(private val client: HttpClient, private val json: Json) {
+public class HolidayService internal constructor(
+	private val client: HttpClient,
+	private val json: Json,
+) {
 	public suspend fun findHoliday(year: Int, month: Month): List<Holiday> {
 		val response =
 			client.get("getRestDeInfo") {
diff --git a/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/account/Account.kt b/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/account/Account.kt
index 8330c4f2..c0e3445f 100644
--- a/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/account/Account.kt
+++ b/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/account/Account.kt
@@ -7,5 +7,8 @@ public sealed class Account {
 		override val uid: String? = null
 	}
 
-	public data class Member(val email: String, override val uid: String) : Account()
+	public data class Member(
+		val email: String,
+		override val uid: String,
+	) : Account()
 }
diff --git a/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/account/AccountToken.kt b/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/account/AccountToken.kt
index 62d19e85..c2cd6187 100644
--- a/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/account/AccountToken.kt
+++ b/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/account/AccountToken.kt
@@ -1,3 +1,6 @@
 package io.github.taetae98coding.diary.core.model.account
 
-public data class AccountToken(val uid: String, val token: String)
+public data class AccountToken(
+	val uid: String,
+	val token: String,
+)
diff --git a/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/holiday/Holiday.kt b/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/holiday/Holiday.kt
index 06f17b82..05965d1b 100644
--- a/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/holiday/Holiday.kt
+++ b/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/holiday/Holiday.kt
@@ -2,4 +2,8 @@ package io.github.taetae98coding.diary.core.model.holiday
 
 import kotlinx.datetime.LocalDate
 
-public data class Holiday(val name: String, override val start: LocalDate, override val endInclusive: LocalDate) : ClosedRange<LocalDate>
+public data class Holiday(
+	val name: String,
+	override val start: LocalDate,
+	override val endInclusive: LocalDate,
+) : ClosedRange<LocalDate>
diff --git a/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/memo/Memo.kt b/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/memo/Memo.kt
index bf233629..d1c1c2fa 100644
--- a/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/memo/Memo.kt
+++ b/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/memo/Memo.kt
@@ -2,4 +2,12 @@ package io.github.taetae98coding.diary.core.model.memo
 
 import kotlinx.datetime.Instant
 
-public data class Memo(val id: String, val detail: MemoDetail, val primaryTag: String?, val owner: String?, val isFinish: Boolean, val isDelete: Boolean, val updateAt: Instant)
+public data class Memo(
+	val id: String,
+	val detail: MemoDetail,
+	val primaryTag: String?,
+	val owner: String?,
+	val isFinish: Boolean,
+	val isDelete: Boolean,
+	val updateAt: Instant,
+)
diff --git a/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/memo/MemoAndTagIds.kt b/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/memo/MemoAndTagIds.kt
index e87e8156..82a34e4f 100644
--- a/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/memo/MemoAndTagIds.kt
+++ b/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/memo/MemoAndTagIds.kt
@@ -1,3 +1,6 @@
 package io.github.taetae98coding.diary.core.model.memo
 
-public data class MemoAndTagIds(val memo: MemoDto, val tagIds: Set<String>)
+public data class MemoAndTagIds(
+	val memo: MemoDto,
+	val tagIds: Set<String>,
+)
diff --git a/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/memo/MemoDetail.kt b/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/memo/MemoDetail.kt
index 4f12bbad..a89e8667 100644
--- a/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/memo/MemoDetail.kt
+++ b/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/memo/MemoDetail.kt
@@ -2,4 +2,10 @@ package io.github.taetae98coding.diary.core.model.memo
 
 import kotlinx.datetime.LocalDate
 
-public data class MemoDetail(val title: String, val description: String, val start: LocalDate?, val endInclusive: LocalDate?, val color: Int)
+public data class MemoDetail(
+	val title: String,
+	val description: String,
+	val start: LocalDate?,
+	val endInclusive: LocalDate?,
+	val color: Int,
+)
diff --git a/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/memo/MemoDto.kt b/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/memo/MemoDto.kt
index cf865255..33ef40ad 100644
--- a/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/memo/MemoDto.kt
+++ b/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/memo/MemoDto.kt
@@ -2,4 +2,13 @@ package io.github.taetae98coding.diary.core.model.memo
 
 import kotlinx.datetime.Instant
 
-public data class MemoDto(val id: String, val detail: MemoDetail, val owner: String?, val primaryTag: String?, val isFinish: Boolean, val isDelete: Boolean, val updateAt: Instant, val serverUpdateAt: Instant?)
+public data class MemoDto(
+	val id: String,
+	val detail: MemoDetail,
+	val owner: String?,
+	val primaryTag: String?,
+	val isFinish: Boolean,
+	val isDelete: Boolean,
+	val updateAt: Instant,
+	val serverUpdateAt: Instant?,
+)
diff --git a/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/tag/Tag.kt b/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/tag/Tag.kt
index 99f03896..83fc2fe7 100644
--- a/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/tag/Tag.kt
+++ b/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/tag/Tag.kt
@@ -2,4 +2,11 @@ package io.github.taetae98coding.diary.core.model.tag
 
 import kotlinx.datetime.Instant
 
-public data class Tag(val id: String, val detail: TagDetail, val owner: String?, val isFinish: Boolean, val isDelete: Boolean, val updateAt: Instant)
+public data class Tag(
+	val id: String,
+	val detail: TagDetail,
+	val owner: String?,
+	val isFinish: Boolean,
+	val isDelete: Boolean,
+	val updateAt: Instant,
+)
diff --git a/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/tag/TagDetail.kt b/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/tag/TagDetail.kt
index 2689f024..8db387c1 100644
--- a/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/tag/TagDetail.kt
+++ b/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/tag/TagDetail.kt
@@ -1,3 +1,7 @@
 package io.github.taetae98coding.diary.core.model.tag
 
-public data class TagDetail(val title: String, val description: String, val color: Int)
+public data class TagDetail(
+	val title: String,
+	val description: String,
+	val color: Int,
+)
diff --git a/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/tag/TagDto.kt b/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/tag/TagDto.kt
index 7530e4c6..94a50c2b 100644
--- a/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/tag/TagDto.kt
+++ b/app/core/model/src/commonMain/kotlin/io/github/taetae98coding/diary/core/model/tag/TagDto.kt
@@ -2,4 +2,12 @@ package io.github.taetae98coding.diary.core.model.tag
 
 import kotlinx.datetime.Instant
 
-public data class TagDto(val id: String, val detail: TagDetail, val owner: String?, val isFinish: Boolean, val isDelete: Boolean, val updateAt: Instant, val serverUpdateAt: Instant?)
+public data class TagDto(
+	val id: String,
+	val detail: TagDetail,
+	val owner: String?,
+	val isFinish: Boolean,
+	val isDelete: Boolean,
+	val updateAt: Instant,
+	val serverUpdateAt: Instant?,
+)
diff --git a/app/core/navigation/src/commonMain/kotlin/io/github/taetae98coding/diary/core/navigation/memo/MemoAddDestination.kt b/app/core/navigation/src/commonMain/kotlin/io/github/taetae98coding/diary/core/navigation/memo/MemoAddDestination.kt
index 834e606e..0c9e75c6 100644
--- a/app/core/navigation/src/commonMain/kotlin/io/github/taetae98coding/diary/core/navigation/memo/MemoAddDestination.kt
+++ b/app/core/navigation/src/commonMain/kotlin/io/github/taetae98coding/diary/core/navigation/memo/MemoAddDestination.kt
@@ -6,8 +6,14 @@ import kotlinx.serialization.Serializable
 
 @Serializable
 public data class MemoAddDestination(
-	@SerialName("start")
+    @SerialName("start")
 	val start: LocalDate? = null,
-	@SerialName("endInclusive")
+    @SerialName("endInclusive")
 	val endInclusive: LocalDate? = null,
-)
+    @SerialName(SELECTED_TAG)
+    val selectedTag: String? = null,
+) {
+    public companion object {
+        public const val SELECTED_TAG: String = "selectedTag"
+    }
+}
diff --git a/app/data/account/src/commonMain/kotlin/io/github/taetae98coding/diary/data/account/repository/AccountRepositoryImpl.kt b/app/data/account/src/commonMain/kotlin/io/github/taetae98coding/diary/data/account/repository/AccountRepositoryImpl.kt
index a35c1039..3fdea4ae 100644
--- a/app/data/account/src/commonMain/kotlin/io/github/taetae98coding/diary/data/account/repository/AccountRepositoryImpl.kt
+++ b/app/data/account/src/commonMain/kotlin/io/github/taetae98coding/diary/data/account/repository/AccountRepositoryImpl.kt
@@ -6,7 +6,9 @@ import kotlinx.coroutines.flow.Flow
 import org.koin.core.annotation.Factory
 
 @Factory
-internal class AccountRepositoryImpl(private val preferencesDataSource: AccountPreferences) : AccountRepository {
+internal class AccountRepositoryImpl(
+	private val preferencesDataSource: AccountPreferences,
+) : AccountRepository {
 	override fun getEmail(): Flow<String?> = preferencesDataSource.getEmail()
 
 	override fun getUid(): Flow<String?> = preferencesDataSource.getUid()
diff --git a/app/data/backup/src/commonMain/kotlin/io/github/taetae98coding/diary/data/backup/repository/MemoBackupRepositoryImpl.kt b/app/data/backup/src/commonMain/kotlin/io/github/taetae98coding/diary/data/backup/repository/MemoBackupRepositoryImpl.kt
index 41c2003f..77db2f0c 100644
--- a/app/data/backup/src/commonMain/kotlin/io/github/taetae98coding/diary/data/backup/repository/MemoBackupRepositoryImpl.kt
+++ b/app/data/backup/src/commonMain/kotlin/io/github/taetae98coding/diary/data/backup/repository/MemoBackupRepositoryImpl.kt
@@ -10,7 +10,11 @@ import kotlinx.coroutines.sync.withLock
 import org.koin.core.annotation.Factory
 
 @Factory
-internal class MemoBackupRepositoryImpl(private val memoDao: MemoDao, private val memoBackupDao: MemoBackupDao, private val memoService: MemoService) : MemoBackupRepository {
+internal class MemoBackupRepositoryImpl(
+	private val memoDao: MemoDao,
+	private val memoBackupDao: MemoBackupDao,
+	private val memoService: MemoService,
+) : MemoBackupRepository {
 	override suspend fun backup(uid: String) {
 		mutex.withLock {
 			while (true) {
diff --git a/app/data/backup/src/commonMain/kotlin/io/github/taetae98coding/diary/data/backup/repository/TagBackupRepositoryImpl.kt b/app/data/backup/src/commonMain/kotlin/io/github/taetae98coding/diary/data/backup/repository/TagBackupRepositoryImpl.kt
index 3e1e1cc3..f34b76d3 100644
--- a/app/data/backup/src/commonMain/kotlin/io/github/taetae98coding/diary/data/backup/repository/TagBackupRepositoryImpl.kt
+++ b/app/data/backup/src/commonMain/kotlin/io/github/taetae98coding/diary/data/backup/repository/TagBackupRepositoryImpl.kt
@@ -10,7 +10,11 @@ import kotlinx.coroutines.sync.withLock
 import org.koin.core.annotation.Factory
 
 @Factory
-internal class TagBackupRepositoryImpl(private val tagDao: TagDao, private val tagBackupDao: TagBackupDao, private val tagService: TagService) : TagBackupRepository {
+internal class TagBackupRepositoryImpl(
+	private val tagDao: TagDao,
+	private val tagBackupDao: TagBackupDao,
+	private val tagService: TagService,
+) : TagBackupRepository {
 	override suspend fun backup(uid: String) {
 		mutex.withLock {
 			while (true) {
diff --git a/app/data/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/data/calendar/repository/CalendarRepositoryImpl.kt b/app/data/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/data/calendar/repository/CalendarRepositoryImpl.kt
index c98cebaa..70b4fe9f 100644
--- a/app/data/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/data/calendar/repository/CalendarRepositoryImpl.kt
+++ b/app/data/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/data/calendar/repository/CalendarRepositoryImpl.kt
@@ -6,7 +6,9 @@ import kotlinx.coroutines.flow.Flow
 import org.koin.core.annotation.Factory
 
 @Factory
-internal class CalendarRepositoryImpl(private val localDataSource: CalendarFilterDao) : CalendarRepository {
+internal class CalendarRepositoryImpl(
+	private val localDataSource: CalendarFilterDao,
+) : CalendarRepository {
 	override suspend fun upsert(uid: String?, tagId: String) {
 		localDataSource.upsert(uid, tagId)
 	}
diff --git a/app/data/credential/src/commonMain/kotlin/io/github/taetae98coding/diary/data/credential/repository/CredentialRepositoryImpl.kt b/app/data/credential/src/commonMain/kotlin/io/github/taetae98coding/diary/data/credential/repository/CredentialRepositoryImpl.kt
index 73dcbeb7..7f871154 100644
--- a/app/data/credential/src/commonMain/kotlin/io/github/taetae98coding/diary/data/credential/repository/CredentialRepositoryImpl.kt
+++ b/app/data/credential/src/commonMain/kotlin/io/github/taetae98coding/diary/data/credential/repository/CredentialRepositoryImpl.kt
@@ -9,7 +9,10 @@ import kotlinx.coroutines.flow.flow
 import org.koin.core.annotation.Factory
 
 @Factory
-internal class CredentialRepositoryImpl(private val preferencesDataSource: AccountPreferences, private val remoteDataSource: AccountService) : CredentialRepository {
+internal class CredentialRepositoryImpl(
+	private val preferencesDataSource: AccountPreferences,
+	private val remoteDataSource: AccountService,
+) : CredentialRepository {
 	override suspend fun join(email: String, password: String) {
 		remoteDataSource.join(email, password)
 	}
diff --git a/app/data/fcm/src/commonMain/kotlin/io/github/taetae98coding/diary/data/fcm/repository/FCMRepositoryImpl.kt b/app/data/fcm/src/commonMain/kotlin/io/github/taetae98coding/diary/data/fcm/repository/FCMRepositoryImpl.kt
index aeacbc20..65f63c10 100644
--- a/app/data/fcm/src/commonMain/kotlin/io/github/taetae98coding/diary/data/fcm/repository/FCMRepositoryImpl.kt
+++ b/app/data/fcm/src/commonMain/kotlin/io/github/taetae98coding/diary/data/fcm/repository/FCMRepositoryImpl.kt
@@ -6,7 +6,10 @@ import io.github.taetae98coding.diary.library.firebase.messaging.KFirebaseMessag
 import org.koin.core.annotation.Factory
 
 @Factory
-internal class FCMRepositoryImpl(private val messaging: KFirebaseMessaging, private val remoteDataSource: FCMService) : FCMRepository {
+internal class FCMRepositoryImpl(
+	private val messaging: KFirebaseMessaging,
+	private val remoteDataSource: FCMService,
+) : FCMRepository {
 	override suspend fun upsert() {
 		remoteDataSource.upsert(messaging.getToken())
 	}
diff --git a/app/data/fetch/src/commonMain/kotlin/io/github/taetae98coding/diary/data/fetch/repository/MemoFetchRepositoryImpl.kt b/app/data/fetch/src/commonMain/kotlin/io/github/taetae98coding/diary/data/fetch/repository/MemoFetchRepositoryImpl.kt
index 2c1fbb6f..00594185 100644
--- a/app/data/fetch/src/commonMain/kotlin/io/github/taetae98coding/diary/data/fetch/repository/MemoFetchRepositoryImpl.kt
+++ b/app/data/fetch/src/commonMain/kotlin/io/github/taetae98coding/diary/data/fetch/repository/MemoFetchRepositoryImpl.kt
@@ -10,7 +10,10 @@ import kotlinx.datetime.Instant
 import org.koin.core.annotation.Factory
 
 @Factory
-internal class MemoFetchRepositoryImpl(private val localDataSource: MemoDao, private val remoteDataSource: MemoService) : MemoFetchRepository {
+internal class MemoFetchRepositoryImpl(
+	private val localDataSource: MemoDao,
+	private val remoteDataSource: MemoService,
+) : MemoFetchRepository {
 	override suspend fun fetch(uid: String) {
 		mutex.withLock {
 			while (true) {
diff --git a/app/data/fetch/src/commonMain/kotlin/io/github/taetae98coding/diary/data/fetch/repository/TagFetchRepositoryImpl.kt b/app/data/fetch/src/commonMain/kotlin/io/github/taetae98coding/diary/data/fetch/repository/TagFetchRepositoryImpl.kt
index cea97815..d4ad3140 100644
--- a/app/data/fetch/src/commonMain/kotlin/io/github/taetae98coding/diary/data/fetch/repository/TagFetchRepositoryImpl.kt
+++ b/app/data/fetch/src/commonMain/kotlin/io/github/taetae98coding/diary/data/fetch/repository/TagFetchRepositoryImpl.kt
@@ -10,7 +10,10 @@ import kotlinx.datetime.Instant
 import org.koin.core.annotation.Factory
 
 @Factory
-internal class TagFetchRepositoryImpl(private val localDataSource: TagDao, private val remoteDataSource: TagService) : TagFetchRepository {
+internal class TagFetchRepositoryImpl(
+	private val localDataSource: TagDao,
+	private val remoteDataSource: TagService,
+) : TagFetchRepository {
 	override suspend fun fetch(uid: String) {
 		mutex.withLock {
 			while (true) {
diff --git a/app/data/holiday/src/commonMain/kotlin/io/github/taetae98coding/diary/data/holiday/repository/HolidayRepositoryImpl.kt b/app/data/holiday/src/commonMain/kotlin/io/github/taetae98coding/diary/data/holiday/repository/HolidayRepositoryImpl.kt
index 5c6d12c1..977c6931 100644
--- a/app/data/holiday/src/commonMain/kotlin/io/github/taetae98coding/diary/data/holiday/repository/HolidayRepositoryImpl.kt
+++ b/app/data/holiday/src/commonMain/kotlin/io/github/taetae98coding/diary/data/holiday/repository/HolidayRepositoryImpl.kt
@@ -30,7 +30,11 @@ import org.koin.core.annotation.Factory
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @Factory
-internal class HolidayRepositoryImpl(private val preferencesDataSource: HolidayPreferences, private val localDataSource: HolidayDao, private val remoteDataSource: HolidayService) : HolidayRepository {
+internal class HolidayRepositoryImpl(
+	private val preferencesDataSource: HolidayPreferences,
+	private val localDataSource: HolidayDao,
+	private val remoteDataSource: HolidayService,
+) : HolidayRepository {
 	override fun findHoliday(year: Int, month: Month): Flow<List<Holiday>> {
 		val localDate = LocalDate(year, month, 1)
 		val list = IntRange(-1, 1).map { localDate.plus(it, DateTimeUnit.MONTH) }
diff --git a/app/data/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/data/memo/repository/MemoRepositoryImpl.kt b/app/data/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/data/memo/repository/MemoRepositoryImpl.kt
index 308841ef..ca915e51 100644
--- a/app/data/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/data/memo/repository/MemoRepositoryImpl.kt
+++ b/app/data/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/data/memo/repository/MemoRepositoryImpl.kt
@@ -17,7 +17,9 @@ import org.koin.core.annotation.Factory
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @Factory
-internal class MemoRepositoryImpl(private val localDataSource: MemoDao) : MemoRepository {
+internal class MemoRepositoryImpl(
+	private val localDataSource: MemoDao,
+) : MemoRepository {
 	override suspend fun upsert(memo: Memo, tagIds: Set<String>) {
 		localDataSource.upsert(MemoAndTagIds(memo.toDto(), tagIds))
 	}
diff --git a/app/data/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/data/memo/repository/MemoTagRepositoryImpl.kt b/app/data/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/data/memo/repository/MemoTagRepositoryImpl.kt
index 84cf34a1..b9886e6a 100644
--- a/app/data/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/data/memo/repository/MemoTagRepositoryImpl.kt
+++ b/app/data/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/data/memo/repository/MemoTagRepositoryImpl.kt
@@ -6,7 +6,9 @@ import kotlinx.coroutines.flow.Flow
 import org.koin.core.annotation.Factory
 
 @Factory
-internal class MemoTagRepositoryImpl(private val localDataSource: MemoTagDao) : MemoTagRepository {
+internal class MemoTagRepositoryImpl(
+	private val localDataSource: MemoTagDao,
+) : MemoTagRepository {
 	override fun findTagIdsByMemoId(memoId: String): Flow<Set<String>> = localDataSource.findTagIdsByMemoId(memoId)
 
 	override suspend fun upsert(memoId: String, tagId: String) {
diff --git a/app/data/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/data/tag/repository/TagRepositoryImpl.kt b/app/data/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/data/tag/repository/TagRepositoryImpl.kt
index 6ae1f704..d0cc28ef 100644
--- a/app/data/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/data/tag/repository/TagRepositoryImpl.kt
+++ b/app/data/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/data/tag/repository/TagRepositoryImpl.kt
@@ -2,7 +2,10 @@ package io.github.taetae98coding.diary.data.tag.repository
 
 import io.github.taetae98coding.diary.core.diary.database.TagDao
 import io.github.taetae98coding.diary.core.model.mapper.toDto
+import io.github.taetae98coding.diary.core.model.mapper.toMemo
 import io.github.taetae98coding.diary.core.model.mapper.toTag
+import io.github.taetae98coding.diary.core.model.memo.Memo
+import io.github.taetae98coding.diary.core.model.memo.MemoDto
 import io.github.taetae98coding.diary.core.model.tag.Tag
 import io.github.taetae98coding.diary.core.model.tag.TagDetail
 import io.github.taetae98coding.diary.core.model.tag.TagDto
@@ -15,32 +18,38 @@ import org.koin.core.annotation.Factory
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @Factory
-internal class TagRepositoryImpl(private val localDataSource: TagDao) : TagRepository {
-	override suspend fun upsert(tag: Tag) {
-		localDataSource.upsert(tag.toDto())
-	}
-
-	override suspend fun update(tagId: String, detail: TagDetail) {
-		localDataSource.update(tagId, detail)
-	}
-
-	override suspend fun updateDelete(tagId: String, isDelete: Boolean) {
-		localDataSource.updateDelete(tagId, isDelete)
-	}
-
-	override suspend fun updateFinish(tagId: String, isFinish: Boolean) {
-		localDataSource.updateFinish(tagId, isFinish)
-	}
-
-	override fun find(tagId: String): Flow<Tag?> = localDataSource.find(tagId, true).mapLatest { it?.toTag() }
-
-	override fun findByIds(tagIds: Set<String>): Flow<List<Tag>> =
-		localDataSource
-			.findByIds(tagIds, true)
-			.mapCollectionLatest(TagDto::toTag)
-
-	override fun page(owner: String?): Flow<List<Tag>> =
-		localDataSource
-			.page(owner)
-			.mapCollectionLatest(TagDto::toTag)
+internal class TagRepositoryImpl(
+    private val localDataSource: TagDao,
+) : TagRepository {
+    override suspend fun upsert(tag: Tag) {
+        localDataSource.upsert(tag.toDto())
+    }
+
+    override suspend fun update(tagId: String, detail: TagDetail) {
+        localDataSource.update(tagId, detail)
+    }
+
+    override suspend fun updateDelete(tagId: String, isDelete: Boolean) {
+        localDataSource.updateDelete(tagId, isDelete)
+    }
+
+    override suspend fun updateFinish(tagId: String, isFinish: Boolean) {
+        localDataSource.updateFinish(tagId, isFinish)
+    }
+
+    override fun page(owner: String?): Flow<List<Tag>> = localDataSource
+        .page(owner)
+        .mapCollectionLatest(TagDto::toTag)
+
+    override fun find(tagId: String): Flow<Tag?> = localDataSource.find(tagId, true).mapLatest { it?.toTag() }
+
+    override fun findByIds(tagIds: Set<String>): Flow<List<Tag>> =
+        localDataSource
+            .findByIds(tagIds, true)
+            .mapCollectionLatest(TagDto::toTag)
+
+    override fun findMemoByTagId(tagId: String): Flow<List<Memo>> {
+        return localDataSource.findMemoByTagId(tagId)
+            .mapCollectionLatest(MemoDto::toMemo)
+    }
 }
diff --git a/app/domain/account/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/account/usecase/GetAccountUseCase.kt b/app/domain/account/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/account/usecase/GetAccountUseCase.kt
index 89adc4d0..5e11d2c8 100644
--- a/app/domain/account/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/account/usecase/GetAccountUseCase.kt
+++ b/app/domain/account/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/account/usecase/GetAccountUseCase.kt
@@ -13,7 +13,9 @@ import org.koin.core.annotation.Factory
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @Factory
-public class GetAccountUseCase(private val repository: AccountRepository) {
+public class GetAccountUseCase(
+	private val repository: AccountRepository,
+) {
 	public operator fun invoke(): Flow<Result<Account>> =
 		flow {
 			combine(
diff --git a/app/domain/account/src/jvmTest/kotlin/io/github/taetae98coding/diary/domain/account/GetAccountUseCaseTest.kt b/app/domain/account/src/jvmTest/kotlin/io/github/taetae98coding/diary/domain/account/GetAccountUseCaseTest.kt
new file mode 100644
index 00000000..f18e1311
--- /dev/null
+++ b/app/domain/account/src/jvmTest/kotlin/io/github/taetae98coding/diary/domain/account/GetAccountUseCaseTest.kt
@@ -0,0 +1,56 @@
+package io.github.taetae98coding.diary.domain.account
+
+import io.github.taetae98coding.diary.core.model.account.Account
+import io.github.taetae98coding.diary.domain.account.repository.AccountRepository
+import io.github.taetae98coding.diary.domain.account.usecase.GetAccountUseCase
+import io.kotest.core.spec.style.BehaviorSpec
+import io.kotest.matchers.result.shouldBeSuccess
+import io.mockk.clearAllMocks
+import io.mockk.every
+import io.mockk.mockk
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.flowOf
+
+class GetAccountUseCaseTest : BehaviorSpec() {
+	init {
+		val accountRepository = mockk<AccountRepository>()
+		val useCase = GetAccountUseCase(
+			repository = accountRepository,
+		)
+
+		Given("no uid and email") {
+			every { accountRepository.getUid() } returns flowOf(null)
+			every { accountRepository.getEmail() } returns flowOf(null)
+
+			When("call usecase") {
+				val result = useCase().first()
+
+				Then("result is guest") {
+					result.shouldBeSuccess(mockk<Account.Guest>())
+				}
+			}
+
+			clearAllMocks()
+		}
+
+		Given("has uid and email") {
+			val account = mockk<Account.Member> {
+				every { uid } returns "uid"
+				every { email } returns "email"
+			}
+
+			every { accountRepository.getUid() } returns flowOf(account.uid)
+			every { accountRepository.getEmail() } returns flowOf(account.email)
+
+			When("call usecase") {
+				val result = useCase().first()
+
+				Then("result is member") {
+					result.shouldBeSuccess(account)
+				}
+			}
+
+			clearAllMocks()
+		}
+	}
+}
diff --git a/app/domain/backup/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/backup/usecase/BackupUseCase.kt b/app/domain/backup/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/backup/usecase/BackupUseCase.kt
index 7c0aedd3..d4ca1ae6 100644
--- a/app/domain/backup/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/backup/usecase/BackupUseCase.kt
+++ b/app/domain/backup/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/backup/usecase/BackupUseCase.kt
@@ -8,7 +8,11 @@ import kotlinx.coroutines.flow.first
 import org.koin.core.annotation.Factory
 
 @Factory
-public class BackupUseCase internal constructor(private val getAccountUseCase: GetAccountUseCase, private val tagBackupRepository: TagBackupRepository, private val memoBackupRepository: MemoBackupRepository) {
+public class BackupUseCase internal constructor(
+	private val getAccountUseCase: GetAccountUseCase,
+	private val tagBackupRepository: TagBackupRepository,
+	private val memoBackupRepository: MemoBackupRepository,
+) {
 	public suspend operator fun invoke(): Result<Unit> =
 		runCatching {
 			val account = getAccountUseCase().first().getOrThrow()
diff --git a/app/domain/backup/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/backup/usecase/PushMemoBackupQueueUseCase.kt b/app/domain/backup/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/backup/usecase/PushMemoBackupQueueUseCase.kt
index abb527e8..4c529493 100644
--- a/app/domain/backup/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/backup/usecase/PushMemoBackupQueueUseCase.kt
+++ b/app/domain/backup/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/backup/usecase/PushMemoBackupQueueUseCase.kt
@@ -9,7 +9,12 @@ import kotlinx.coroutines.launch
 import org.koin.core.annotation.Factory
 
 @Factory
-public class PushMemoBackupQueueUseCase internal constructor(private val getAccountUseCase: GetAccountUseCase, private val backupUseCase: BackupUseCase, private val coroutineScope: CoroutineScope, private val repository: MemoBackupRepository) {
+public class PushMemoBackupQueueUseCase internal constructor(
+	private val getAccountUseCase: GetAccountUseCase,
+	private val backupUseCase: BackupUseCase,
+	private val coroutineScope: CoroutineScope,
+	private val repository: MemoBackupRepository,
+) {
 	public suspend operator fun invoke(memoId: String?): Result<Unit> {
 		return runCatching {
 			if (memoId.isNullOrBlank()) return@runCatching
diff --git a/app/domain/backup/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/backup/usecase/PushTagBackupQueueUseCase.kt b/app/domain/backup/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/backup/usecase/PushTagBackupQueueUseCase.kt
index 5d116015..4076dc95 100644
--- a/app/domain/backup/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/backup/usecase/PushTagBackupQueueUseCase.kt
+++ b/app/domain/backup/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/backup/usecase/PushTagBackupQueueUseCase.kt
@@ -9,7 +9,12 @@ import kotlinx.coroutines.launch
 import org.koin.core.annotation.Factory
 
 @Factory
-public class PushTagBackupQueueUseCase internal constructor(private val getAccountUseCase: GetAccountUseCase, private val backupUseCase: BackupUseCase, private val coroutineScope: CoroutineScope, private val repository: TagBackupRepository) {
+public class PushTagBackupQueueUseCase internal constructor(
+	private val getAccountUseCase: GetAccountUseCase,
+	private val backupUseCase: BackupUseCase,
+	private val coroutineScope: CoroutineScope,
+	private val repository: TagBackupRepository,
+) {
 	public suspend operator fun invoke(tagId: String?): Result<Unit> {
 		return runCatching {
 			if (tagId.isNullOrBlank()) return@runCatching
diff --git a/app/domain/backup/src/jvmTest/kotlin/io/github/taetae98coding/diary/domain/backup/BackupUseCaseTest.kt b/app/domain/backup/src/jvmTest/kotlin/io/github/taetae98coding/diary/domain/backup/BackupUseCaseTest.kt
new file mode 100644
index 00000000..601493a2
--- /dev/null
+++ b/app/domain/backup/src/jvmTest/kotlin/io/github/taetae98coding/diary/domain/backup/BackupUseCaseTest.kt
@@ -0,0 +1,77 @@
+package io.github.taetae98coding.diary.domain.backup
+
+import io.github.taetae98coding.diary.core.model.account.Account
+import io.github.taetae98coding.diary.domain.account.usecase.GetAccountUseCase
+import io.github.taetae98coding.diary.domain.backup.repository.MemoBackupRepository
+import io.github.taetae98coding.diary.domain.backup.repository.TagBackupRepository
+import io.github.taetae98coding.diary.domain.backup.usecase.BackupUseCase
+import io.kotest.core.spec.style.BehaviorSpec
+import io.kotest.matchers.result.shouldBeSuccess
+import io.mockk.Called
+import io.mockk.clearAllMocks
+import io.mockk.coVerify
+import io.mockk.every
+import io.mockk.mockk
+import io.mockk.verify
+import kotlinx.coroutines.flow.flowOf
+
+class BackupUseCaseTest : BehaviorSpec() {
+	init {
+		val getAccountUseCase = mockk<GetAccountUseCase>()
+		val memoBackupRepository = mockk<MemoBackupRepository>(relaxed = true, relaxUnitFun = true)
+		val tagBackupRepository = mockk<TagBackupRepository>(relaxed = true, relaxUnitFun = true)
+
+		val useCase = BackupUseCase(
+			getAccountUseCase = getAccountUseCase,
+			memoBackupRepository = memoBackupRepository,
+			tagBackupRepository = tagBackupRepository,
+		)
+
+		Given("account is Guest") {
+			every { getAccountUseCase() } returns flowOf(Result.success(mockk<Account.Guest>()))
+
+			When("call usecase") {
+				val result = useCase()
+
+				Then("result is success") {
+					result.shouldBeSuccess()
+				}
+
+				Then("do nothing") {
+					verify {
+						tagBackupRepository wasNot Called
+						memoBackupRepository wasNot Called
+					}
+				}
+			}
+
+			clearAllMocks()
+		}
+
+		Given("account is Member") {
+			val accountUid = "uid"
+			val account = mockk<Account.Member> {
+				every { uid } returns accountUid
+			}
+
+			every { getAccountUseCase() } returns flowOf(Result.success(account))
+
+			When("call usecase") {
+				val result = useCase()
+
+				Then("result is success") {
+					result.shouldBeSuccess()
+				}
+
+				Then("do backup") {
+					coVerify {
+						tagBackupRepository.backup(accountUid)
+						memoBackupRepository.backup(accountUid)
+					}
+				}
+			}
+
+			clearAllMocks()
+		}
+	}
+}
diff --git a/app/domain/backup/src/jvmTest/kotlin/io/github/taetae98coding/diary/domain/backup/PushMemoBackupQueueUseCaseTest.kt b/app/domain/backup/src/jvmTest/kotlin/io/github/taetae98coding/diary/domain/backup/PushMemoBackupQueueUseCaseTest.kt
new file mode 100644
index 00000000..5f394bc6
--- /dev/null
+++ b/app/domain/backup/src/jvmTest/kotlin/io/github/taetae98coding/diary/domain/backup/PushMemoBackupQueueUseCaseTest.kt
@@ -0,0 +1,122 @@
+package io.github.taetae98coding.diary.domain.backup
+
+import io.github.taetae98coding.diary.core.model.account.Account
+import io.github.taetae98coding.diary.domain.account.usecase.GetAccountUseCase
+import io.github.taetae98coding.diary.domain.backup.repository.MemoBackupRepository
+import io.github.taetae98coding.diary.domain.backup.usecase.BackupUseCase
+import io.github.taetae98coding.diary.domain.backup.usecase.PushMemoBackupQueueUseCase
+import io.kotest.core.concurrency.CoroutineDispatcherFactory
+import io.kotest.core.spec.style.BehaviorSpec
+import io.kotest.core.test.TestCase
+import io.kotest.matchers.result.shouldBeSuccess
+import io.mockk.Called
+import io.mockk.clearAllMocks
+import io.mockk.coVerify
+import io.mockk.every
+import io.mockk.mockk
+import io.mockk.verify
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.withContext
+
+@OptIn(ExperimentalCoroutinesApi::class)
+class PushMemoBackupQueueUseCaseTest : BehaviorSpec() {
+	init {
+		val dispatcher = UnconfinedTestDispatcher()
+		val scope = CoroutineScope(dispatcher)
+
+		coroutineDispatcherFactory = object : CoroutineDispatcherFactory {
+			override suspend fun <T> withDispatcher(
+				testCase: TestCase,
+				f: suspend () -> T,
+			): T = withContext(dispatcher) {
+				f()
+			}
+		}
+
+		val getAccountUseCase = mockk<GetAccountUseCase>()
+		val backupUseCase = mockk<BackupUseCase>(relaxed = true, relaxUnitFun = true)
+		val memoBackupRepository = mockk<MemoBackupRepository>(relaxed = true, relaxUnitFun = true)
+		val useCase = PushMemoBackupQueueUseCase(
+			getAccountUseCase = getAccountUseCase,
+			backupUseCase = backupUseCase,
+			coroutineScope = scope,
+			repository = memoBackupRepository,
+		)
+
+		Given("memoId is null") {
+			val memoId = null
+
+			When("call usecase") {
+				val result = useCase(memoId)
+
+				Then("result is success") {
+					result.shouldBeSuccess()
+				}
+
+				Then("do nothing") {
+					verify {
+						getAccountUseCase wasNot Called
+						backupUseCase wasNot Called
+						memoBackupRepository wasNot Called
+					}
+				}
+			}
+
+			clearAllMocks()
+		}
+
+		Given("memoId is not null") {
+			val memoId = "memoId"
+
+			And("account is Guest") {
+				every { getAccountUseCase() } returns flowOf(Result.success(mockk<Account.Guest>()))
+
+				When("call usecase") {
+					val result = useCase(memoId)
+
+					Then("result is success") {
+						result.shouldBeSuccess()
+					}
+
+					Then("do not backup") {
+						verify {
+							memoBackupRepository wasNot Called
+							backupUseCase wasNot Called
+						}
+					}
+				}
+
+				clearAllMocks()
+			}
+
+			And("account is Member") {
+				val accountUid = "uid"
+				val account = mockk<Account.Member> {
+					every { uid } returns accountUid
+				}
+
+				every { getAccountUseCase() } returns flowOf(Result.success(account))
+
+				When("call usecase") {
+					val result = useCase(memoId)
+
+					Then("result is success") {
+						result.shouldBeSuccess()
+					}
+
+					Then("do backup") {
+						coVerify {
+							memoBackupRepository.upsertBackupQueue(accountUid, memoId)
+							backupUseCase()
+						}
+					}
+				}
+
+				clearAllMocks()
+			}
+		}
+	}
+}
diff --git a/app/domain/backup/src/jvmTest/kotlin/io/github/taetae98coding/diary/domain/backup/PushTagBackupQueueUseCaseTest.kt b/app/domain/backup/src/jvmTest/kotlin/io/github/taetae98coding/diary/domain/backup/PushTagBackupQueueUseCaseTest.kt
new file mode 100644
index 00000000..ccec6831
--- /dev/null
+++ b/app/domain/backup/src/jvmTest/kotlin/io/github/taetae98coding/diary/domain/backup/PushTagBackupQueueUseCaseTest.kt
@@ -0,0 +1,118 @@
+package io.github.taetae98coding.diary.domain.backup
+
+import io.github.taetae98coding.diary.core.model.account.Account
+import io.github.taetae98coding.diary.domain.account.usecase.GetAccountUseCase
+import io.github.taetae98coding.diary.domain.backup.repository.TagBackupRepository
+import io.github.taetae98coding.diary.domain.backup.usecase.BackupUseCase
+import io.github.taetae98coding.diary.domain.backup.usecase.PushTagBackupQueueUseCase
+import io.kotest.core.concurrency.CoroutineDispatcherFactory
+import io.kotest.core.spec.style.BehaviorSpec
+import io.kotest.core.test.TestCase
+import io.kotest.matchers.result.shouldBeSuccess
+import io.mockk.Called
+import io.mockk.clearAllMocks
+import io.mockk.coVerify
+import io.mockk.every
+import io.mockk.mockk
+import io.mockk.verify
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.withContext
+
+@OptIn(ExperimentalCoroutinesApi::class)
+class PushTagBackupQueueUseCaseTest : BehaviorSpec() {
+	init {
+		val dispatcher = UnconfinedTestDispatcher()
+		val scope = CoroutineScope(dispatcher)
+
+		coroutineDispatcherFactory = object : CoroutineDispatcherFactory {
+			override suspend fun <T> withDispatcher(testCase: TestCase, f: suspend () -> T): T = withContext(dispatcher) {
+				f()
+			}
+		}
+
+		val getAccountUseCase = mockk<GetAccountUseCase>()
+		val backupUseCase = mockk<BackupUseCase>(relaxed = true, relaxUnitFun = true)
+		val tagBackupRepository = mockk<TagBackupRepository>(relaxed = true, relaxUnitFun = true)
+		val useCase = PushTagBackupQueueUseCase(
+			getAccountUseCase = getAccountUseCase,
+			backupUseCase = backupUseCase,
+			coroutineScope = scope,
+			repository = tagBackupRepository,
+		)
+
+		Given("tagId is null") {
+			val tagId = null
+
+			When("call usecase") {
+				val result = useCase(tagId)
+
+				Then("result is success") {
+					result.shouldBeSuccess()
+				}
+
+				Then("do nothing") {
+					verify {
+						getAccountUseCase wasNot Called
+						backupUseCase wasNot Called
+						tagBackupRepository wasNot Called
+					}
+				}
+			}
+		}
+
+		Given("tagId is not null") {
+			val tagId = "tagId"
+
+			And("account is Guest") {
+				every { getAccountUseCase.invoke() } returns flowOf(Result.success(mockk<Account.Guest>()))
+
+				When("call usecase") {
+					val result = useCase(tagId)
+
+					Then("result is success") {
+						result.shouldBeSuccess()
+					}
+
+					Then("do not backup") {
+						verify {
+							backupUseCase wasNot Called
+							tagBackupRepository wasNot Called
+						}
+					}
+				}
+
+				clearAllMocks()
+			}
+
+			And("account is Member") {
+				val accountUid = "uid"
+				val account = mockk<Account.Member> {
+					every { this@mockk.uid } returns accountUid
+				}
+
+				every { getAccountUseCase.invoke() } returns flowOf(Result.success(account))
+
+				When("call usecase") {
+					val result = useCase(tagId)
+
+					Then("result is success") {
+						result.shouldBeSuccess()
+					}
+
+					Then("do backup") {
+
+						coVerify {
+							tagBackupRepository.upsertBackupQueue(accountUid, tagId)
+							backupUseCase()
+						}
+					}
+				}
+
+				clearAllMocks()
+			}
+		}
+	}
+}
diff --git a/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/entity/CalendarTagFilter.kt b/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/entity/CalendarTagFilter.kt
index 99791fdf..1484c42b 100644
--- a/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/entity/CalendarTagFilter.kt
+++ b/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/entity/CalendarTagFilter.kt
@@ -2,4 +2,7 @@ package io.github.taetae98coding.diary.domain.calendar.entity
 
 import io.github.taetae98coding.diary.core.model.tag.Tag
 
-public data class CalendarTagFilter(val tag: Tag, val isSelected: Boolean)
+public data class CalendarTagFilter(
+	val tag: Tag,
+	val isSelected: Boolean,
+)
diff --git a/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/usecase/DeleteCalendarTagUseCase.kt b/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/usecase/DeleteCalendarTagUseCase.kt
index 9073c454..fef2137f 100644
--- a/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/usecase/DeleteCalendarTagUseCase.kt
+++ b/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/usecase/DeleteCalendarTagUseCase.kt
@@ -6,9 +6,14 @@ import kotlinx.coroutines.flow.first
 import org.koin.core.annotation.Factory
 
 @Factory
-public class DeleteCalendarTagUseCase internal constructor(private val getAccountUseCase: GetAccountUseCase, private val repository: CalendarRepository) {
-	public suspend operator fun invoke(tagId: String): Result<Unit> =
+public class DeleteCalendarTagUseCase internal constructor(
+	private val getAccountUseCase: GetAccountUseCase,
+	private val repository: CalendarRepository,
+) {
+	public suspend operator fun invoke(tagId: String?): Result<Unit> =
 		runCatching {
+			if (tagId.isNullOrBlank()) return@runCatching
+
 			val account = getAccountUseCase().first().getOrThrow()
 			repository.delete(account.uid, tagId)
 		}
diff --git a/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/usecase/FindCalendarFilterTagUseCase.kt b/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/usecase/FindCalendarFilterTagUseCase.kt
deleted file mode 100644
index 81808209..00000000
--- a/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/usecase/FindCalendarFilterTagUseCase.kt
+++ /dev/null
@@ -1,57 +0,0 @@
-package io.github.taetae98coding.diary.domain.calendar.usecase
-
-import io.github.taetae98coding.diary.domain.account.usecase.GetAccountUseCase
-import io.github.taetae98coding.diary.domain.calendar.entity.CalendarTagFilter
-import io.github.taetae98coding.diary.domain.calendar.repository.CalendarRepository
-import io.github.taetae98coding.diary.domain.tag.repository.TagRepository
-import io.github.taetae98coding.diary.domain.tag.usecase.PageTagUseCase
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.catch
-import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.emitAll
-import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.flow
-import kotlinx.coroutines.flow.mapLatest
-import org.koin.core.annotation.Factory
-
-@OptIn(ExperimentalCoroutinesApi::class)
-@Factory
-public class FindCalendarFilterTagUseCase internal constructor(private val getAccountUseCase: GetAccountUseCase, private val pageTagUseCase: PageTagUseCase, private val calendarRepository: CalendarRepository, private val tagRepository: TagRepository) {
-	public operator fun invoke(): Flow<Result<List<CalendarTagFilter>>> =
-		flow {
-			val accountFlow = getAccountUseCase().mapLatest { it.getOrThrow() }
-			val pageTagFlow = pageTagUseCase().mapLatest { it.getOrThrow() }
-			val filterTagFlow =
-				accountFlow
-					.flatMapLatest { calendarRepository.findFilter(it.uid) }
-					.flatMapLatest { tagRepository.findByIds(it) }
-
-			combine(
-				pageTagFlow,
-				filterTagFlow,
-			) { pageTag, filterTag ->
-				val filterTagIds = filterTag.map { it.id }.toSet()
-
-				buildList {
-					addAll(pageTag)
-					addAll(filterTag)
-				}.distinctBy {
-					it.id
-				}.sortedBy {
-					it.detail.title
-				}.map {
-					CalendarTagFilter(
-						tag = it,
-						isSelected = filterTagIds.contains(it.id),
-					)
-				}
-			}.also {
-				emitAll(it)
-			}
-		}.mapLatest {
-			Result.success(it)
-		}.catch {
-			emit(Result.failure(it))
-		}
-}
diff --git a/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/usecase/FindCalendarMemoUseCase.kt b/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/usecase/FindCalendarMemoUseCase.kt
index 10f2c005..87c3e9ad 100644
--- a/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/usecase/FindCalendarMemoUseCase.kt
+++ b/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/usecase/FindCalendarMemoUseCase.kt
@@ -2,7 +2,6 @@ package io.github.taetae98coding.diary.domain.calendar.usecase
 
 import io.github.taetae98coding.diary.core.model.memo.Memo
 import io.github.taetae98coding.diary.domain.account.usecase.GetAccountUseCase
-import io.github.taetae98coding.diary.domain.calendar.repository.CalendarRepository
 import io.github.taetae98coding.diary.domain.memo.repository.MemoRepository
 import io.github.taetae98coding.diary.domain.tag.repository.TagRepository
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -18,19 +17,22 @@ import org.koin.core.annotation.Factory
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @Factory
-public class FindCalendarMemoUseCase internal constructor(private val getAccountUseCase: GetAccountUseCase, private val calendarRepository: CalendarRepository, private val memoRepository: MemoRepository, private val tagRepository: TagRepository) {
+public class FindCalendarMemoUseCase internal constructor(
+	private val getAccountUseCase: GetAccountUseCase,
+	private val findCalendarSelectedTagFilterUseCase: FindCalendarSelectedTagFilterUseCase,
+	private val memoRepository: MemoRepository,
+	private val tagRepository: TagRepository,
+) {
 	public operator fun invoke(dateRange: ClosedRange<LocalDate>): Flow<Result<List<Memo>>> =
 		flow {
-			val accountFlow = getAccountUseCase().mapLatest { it.getOrThrow() }
-			val calendarTagFilterFlow =
-				accountFlow
-					.flatMapLatest { calendarRepository.findFilter(it.uid) }
-					.flatMapLatest { tagRepository.findByIds(it) }
-					.mapLatest { list -> list.map { it.id }.toSet() }
-
-			combine(accountFlow, calendarTagFilterFlow) { account, tagFilter ->
+			combine(
+				getAccountUseCase().mapLatest { it.getOrThrow() },
+				findCalendarSelectedTagFilterUseCase().mapLatest { it.getOrThrow() },
+			) { account, selectedTagFilter ->
+				account to selectedTagFilter.map { it.id }.toSet()
+			}.flatMapLatest { (account, selectedTagFilterIds) ->
 				memoRepository
-					.findByDateRange(account.uid, dateRange, tagFilter)
+					.findByDateRange(account.uid, dateRange, selectedTagFilterIds)
 					.flatMapLatest { memoList ->
 						val tagIdSet = memoList.mapNotNull { it.primaryTag }.toSet()
 
@@ -48,8 +50,6 @@ public class FindCalendarMemoUseCase internal constructor(private val getAccount
 							}
 						}
 					}
-			}.flatMapLatest {
-				it
 			}.also {
 				emitAll(it)
 			}
diff --git a/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/usecase/FindCalendarSelectedTagFilterUseCase.kt b/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/usecase/FindCalendarSelectedTagFilterUseCase.kt
new file mode 100644
index 00000000..2239e9d9
--- /dev/null
+++ b/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/usecase/FindCalendarSelectedTagFilterUseCase.kt
@@ -0,0 +1,34 @@
+package io.github.taetae98coding.diary.domain.calendar.usecase
+
+import io.github.taetae98coding.diary.core.model.tag.Tag
+import io.github.taetae98coding.diary.domain.account.usecase.GetAccountUseCase
+import io.github.taetae98coding.diary.domain.calendar.repository.CalendarRepository
+import io.github.taetae98coding.diary.domain.tag.repository.TagRepository
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.catch
+import kotlinx.coroutines.flow.emitAll
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.flow.mapLatest
+import org.koin.core.annotation.Factory
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@Factory
+public class FindCalendarSelectedTagFilterUseCase internal constructor(
+	private val getAccountUseCase: GetAccountUseCase,
+	private val calendarRepository: CalendarRepository,
+	private val tagRepository: TagRepository,
+) {
+	public operator fun invoke(): Flow<Result<List<Tag>>> = flow {
+		getAccountUseCase()
+			.mapLatest { it.getOrThrow() }
+			.flatMapLatest { calendarRepository.findFilter(it.uid) }
+			.flatMapLatest { tagRepository.findByIds(it) }
+			.also { emitAll(it) }
+	}.mapLatest {
+		Result.success(it)
+	}.catch {
+		emit(Result.failure(it))
+	}
+}
diff --git a/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/usecase/FindCalendarTagFilterUseCase.kt b/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/usecase/FindCalendarTagFilterUseCase.kt
new file mode 100644
index 00000000..8b8fc18f
--- /dev/null
+++ b/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/usecase/FindCalendarTagFilterUseCase.kt
@@ -0,0 +1,49 @@
+package io.github.taetae98coding.diary.domain.calendar.usecase
+
+import io.github.taetae98coding.diary.domain.calendar.entity.CalendarTagFilter
+import io.github.taetae98coding.diary.domain.tag.usecase.PageTagUseCase
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.catch
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.emitAll
+import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.flow.mapLatest
+import org.koin.core.annotation.Factory
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@Factory
+public class FindCalendarTagFilterUseCase internal constructor(
+	private val pageTagUseCase: PageTagUseCase,
+	private val findCalendarSelectedTagFilterUseCase: FindCalendarSelectedTagFilterUseCase,
+) {
+	public operator fun invoke(): Flow<Result<List<CalendarTagFilter>>> =
+		flow {
+			combine(
+				pageTagUseCase().mapLatest { it.getOrThrow() },
+				findCalendarSelectedTagFilterUseCase().mapLatest { it.getOrThrow() },
+			) { pageTag, selectedTagFilter ->
+				val selectedTagFilterIds = selectedTagFilter.map { it.id }.toSet()
+
+				buildList {
+					addAll(pageTag)
+					addAll(selectedTagFilter)
+				}.distinctBy {
+					it.id
+				}.sortedBy {
+					it.detail.title
+				}.map {
+					CalendarTagFilter(
+						tag = it,
+						isSelected = selectedTagFilterIds.contains(it.id),
+					)
+				}
+			}.also {
+				emitAll(it)
+			}
+		}.mapLatest {
+			Result.success(it)
+		}.catch {
+			emit(Result.failure(it))
+		}
+}
diff --git a/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/usecase/HasCalendarFilterUseCase.kt b/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/usecase/HasCalendarFilterUseCase.kt
index 0ad5edc0..3b5a4f82 100644
--- a/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/usecase/HasCalendarFilterUseCase.kt
+++ b/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/usecase/HasCalendarFilterUseCase.kt
@@ -1,26 +1,22 @@
 package io.github.taetae98coding.diary.domain.calendar.usecase
 
-import io.github.taetae98coding.diary.domain.account.usecase.GetAccountUseCase
-import io.github.taetae98coding.diary.domain.calendar.repository.CalendarRepository
-import io.github.taetae98coding.diary.domain.tag.repository.TagRepository
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.catch
 import kotlinx.coroutines.flow.emitAll
-import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.flow
 import kotlinx.coroutines.flow.mapLatest
 import org.koin.core.annotation.Factory
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @Factory
-public class HasCalendarFilterUseCase internal constructor(private val getAccountUseCase: GetAccountUseCase, private val calendarRepository: CalendarRepository, private val tagRepository: TagRepository) {
+public class HasCalendarFilterUseCase internal constructor(
+	private val findCalendarSelectedTagFilterUseCase: FindCalendarSelectedTagFilterUseCase,
+) {
 	public operator fun invoke(): Flow<Result<Boolean>> =
 		flow {
-			getAccountUseCase()
+			findCalendarSelectedTagFilterUseCase()
 				.mapLatest { it.getOrThrow() }
-				.flatMapLatest { calendarRepository.findFilter(it.uid) }
-				.flatMapLatest { tagRepository.findByIds(it) }
 				.mapLatest { it.isNotEmpty() }
 				.also { emitAll(it) }
 		}.mapLatest {
diff --git a/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/usecase/UpsertCalendarTagUseCase.kt b/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/usecase/UpsertCalendarTagUseCase.kt
index 5f4d2608..f42dc1cc 100644
--- a/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/usecase/UpsertCalendarTagUseCase.kt
+++ b/app/domain/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/calendar/usecase/UpsertCalendarTagUseCase.kt
@@ -6,7 +6,10 @@ import kotlinx.coroutines.flow.first
 import org.koin.core.annotation.Factory
 
 @Factory
-public class UpsertCalendarTagUseCase internal constructor(private val getAccountUseCase: GetAccountUseCase, private val repository: CalendarRepository) {
+public class UpsertCalendarTagUseCase internal constructor(
+	private val getAccountUseCase: GetAccountUseCase,
+	private val repository: CalendarRepository,
+) {
 	public suspend operator fun invoke(tagId: String): Result<Unit> =
 		runCatching {
 			val account = getAccountUseCase().first().getOrThrow()
diff --git a/app/domain/calendar/src/jvmTest/kotlin/io/github/taetae98coding/diary/domain/calendar/DeleteCalendarTagUseCaseTest.kt b/app/domain/calendar/src/jvmTest/kotlin/io/github/taetae98coding/diary/domain/calendar/DeleteCalendarTagUseCaseTest.kt
new file mode 100644
index 00000000..eaee1de0
--- /dev/null
+++ b/app/domain/calendar/src/jvmTest/kotlin/io/github/taetae98coding/diary/domain/calendar/DeleteCalendarTagUseCaseTest.kt
@@ -0,0 +1,78 @@
+package io.github.taetae98coding.diary.domain.calendar
+
+import io.github.taetae98coding.diary.core.model.account.Account
+import io.github.taetae98coding.diary.domain.account.usecase.GetAccountUseCase
+import io.github.taetae98coding.diary.domain.calendar.repository.CalendarRepository
+import io.github.taetae98coding.diary.domain.calendar.usecase.DeleteCalendarTagUseCase
+import io.kotest.core.spec.style.BehaviorSpec
+import io.kotest.matchers.result.shouldBeSuccess
+import io.mockk.Called
+import io.mockk.clearAllMocks
+import io.mockk.coVerify
+import io.mockk.every
+import io.mockk.mockk
+import io.mockk.verify
+import kotlinx.coroutines.flow.flowOf
+
+class DeleteCalendarTagUseCaseTest : BehaviorSpec() {
+	init {
+		val getAccountUseCase = mockk<GetAccountUseCase>()
+		val calendarRepository = mockk<CalendarRepository>(relaxed = true, relaxUnitFun = true)
+
+		val useCase = DeleteCalendarTagUseCase(
+			getAccountUseCase = getAccountUseCase,
+			repository = calendarRepository,
+		)
+
+		Given("has account") {
+			val accountUid = "uid"
+			val account = mockk<Account> {
+				every { uid } returns accountUid
+			}
+
+			every { getAccountUseCase() } returns flowOf(Result.success(account))
+
+			And("tagId is null") {
+				val tagId = null
+
+				When("call usecase") {
+					val result = useCase(tagId)
+
+					Then("result is success") {
+						result.shouldBeSuccess()
+					}
+
+					Then("do nothing") {
+						verify {
+							getAccountUseCase wasNot Called
+							calendarRepository wasNot Called
+						}
+					}
+				}
+
+				clearAllMocks(answers = false)
+			}
+
+			And("tagId is not null") {
+				val tagId = "tagId"
+
+				When("call usecase") {
+					val result = useCase(tagId)
+
+					Then("result is success") {
+						result.shouldBeSuccess()
+					}
+
+					Then("do delete") {
+
+						coVerify {
+							calendarRepository.delete(accountUid, tagId)
+						}
+					}
+				}
+
+				clearAllMocks(answers = false)
+			}
+		}
+	}
+}
diff --git a/app/domain/calendar/src/jvmTest/kotlin/io/github/taetae98coding/diary/domain/calendar/FindCalendarMemoUseCaseTest.kt b/app/domain/calendar/src/jvmTest/kotlin/io/github/taetae98coding/diary/domain/calendar/FindCalendarMemoUseCaseTest.kt
new file mode 100644
index 00000000..4abbc4f6
--- /dev/null
+++ b/app/domain/calendar/src/jvmTest/kotlin/io/github/taetae98coding/diary/domain/calendar/FindCalendarMemoUseCaseTest.kt
@@ -0,0 +1,114 @@
+package io.github.taetae98coding.diary.domain.calendar
+
+import io.github.taetae98coding.diary.core.model.account.Account
+import io.github.taetae98coding.diary.core.model.memo.Memo
+import io.github.taetae98coding.diary.core.model.memo.MemoDetail
+import io.github.taetae98coding.diary.core.model.tag.Tag
+import io.github.taetae98coding.diary.core.model.tag.TagDetail
+import io.github.taetae98coding.diary.domain.account.usecase.GetAccountUseCase
+import io.github.taetae98coding.diary.domain.calendar.usecase.FindCalendarMemoUseCase
+import io.github.taetae98coding.diary.domain.calendar.usecase.FindCalendarSelectedTagFilterUseCase
+import io.github.taetae98coding.diary.domain.memo.repository.MemoRepository
+import io.github.taetae98coding.diary.domain.tag.repository.TagRepository
+import io.kotest.core.spec.style.BehaviorSpec
+import io.kotest.matchers.result.shouldBeSuccess
+import io.kotest.matchers.shouldBe
+import io.kotest.matchers.shouldNotBe
+import io.mockk.every
+import io.mockk.mockk
+import io.mockk.verify
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.datetime.Instant
+import kotlinx.datetime.LocalDate
+
+class FindCalendarMemoUseCaseTest : BehaviorSpec() {
+	init {
+		val getAccountUseCase = mockk<GetAccountUseCase>()
+		val findCalendarSelectedTagFilterUseCase = mockk<FindCalendarSelectedTagFilterUseCase>()
+		val memoRepository = mockk<MemoRepository>(relaxed = true, relaxUnitFun = true)
+		val tagRepository = mockk<TagRepository>(relaxed = true, relaxUnitFun = true)
+
+		val useCase = FindCalendarMemoUseCase(
+			getAccountUseCase = getAccountUseCase,
+			findCalendarSelectedTagFilterUseCase = findCalendarSelectedTagFilterUseCase,
+			memoRepository = memoRepository,
+			tagRepository = tagRepository,
+		)
+
+		Given("has account") {
+			val accountUid = "uid"
+			val account = mockk<Account>(relaxed = true, relaxUnitFun = true) {
+				every { uid } returns accountUid
+			}
+			every { getAccountUseCase() } returns flowOf(Result.success(account))
+
+			And("has selected tag filter") {
+				val selectedTagFilter = listOf(createTag())
+
+				every { findCalendarSelectedTagFilterUseCase() } answers {
+					flowOf(Result.success(selectedTagFilter))
+				}
+
+				When("call usecase") {
+					val dateRange = LocalDate(2000, 1, 1)..LocalDate(2000, 1, 31)
+					val memoList = List(2) { createMemo(it.toString(), if (it == 0) "0" else null) }
+					val tagList = listOf(createTag())
+
+					every { memoRepository.findByDateRange(any(), any(), any()) } returns flowOf(memoList)
+					every { tagRepository.findByIds(any()) } returns flowOf(tagList)
+
+					val result = useCase(dateRange).first()
+
+					Then("result is success") {
+						result.shouldBeSuccess()
+					}
+
+					Then("memo color changed") {
+						val resultList = result.getOrThrow()
+						val tag = tagList.first()
+
+						resultList.first().detail.color shouldBe tag.detail.color
+						resultList.last().detail.color shouldNotBe tag.detail.color
+					}
+
+					Then("do find") {
+						verify {
+							memoRepository.findByDateRange(accountUid, dateRange, selectedTagFilter.map { it.id }.toSet())
+							tagRepository.findByIds(any())
+						}
+					}
+				}
+			}
+		}
+	}
+
+	private fun createTag(): Tag = Tag(
+		id = "0",
+		detail = TagDetail(
+			title = "title",
+			description = "description",
+			color = 100,
+		),
+		owner = null,
+		isFinish = false,
+		isDelete = false,
+		updateAt = Instant.DISTANT_PAST,
+	)
+
+	private fun createMemo(id: String, primaryTag: String?): Memo = Memo(
+		id = id,
+		detail = MemoDetail(
+			title = "title",
+			description = "description",
+			start = null,
+			endInclusive = null,
+			color = 0,
+		),
+		primaryTag = primaryTag,
+		owner = null,
+		isFinish = false,
+		isDelete = false,
+		updateAt = Instant.DISTANT_PAST,
+	)
+}
diff --git a/app/domain/calendar/src/jvmTest/kotlin/io/github/taetae98coding/diary/domain/calendar/FindCalendarSelectedTagFilterUseCaseTest.kt b/app/domain/calendar/src/jvmTest/kotlin/io/github/taetae98coding/diary/domain/calendar/FindCalendarSelectedTagFilterUseCaseTest.kt
new file mode 100644
index 00000000..2d589915
--- /dev/null
+++ b/app/domain/calendar/src/jvmTest/kotlin/io/github/taetae98coding/diary/domain/calendar/FindCalendarSelectedTagFilterUseCaseTest.kt
@@ -0,0 +1,69 @@
+package io.github.taetae98coding.diary.domain.calendar
+
+import io.github.taetae98coding.diary.core.model.account.Account
+import io.github.taetae98coding.diary.core.model.tag.Tag
+import io.github.taetae98coding.diary.domain.account.usecase.GetAccountUseCase
+import io.github.taetae98coding.diary.domain.calendar.repository.CalendarRepository
+import io.github.taetae98coding.diary.domain.calendar.usecase.FindCalendarSelectedTagFilterUseCase
+import io.github.taetae98coding.diary.domain.tag.repository.TagRepository
+import io.kotest.core.spec.style.BehaviorSpec
+import io.kotest.matchers.result.shouldBeSuccess
+import io.mockk.every
+import io.mockk.mockk
+import io.mockk.verify
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.flowOf
+
+class FindCalendarSelectedTagFilterUseCaseTest : BehaviorSpec() {
+	init {
+		val getAccountUseCase = mockk<GetAccountUseCase>()
+		val calendarRepository = mockk<CalendarRepository>()
+		val tagRepository = mockk<TagRepository>()
+
+		val useCase = FindCalendarSelectedTagFilterUseCase(
+			getAccountUseCase = getAccountUseCase,
+			calendarRepository = calendarRepository,
+			tagRepository = tagRepository,
+		)
+
+		Given("has account") {
+			val accountUid = "uid"
+			val account = mockk<Account>(relaxed = true) {
+				every { uid } returns accountUid
+			}
+
+			every { getAccountUseCase() } returns flowOf(Result.success(account))
+
+			And("has tag filter") {
+				val tagIds = setOf("1", "2", "3")
+				every { calendarRepository.findFilter(any()) } returns flowOf(tagIds)
+
+				When("call usecase") {
+					every { tagRepository.findByIds(any()) } answers {
+						val ids = arg<Set<String>>(0)
+						val list = ids.map {
+							mockk<Tag> {
+								every { id } returns it
+							}
+						}
+
+						flowOf(list)
+					}
+
+					val result = useCase().first()
+
+					Then("result is success") {
+						result.shouldBeSuccess()
+					}
+
+					Then("do find") {
+						verify {
+							calendarRepository.findFilter(accountUid)
+							tagRepository.findByIds(tagIds)
+						}
+					}
+				}
+			}
+		}
+	}
+}
diff --git a/app/domain/credential/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/credential/usecase/JoinUseCase.kt b/app/domain/credential/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/credential/usecase/JoinUseCase.kt
index 707122b7..1778cf8b 100644
--- a/app/domain/credential/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/credential/usecase/JoinUseCase.kt
+++ b/app/domain/credential/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/credential/usecase/JoinUseCase.kt
@@ -6,7 +6,9 @@ import io.github.taetae98coding.diary.library.kotlin.regex.email
 import org.koin.core.annotation.Factory
 
 @Factory
-public class JoinUseCase internal constructor(private val repository: CredentialRepository) {
+public class JoinUseCase internal constructor(
+	private val repository: CredentialRepository,
+) {
 	public suspend operator fun invoke(email: String, password: String): Result<Unit> =
 		runCatching {
 			if (!email.contains(Regex.email())) throw InvalidEmailException()
diff --git a/app/domain/credential/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/credential/usecase/LoginUseCase.kt b/app/domain/credential/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/credential/usecase/LoginUseCase.kt
index ed2f292d..f79f3027 100644
--- a/app/domain/credential/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/credential/usecase/LoginUseCase.kt
+++ b/app/domain/credential/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/credential/usecase/LoginUseCase.kt
@@ -11,7 +11,12 @@ import kotlinx.coroutines.launch
 import org.koin.core.annotation.Factory
 
 @Factory
-public class LoginUseCase internal constructor(private val coroutineScope: CoroutineScope, private val repository: CredentialRepository, private val fetchUseCase: FetchUseCase, private val updateFCMTokenUseCase: UpdateFCMTokenUseCase) {
+public class LoginUseCase internal constructor(
+	private val coroutineScope: CoroutineScope,
+	private val repository: CredentialRepository,
+	private val fetchUseCase: FetchUseCase,
+	private val updateFCMTokenUseCase: UpdateFCMTokenUseCase,
+) {
 	public suspend operator fun invoke(email: String, password: String): Result<Unit> =
 		runCatching {
 			val token = repository.fetchToken(email, password).first()
diff --git a/app/domain/credential/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/credential/usecase/LogoutUseCase.kt b/app/domain/credential/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/credential/usecase/LogoutUseCase.kt
index f93e55e1..a020bc8c 100644
--- a/app/domain/credential/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/credential/usecase/LogoutUseCase.kt
+++ b/app/domain/credential/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/credential/usecase/LogoutUseCase.kt
@@ -6,7 +6,11 @@ import io.github.taetae98coding.diary.domain.fcm.usecase.UpdateFCMTokenUseCase
 import org.koin.core.annotation.Factory
 
 @Factory
-public class LogoutUseCase internal constructor(private val repository: CredentialRepository, private val backupUseCase: BackupUseCase, private val updateFCMTokenUseCase: UpdateFCMTokenUseCase) {
+public class LogoutUseCase internal constructor(
+	private val repository: CredentialRepository,
+	private val backupUseCase: BackupUseCase,
+	private val updateFCMTokenUseCase: UpdateFCMTokenUseCase,
+) {
 	public suspend operator fun invoke(): Result<Unit> =
 		runCatching {
 			backupUseCase()
diff --git a/app/domain/fcm/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/fcm/usecase/UpdateFCMTokenUseCase.kt b/app/domain/fcm/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/fcm/usecase/UpdateFCMTokenUseCase.kt
index fbe419bb..15a5b272 100644
--- a/app/domain/fcm/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/fcm/usecase/UpdateFCMTokenUseCase.kt
+++ b/app/domain/fcm/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/fcm/usecase/UpdateFCMTokenUseCase.kt
@@ -7,7 +7,10 @@ import kotlinx.coroutines.flow.first
 import org.koin.core.annotation.Factory
 
 @Factory
-public class UpdateFCMTokenUseCase internal constructor(private val getAccountUseCase: GetAccountUseCase, private val repository: FCMRepository) {
+public class UpdateFCMTokenUseCase internal constructor(
+	private val getAccountUseCase: GetAccountUseCase,
+	private val repository: FCMRepository,
+) {
 	public suspend operator fun invoke(): Result<Unit> =
 		runCatching {
 			val account = getAccountUseCase().first().getOrThrow()
diff --git a/app/domain/fetch/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/fetch/usecase/FetchUseCase.kt b/app/domain/fetch/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/fetch/usecase/FetchUseCase.kt
index 31c3f07a..d5866819 100644
--- a/app/domain/fetch/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/fetch/usecase/FetchUseCase.kt
+++ b/app/domain/fetch/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/fetch/usecase/FetchUseCase.kt
@@ -9,7 +9,12 @@ import kotlinx.coroutines.flow.first
 import org.koin.core.annotation.Factory
 
 @Factory
-public class FetchUseCase internal constructor(private val getAccountUseCase: GetAccountUseCase, private val backupUseCase: BackupUseCase, private val memoFetchRepository: MemoFetchRepository, private val tagFetchRepository: TagFetchRepository) {
+public class FetchUseCase internal constructor(
+	private val getAccountUseCase: GetAccountUseCase,
+	private val backupUseCase: BackupUseCase,
+	private val memoFetchRepository: MemoFetchRepository,
+	private val tagFetchRepository: TagFetchRepository,
+) {
 	public suspend operator fun invoke(): Result<Unit> =
 		runCatching {
 			val account = getAccountUseCase().first().getOrThrow()
diff --git a/app/domain/holiday/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/holiday/usecase/FindHolidayUseCase.kt b/app/domain/holiday/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/holiday/usecase/FindHolidayUseCase.kt
index 1b40670d..9bb38b7b 100644
--- a/app/domain/holiday/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/holiday/usecase/FindHolidayUseCase.kt
+++ b/app/domain/holiday/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/holiday/usecase/FindHolidayUseCase.kt
@@ -13,7 +13,9 @@ import org.koin.core.annotation.Factory
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @Factory
-public class FindHolidayUseCase internal constructor(private val repository: HolidayRepository) {
+public class FindHolidayUseCase internal constructor(
+	private val repository: HolidayRepository,
+) {
 	public operator fun invoke(year: Int, month: Month): Flow<Result<List<Holiday>>> =
 		flow { emitAll(repository.findHoliday(year, month)) }
 			.mapLatest { Result.success(it) }
diff --git a/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/entity/MemoTag.kt b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/entity/MemoTag.kt
index 85c48a6a..7b48fe66 100644
--- a/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/entity/MemoTag.kt
+++ b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/entity/MemoTag.kt
@@ -2,4 +2,8 @@ package io.github.taetae98coding.diary.domain.memo.entity
 
 import io.github.taetae98coding.diary.core.model.tag.Tag
 
-public data class MemoTag(val tag: Tag, val isSelected: Boolean, val isPrimary: Boolean)
+public data class MemoTag(
+	val tag: Tag,
+	val isSelected: Boolean,
+	val isPrimary: Boolean,
+)
diff --git a/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/AddMemoUseCase.kt b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/AddMemoUseCase.kt
index 7dfac6f3..c9c120d0 100644
--- a/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/AddMemoUseCase.kt
+++ b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/AddMemoUseCase.kt
@@ -6,15 +6,20 @@ import io.github.taetae98coding.diary.core.model.memo.MemoDetail
 import io.github.taetae98coding.diary.domain.account.usecase.GetAccountUseCase
 import io.github.taetae98coding.diary.domain.backup.usecase.PushMemoBackupQueueUseCase
 import io.github.taetae98coding.diary.domain.memo.repository.MemoRepository
-import kotlin.uuid.ExperimentalUuidApi
-import kotlin.uuid.Uuid
 import kotlinx.coroutines.flow.first
 import kotlinx.datetime.Clock
 import org.koin.core.annotation.Factory
+import kotlin.uuid.ExperimentalUuidApi
+import kotlin.uuid.Uuid
 
 @OptIn(ExperimentalUuidApi::class)
 @Factory
-public class AddMemoUseCase internal constructor(private val getAccountUseCase: GetAccountUseCase, private val pushMemoBackupQueueUseCase: PushMemoBackupQueueUseCase, private val clock: Clock, private val repository: MemoRepository) {
+public class AddMemoUseCase internal constructor(
+	private val getAccountUseCase: GetAccountUseCase,
+	private val pushMemoBackupQueueUseCase: PushMemoBackupQueueUseCase,
+	private val clock: Clock,
+	private val repository: MemoRepository,
+) {
 	public suspend operator fun invoke(
 		detail: MemoDetail,
 		primaryTag: String?,
diff --git a/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/DeleteMemoPrimaryTagUseCase.kt b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/DeleteMemoPrimaryTagUseCase.kt
index 53e52cbb..9c087df4 100644
--- a/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/DeleteMemoPrimaryTagUseCase.kt
+++ b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/DeleteMemoPrimaryTagUseCase.kt
@@ -5,7 +5,10 @@ import io.github.taetae98coding.diary.domain.memo.repository.MemoRepository
 import org.koin.core.annotation.Factory
 
 @Factory
-public class DeleteMemoPrimaryTagUseCase internal constructor(private val pushMemoBackupQueueUseCase: PushMemoBackupQueueUseCase, private val repository: MemoRepository) {
+public class DeleteMemoPrimaryTagUseCase internal constructor(
+	private val pushMemoBackupQueueUseCase: PushMemoBackupQueueUseCase,
+	private val repository: MemoRepository,
+) {
 	public suspend operator fun invoke(memoId: String?): Result<Unit> {
 		return runCatching {
 			if (memoId.isNullOrBlank()) return@runCatching
diff --git a/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/DeleteMemoUseCase.kt b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/DeleteMemoUseCase.kt
index 1cc74670..ff576ec6 100644
--- a/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/DeleteMemoUseCase.kt
+++ b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/DeleteMemoUseCase.kt
@@ -5,7 +5,10 @@ import io.github.taetae98coding.diary.domain.memo.repository.MemoRepository
 import org.koin.core.annotation.Factory
 
 @Factory
-public class DeleteMemoUseCase internal constructor(private val pushMemoBackupQueueUseCase: PushMemoBackupQueueUseCase, private val repository: MemoRepository) {
+public class DeleteMemoUseCase internal constructor(
+	private val pushMemoBackupQueueUseCase: PushMemoBackupQueueUseCase,
+	private val repository: MemoRepository,
+) {
 	public suspend operator fun invoke(memoId: String?): Result<Unit> {
 		return runCatching {
 			if (memoId.isNullOrBlank()) return@runCatching
diff --git a/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/FindMemoTagUseCase.kt b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/FindMemoTagUseCase.kt
index adf84253..5512297c 100644
--- a/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/FindMemoTagUseCase.kt
+++ b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/FindMemoTagUseCase.kt
@@ -17,7 +17,12 @@ import org.koin.core.annotation.Factory
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @Factory
-public class FindMemoTagUseCase internal constructor(private val findMemoUseCase: FindMemoUseCase, private val pageTagUseCase: PageTagUseCase, private val memoTagRepository: MemoTagRepository, private val tagRepository: TagRepository) {
+public class FindMemoTagUseCase internal constructor(
+	private val findMemoUseCase: FindMemoUseCase,
+	private val pageTagUseCase: PageTagUseCase,
+	private val memoTagRepository: MemoTagRepository,
+	private val tagRepository: TagRepository,
+) {
 	public operator fun invoke(memoId: String?): Flow<Result<List<MemoTag>>> {
 		if (memoId.isNullOrBlank()) return flowOf(Result.success(emptyList()))
 
diff --git a/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/FindMemoUseCase.kt b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/FindMemoUseCase.kt
index b3f59f0d..9b9a8bc3 100644
--- a/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/FindMemoUseCase.kt
+++ b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/FindMemoUseCase.kt
@@ -13,7 +13,9 @@ import org.koin.core.annotation.Factory
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @Factory
-public class FindMemoUseCase internal constructor(private val repository: MemoRepository) {
+public class FindMemoUseCase internal constructor(
+	private val repository: MemoRepository,
+) {
 	public operator fun invoke(memoId: String?): Flow<Result<Memo?>> {
 		if (memoId.isNullOrBlank()) return flowOf(Result.success(null))
 
diff --git a/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/FinishMemoUseCase.kt b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/FinishMemoUseCase.kt
index f2a4d5e4..fa429df2 100644
--- a/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/FinishMemoUseCase.kt
+++ b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/FinishMemoUseCase.kt
@@ -5,7 +5,10 @@ import io.github.taetae98coding.diary.domain.memo.repository.MemoRepository
 import org.koin.core.annotation.Factory
 
 @Factory
-public class FinishMemoUseCase internal constructor(private val repository: MemoRepository, private val pushMemoBackupQueueUseCase: PushMemoBackupQueueUseCase) {
+public class FinishMemoUseCase internal constructor(
+	private val repository: MemoRepository,
+	private val pushMemoBackupQueueUseCase: PushMemoBackupQueueUseCase,
+) {
 	public suspend operator fun invoke(memoId: String?): Result<Unit> {
 		return runCatching {
 			if (memoId.isNullOrBlank()) return@runCatching
diff --git a/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/RestartMemoUseCase.kt b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/RestartMemoUseCase.kt
index 8cca1360..c413acf8 100644
--- a/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/RestartMemoUseCase.kt
+++ b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/RestartMemoUseCase.kt
@@ -5,7 +5,10 @@ import io.github.taetae98coding.diary.domain.memo.repository.MemoRepository
 import org.koin.core.annotation.Factory
 
 @Factory
-public class RestartMemoUseCase internal constructor(private val pushMemoBackupQueueUseCase: PushMemoBackupQueueUseCase, private val repository: MemoRepository) {
+public class RestartMemoUseCase internal constructor(
+	private val pushMemoBackupQueueUseCase: PushMemoBackupQueueUseCase,
+	private val repository: MemoRepository,
+) {
 	public suspend operator fun invoke(memoId: String?): Result<Unit> {
 		return runCatching {
 			if (memoId.isNullOrBlank()) return@runCatching
diff --git a/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/RestoreMemoUseCase.kt b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/RestoreMemoUseCase.kt
new file mode 100644
index 00000000..8f555bc3
--- /dev/null
+++ b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/RestoreMemoUseCase.kt
@@ -0,0 +1,20 @@
+package io.github.taetae98coding.diary.domain.memo.usecase
+
+import io.github.taetae98coding.diary.domain.backup.usecase.PushMemoBackupQueueUseCase
+import io.github.taetae98coding.diary.domain.memo.repository.MemoRepository
+import org.koin.core.annotation.Factory
+
+@Factory
+public class RestoreMemoUseCase internal constructor(
+    private val pushMemoBackupQueueUseCase: PushMemoBackupQueueUseCase,
+    private val repository: MemoRepository,
+) {
+    public suspend operator fun invoke(memoId: String?): Result<Unit> {
+        return runCatching {
+            if (memoId.isNullOrBlank()) return@runCatching
+
+            repository.updateDelete(memoId, false)
+            pushMemoBackupQueueUseCase(memoId)
+        }
+    }
+}
diff --git a/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/SelectMemoTagUseCase.kt b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/SelectMemoTagUseCase.kt
index c4d058d4..6202f82c 100644
--- a/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/SelectMemoTagUseCase.kt
+++ b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/SelectMemoTagUseCase.kt
@@ -5,7 +5,10 @@ import io.github.taetae98coding.diary.domain.memo.repository.MemoTagRepository
 import org.koin.core.annotation.Factory
 
 @Factory
-public class SelectMemoTagUseCase internal constructor(private val pushMemoBackupQueueUseCase: PushMemoBackupQueueUseCase, private val repository: MemoTagRepository) {
+public class SelectMemoTagUseCase internal constructor(
+	private val pushMemoBackupQueueUseCase: PushMemoBackupQueueUseCase,
+	private val repository: MemoTagRepository,
+) {
 	public suspend operator fun invoke(memoId: String?, tagId: String?): Result<Unit> {
 		return runCatching {
 			if (memoId.isNullOrBlank() || tagId.isNullOrBlank()) return@runCatching
diff --git a/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/UnselectMemoTagUseCase.kt b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/UnselectMemoTagUseCase.kt
index 88b01888..e00977fb 100644
--- a/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/UnselectMemoTagUseCase.kt
+++ b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/UnselectMemoTagUseCase.kt
@@ -7,7 +7,12 @@ import kotlinx.coroutines.flow.first
 import org.koin.core.annotation.Factory
 
 @Factory
-public class UnselectMemoTagUseCase internal constructor(private val findMemoUseCase: FindMemoUseCase, private val pushMemoBackupQueueUseCase: PushMemoBackupQueueUseCase, private val memoRepository: MemoRepository, private val memoTagRepository: MemoTagRepository) {
+public class UnselectMemoTagUseCase internal constructor(
+	private val findMemoUseCase: FindMemoUseCase,
+	private val pushMemoBackupQueueUseCase: PushMemoBackupQueueUseCase,
+	private val memoRepository: MemoRepository,
+	private val memoTagRepository: MemoTagRepository,
+) {
 	public suspend operator fun invoke(memoId: String?, tagId: String?): Result<Unit> {
 		return runCatching {
 			if (memoId.isNullOrBlank() || tagId.isNullOrBlank()) return@runCatching
diff --git a/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/UpdateMemoPrimaryTagUseCase.kt b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/UpdateMemoPrimaryTagUseCase.kt
index 06a50680..cac0643e 100644
--- a/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/UpdateMemoPrimaryTagUseCase.kt
+++ b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/UpdateMemoPrimaryTagUseCase.kt
@@ -5,7 +5,10 @@ import io.github.taetae98coding.diary.domain.memo.repository.MemoRepository
 import org.koin.core.annotation.Factory
 
 @Factory
-public class UpdateMemoPrimaryTagUseCase internal constructor(private val pushMemoBackupQueueUseCase: PushMemoBackupQueueUseCase, private val repository: MemoRepository) {
+public class UpdateMemoPrimaryTagUseCase internal constructor(
+	private val pushMemoBackupQueueUseCase: PushMemoBackupQueueUseCase,
+	private val repository: MemoRepository,
+) {
 	public suspend operator fun invoke(memoId: String?, tagId: String?): Result<Unit> {
 		return runCatching {
 			if (memoId.isNullOrBlank() || tagId.isNullOrBlank()) return@runCatching
diff --git a/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/UpdateMemoUseCase.kt b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/UpdateMemoUseCase.kt
index 1737ec24..f1018baf 100644
--- a/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/UpdateMemoUseCase.kt
+++ b/app/domain/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/UpdateMemoUseCase.kt
@@ -7,7 +7,10 @@ import kotlinx.coroutines.flow.first
 import org.koin.core.annotation.Factory
 
 @Factory
-public class UpdateMemoUseCase internal constructor(private val pushMemoBackupQueueUseCase: PushMemoBackupQueueUseCase, private val repository: MemoRepository) {
+public class UpdateMemoUseCase internal constructor(
+	private val pushMemoBackupQueueUseCase: PushMemoBackupQueueUseCase,
+	private val repository: MemoRepository,
+) {
 	public suspend operator fun invoke(memoId: String?, detail: MemoDetail): Result<Unit> {
 		return runCatching {
 			if (memoId.isNullOrBlank()) return@runCatching
diff --git a/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/repository/TagRepository.kt b/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/repository/TagRepository.kt
index b0222f2a..0b5cda8f 100644
--- a/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/repository/TagRepository.kt
+++ b/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/repository/TagRepository.kt
@@ -1,5 +1,6 @@
 package io.github.taetae98coding.diary.domain.tag.repository
 
+import io.github.taetae98coding.diary.core.model.memo.Memo
 import io.github.taetae98coding.diary.core.model.tag.Tag
 import io.github.taetae98coding.diary.core.model.tag.TagDetail
 import kotlinx.coroutines.flow.Flow
@@ -13,9 +14,11 @@ public interface TagRepository {
 
 	public suspend fun updateFinish(tagId: String, isFinish: Boolean)
 
+	public fun page(owner: String?): Flow<List<Tag>>
+
 	public fun find(tagId: String): Flow<Tag?>
 
 	public fun findByIds(tagIds: Set<String>): Flow<List<Tag>>
 
-	public fun page(owner: String?): Flow<List<Tag>>
+	public fun findMemoByTagId(tagId: String): Flow<List<Memo>>
 }
diff --git a/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/AddTagUseCase.kt b/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/AddTagUseCase.kt
index 402c1bb5..343f9774 100644
--- a/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/AddTagUseCase.kt
+++ b/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/AddTagUseCase.kt
@@ -6,15 +6,20 @@ import io.github.taetae98coding.diary.core.model.tag.TagDetail
 import io.github.taetae98coding.diary.domain.account.usecase.GetAccountUseCase
 import io.github.taetae98coding.diary.domain.backup.usecase.PushTagBackupQueueUseCase
 import io.github.taetae98coding.diary.domain.tag.repository.TagRepository
-import kotlin.uuid.ExperimentalUuidApi
-import kotlin.uuid.Uuid
 import kotlinx.coroutines.flow.first
 import kotlinx.datetime.Clock
 import org.koin.core.annotation.Factory
+import kotlin.uuid.ExperimentalUuidApi
+import kotlin.uuid.Uuid
 
 @OptIn(ExperimentalUuidApi::class)
 @Factory
-public class AddTagUseCase internal constructor(private val getAccountUseCase: GetAccountUseCase, private val pushTagBackupQueueUseCase: PushTagBackupQueueUseCase, private val clock: Clock, private val repository: TagRepository) {
+public class AddTagUseCase internal constructor(
+	private val getAccountUseCase: GetAccountUseCase,
+	private val pushTagBackupQueueUseCase: PushTagBackupQueueUseCase,
+	private val clock: Clock,
+	private val repository: TagRepository,
+) {
 	public suspend operator fun invoke(detail: TagDetail): Result<Unit> =
 		runCatching {
 			if (detail.title.isBlank()) throw TagTitleBlankException()
diff --git a/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/DeleteTagUseCase.kt b/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/DeleteTagUseCase.kt
index e80031d0..fc1273b5 100644
--- a/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/DeleteTagUseCase.kt
+++ b/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/DeleteTagUseCase.kt
@@ -5,7 +5,10 @@ import io.github.taetae98coding.diary.domain.tag.repository.TagRepository
 import org.koin.core.annotation.Factory
 
 @Factory
-public class DeleteTagUseCase internal constructor(private val repository: TagRepository, private val pushTagBackupQueueUseCase: PushTagBackupQueueUseCase) {
+public class DeleteTagUseCase internal constructor(
+	private val repository: TagRepository,
+	private val pushTagBackupQueueUseCase: PushTagBackupQueueUseCase,
+) {
 	public suspend operator fun invoke(tagId: String?): Result<Unit> {
 		return runCatching {
 			if (tagId.isNullOrBlank()) return@runCatching
diff --git a/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/FindTagUseCase.kt b/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/FindTagUseCase.kt
index 79dbdbc9..62e3e8c2 100644
--- a/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/FindTagUseCase.kt
+++ b/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/FindTagUseCase.kt
@@ -13,7 +13,9 @@ import org.koin.core.annotation.Factory
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @Factory
-public class FindTagUseCase internal constructor(private val repository: TagRepository) {
+public class FindTagUseCase internal constructor(
+	private val repository: TagRepository,
+) {
 	public operator fun invoke(tagId: String?): Flow<Result<Tag?>> {
 		if (tagId.isNullOrBlank()) return flowOf(Result.success(null))
 
diff --git a/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/FinishTagUseCase.kt b/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/FinishTagUseCase.kt
index f10fb168..a10d8995 100644
--- a/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/FinishTagUseCase.kt
+++ b/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/FinishTagUseCase.kt
@@ -5,7 +5,10 @@ import io.github.taetae98coding.diary.domain.tag.repository.TagRepository
 import org.koin.core.annotation.Factory
 
 @Factory
-public class FinishTagUseCase internal constructor(private val pushTagBackupQueueUseCase: PushTagBackupQueueUseCase, private val repository: TagRepository) {
+public class FinishTagUseCase internal constructor(
+	private val pushTagBackupQueueUseCase: PushTagBackupQueueUseCase,
+	private val repository: TagRepository,
+) {
 	public suspend operator fun invoke(tagId: String?): Result<Unit> {
 		return runCatching {
 			if (tagId.isNullOrBlank()) return@runCatching
diff --git a/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/PageTagMemoUseCase.kt b/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/PageTagMemoUseCase.kt
new file mode 100644
index 00000000..b1a2f2f1
--- /dev/null
+++ b/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/PageTagMemoUseCase.kt
@@ -0,0 +1,26 @@
+package io.github.taetae98coding.diary.domain.tag.usecase
+
+import io.github.taetae98coding.diary.core.model.memo.Memo
+import io.github.taetae98coding.diary.domain.tag.repository.TagRepository
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.catch
+import kotlinx.coroutines.flow.emitAll
+import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.mapLatest
+import org.koin.core.annotation.Factory
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@Factory
+public class PageTagMemoUseCase internal constructor(
+	private val repository: TagRepository,
+) {
+	public operator fun invoke(tagId: String?): Flow<Result<List<Memo>>> {
+		if (tagId.isNullOrBlank()) return flowOf(Result.success(emptyList()))
+
+		return flow { emitAll(repository.findMemoByTagId(tagId)) }
+			.mapLatest { Result.success(it) }
+			.catch { emit(Result.failure(it)) }
+	}
+}
diff --git a/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/PageTagUseCase.kt b/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/PageTagUseCase.kt
index ea940cc8..efeb79ca 100644
--- a/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/PageTagUseCase.kt
+++ b/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/PageTagUseCase.kt
@@ -14,7 +14,10 @@ import org.koin.core.annotation.Factory
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @Factory
-public class PageTagUseCase internal constructor(private val getAccountUseCase: GetAccountUseCase, private val repository: TagRepository) {
+public class PageTagUseCase internal constructor(
+	private val getAccountUseCase: GetAccountUseCase,
+	private val repository: TagRepository,
+) {
 	public operator fun invoke(): Flow<Result<List<Tag>>> =
 		flow {
 			getAccountUseCase()
diff --git a/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/RestartTagUseCase.kt b/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/RestartTagUseCase.kt
index 952fd13c..64d9f77c 100644
--- a/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/RestartTagUseCase.kt
+++ b/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/RestartTagUseCase.kt
@@ -5,7 +5,10 @@ import io.github.taetae98coding.diary.domain.tag.repository.TagRepository
 import org.koin.core.annotation.Factory
 
 @Factory
-public class RestartTagUseCase internal constructor(private val pushTagBackupQueueUseCase: PushTagBackupQueueUseCase, private val repository: TagRepository) {
+public class RestartTagUseCase internal constructor(
+	private val pushTagBackupQueueUseCase: PushTagBackupQueueUseCase,
+	private val repository: TagRepository,
+) {
 	public suspend operator fun invoke(tagId: String?): Result<Unit> {
 		return runCatching {
 			if (tagId.isNullOrBlank()) return@runCatching
diff --git a/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/RestoreTagUseCase.kt b/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/RestoreTagUseCase.kt
index aa3961be..d416a3df 100644
--- a/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/RestoreTagUseCase.kt
+++ b/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/RestoreTagUseCase.kt
@@ -5,7 +5,10 @@ import io.github.taetae98coding.diary.domain.tag.repository.TagRepository
 import org.koin.core.annotation.Factory
 
 @Factory
-public class RestoreTagUseCase internal constructor(private val pushTagBackupQueueUseCase: PushTagBackupQueueUseCase, private val repository: TagRepository) {
+public class RestoreTagUseCase internal constructor(
+	private val pushTagBackupQueueUseCase: PushTagBackupQueueUseCase,
+	private val repository: TagRepository,
+) {
 	public suspend operator fun invoke(tagId: String?): Result<Unit> {
 		return runCatching {
 			if (tagId.isNullOrBlank()) return@runCatching
diff --git a/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/UpdateTagUseCase.kt b/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/UpdateTagUseCase.kt
index a6b2a1ab..ca120c49 100644
--- a/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/UpdateTagUseCase.kt
+++ b/app/domain/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/UpdateTagUseCase.kt
@@ -7,7 +7,10 @@ import kotlinx.coroutines.flow.first
 import org.koin.core.annotation.Factory
 
 @Factory
-public class UpdateTagUseCase internal constructor(private val pushTagBackupQueueUseCase: PushTagBackupQueueUseCase, private val repository: TagRepository) {
+public class UpdateTagUseCase internal constructor(
+	private val pushTagBackupQueueUseCase: PushTagBackupQueueUseCase,
+	private val repository: TagRepository,
+) {
 	public suspend operator fun invoke(tagId: String?, detail: TagDetail): Result<Unit> {
 		return runCatching {
 			if (tagId.isNullOrBlank()) return@runCatching
diff --git a/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/common/BottomBarButton.kt b/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/common/BottomBarButton.kt
index eb03f40c..0e86af95 100644
--- a/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/common/BottomBarButton.kt
+++ b/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/common/BottomBarButton.kt
@@ -52,7 +52,8 @@ internal fun BottomBarButtonContent(
 	content: @Composable BoxScope.() -> Unit,
 ) {
 	Box(
-		modifier = modifier.fillMaxWidth()
+		modifier = modifier
+			.fillMaxWidth()
 			.height(50.dp)
 			.windowInsetsPadding(NavigationBarDefaults.windowInsets),
 		contentAlignment = Alignment.Center,
diff --git a/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/join/JoinScreen.kt b/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/join/JoinScreen.kt
index 02ecec02..9ddc1fb1 100644
--- a/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/join/JoinScreen.kt
+++ b/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/join/JoinScreen.kt
@@ -82,7 +82,8 @@ internal fun JoinScreen(
 		Content(
 			state = state,
 			onJoin = onJoin,
-			modifier = Modifier.padding(it)
+			modifier = Modifier
+				.padding(it)
 				.padding(DiaryTheme.dimen.screenPaddingValues),
 		)
 	}
diff --git a/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/join/JoinViewModel.kt b/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/join/JoinViewModel.kt
index b9f53634..100e06a3 100644
--- a/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/join/JoinViewModel.kt
+++ b/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/join/JoinViewModel.kt
@@ -14,7 +14,10 @@ import kotlinx.coroutines.launch
 import org.koin.android.annotation.KoinViewModel
 
 @KoinViewModel
-internal class JoinViewModel(private val joinUseCase: JoinUseCase, private val loginUseCase: LoginUseCase) : ViewModel() {
+internal class JoinViewModel(
+	private val joinUseCase: JoinUseCase,
+	private val loginUseCase: LoginUseCase,
+) : ViewModel() {
 	private val _uiState = MutableStateFlow(JoinUiState(onMessageShow = ::clearMessage))
 	val uiState = _uiState.asStateFlow()
 
diff --git a/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/join/state/JoinScreenState.kt b/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/join/state/JoinScreenState.kt
index 57f206bf..5b4ac3ec 100644
--- a/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/join/state/JoinScreenState.kt
+++ b/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/join/state/JoinScreenState.kt
@@ -12,7 +12,9 @@ import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.launch
 
-internal class JoinScreenState(val coroutineScope: CoroutineScope) {
+internal class JoinScreenState(
+	val coroutineScope: CoroutineScope,
+) {
 	private var messageJob: Job? = null
 	val hostState: SnackbarHostState = SnackbarHostState()
 
diff --git a/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/join/state/JoinUiState.kt b/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/join/state/JoinUiState.kt
index 889f301b..72e412e5 100644
--- a/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/join/state/JoinUiState.kt
+++ b/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/join/state/JoinUiState.kt
@@ -1,5 +1,12 @@
 package io.github.taetae98coding.diary.feature.account.join.state
 
-internal data class JoinUiState(val isProgress: Boolean = false, val isLoginFinish: Boolean = false, val isExistEmail: Boolean = false, val isNetworkError: Boolean = false, val isUnknownError: Boolean = false, val onMessageShow: () -> Unit = {}) {
+internal data class JoinUiState(
+	val isProgress: Boolean = false,
+	val isLoginFinish: Boolean = false,
+	val isExistEmail: Boolean = false,
+	val isNetworkError: Boolean = false,
+	val isUnknownError: Boolean = false,
+	val onMessageShow: () -> Unit = {},
+) {
 	val hasMessage = isLoginFinish || isExistEmail || isNetworkError || isUnknownError
 }
diff --git a/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/login/LoginScreen.kt b/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/login/LoginScreen.kt
index 0efb680f..733f0ada 100644
--- a/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/login/LoginScreen.kt
+++ b/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/login/LoginScreen.kt
@@ -82,7 +82,8 @@ internal fun LoginScreen(
 		Content(
 			state = state,
 			onLogin = onLogin,
-			modifier = Modifier.padding(it)
+			modifier = Modifier
+				.padding(it)
 				.padding(DiaryTheme.dimen.screenPaddingValues),
 		)
 	}
diff --git a/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/login/LoginViewModel.kt b/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/login/LoginViewModel.kt
index 99343c3d..47fcaf59 100644
--- a/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/login/LoginViewModel.kt
+++ b/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/login/LoginViewModel.kt
@@ -13,7 +13,9 @@ import kotlinx.coroutines.launch
 import org.koin.android.annotation.KoinViewModel
 
 @KoinViewModel
-internal class LoginViewModel(private val loginUseCase: LoginUseCase) : ViewModel() {
+internal class LoginViewModel(
+	private val loginUseCase: LoginUseCase,
+) : ViewModel() {
 	private val _uiState = MutableStateFlow(LoginUiState(onMessageShow = ::clearMessage))
 	val uiState = _uiState.asStateFlow()
 
diff --git a/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/login/state/LoginScreenState.kt b/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/login/state/LoginScreenState.kt
index 0a52386a..51e3c545 100644
--- a/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/login/state/LoginScreenState.kt
+++ b/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/login/state/LoginScreenState.kt
@@ -11,7 +11,9 @@ import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.launch
 
-internal class LoginScreenState(private val coroutineScope: CoroutineScope) {
+internal class LoginScreenState(
+	private val coroutineScope: CoroutineScope,
+) {
 	private var messageJob: Job? = null
 	val hostState: SnackbarHostState = SnackbarHostState()
 
diff --git a/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/login/state/LoginUiState.kt b/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/login/state/LoginUiState.kt
index d39e959b..ceb2dbf1 100644
--- a/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/login/state/LoginUiState.kt
+++ b/app/feature/account/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/account/login/state/LoginUiState.kt
@@ -1,5 +1,12 @@
 package io.github.taetae98coding.diary.feature.account.login.state
 
-internal data class LoginUiState(val isProgress: Boolean = false, val isLoginFinish: Boolean = false, val isAccountNotFound: Boolean = false, val isNetworkError: Boolean = false, val isUnknownError: Boolean = false, val onMessageShow: () -> Unit = {}) {
+internal data class LoginUiState(
+	val isProgress: Boolean = false,
+	val isLoginFinish: Boolean = false,
+	val isAccountNotFound: Boolean = false,
+	val isNetworkError: Boolean = false,
+	val isUnknownError: Boolean = false,
+	val onMessageShow: () -> Unit = {},
+) {
 	val hasMessage = isLoginFinish || isAccountNotFound || isNetworkError || isUnknownError
 }
diff --git a/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/CalendarNavigation.kt b/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/CalendarNavigation.kt
index 69bcbf4b..ca394d75 100644
--- a/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/CalendarNavigation.kt
+++ b/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/CalendarNavigation.kt
@@ -5,6 +5,7 @@ import androidx.navigation.NavGraphBuilder
 import androidx.navigation.compose.composable
 import androidx.navigation.compose.dialog
 import androidx.navigation.compose.navigation
+import androidx.navigation.navOptions
 import io.github.taetae98coding.diary.core.compose.dialog.transparentScrimDialogProperties
 import io.github.taetae98coding.diary.core.navigation.calendar.CalendarDestination
 import io.github.taetae98coding.diary.core.navigation.calendar.CalendarFilterDestination
@@ -15,25 +16,30 @@ import io.github.taetae98coding.diary.feature.calendar.filter.CalendarFilterRout
 import io.github.taetae98coding.diary.feature.calendar.home.CalendarHomeRoute
 
 public fun NavGraphBuilder.calendarNavigation(
-	navController: NavController,
+    navController: NavController,
 ) {
-	navigation<CalendarDestination>(
-		startDestination = CalendarHomeDestination,
-	) {
-		composable<CalendarHomeDestination> {
-			CalendarHomeRoute(
-				navigateToCalendarFilter = { navController.navigate(CalendarFilterDestination) },
-				navigateToMemoAdd = { navController.navigate(MemoAddDestination(it.start, it.endInclusive)) },
-				navigateToMemoDetail = { navController.navigate(MemoDetailDestination(it)) },
-			)
-		}
+    navigation<CalendarDestination>(
+        startDestination = CalendarHomeDestination,
+    ) {
+        composable<CalendarHomeDestination> {
+            CalendarHomeRoute(
+                navigateToCalendarFilter = { navController.navigate(CalendarFilterDestination) },
+                navigateToMemoAdd = { navController.navigate(MemoAddDestination(it.start, it.endInclusive)) },
+                navigateToMemoDetail = {
+                    navController.navigate(
+                        route = MemoDetailDestination(it),
+                        navOptions = navOptions { launchSingleTop = true },
+                    )
+                },
+            )
+        }
 
-		dialog<CalendarFilterDestination>(
-			dialogProperties = transparentScrimDialogProperties(),
-		) {
-			CalendarFilterRoute(
-				navigateUp = navController::popBackStack,
-			)
-		}
-	}
+        dialog<CalendarFilterDestination>(
+            dialogProperties = transparentScrimDialogProperties(),
+        ) {
+            CalendarFilterRoute(
+                navigateUp = navController::popBackStack,
+            )
+        }
+    }
 }
diff --git a/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/filter/CalendarFilterDialog.kt b/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/filter/CalendarFilterDialog.kt
index b1c967bd..06bf2f50 100644
--- a/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/filter/CalendarFilterDialog.kt
+++ b/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/filter/CalendarFilterDialog.kt
@@ -44,7 +44,8 @@ internal fun CalendarFilterDialog(
 			Title()
 			Content(
 				listProvider = listProvider,
-				modifier = Modifier.fillMaxWidth()
+				modifier = Modifier
+					.fillMaxWidth()
 					.heightIn(min = 100.dp),
 			)
 		}
@@ -57,7 +58,8 @@ private fun Title(
 ) {
 	Text(
 		text = "태그",
-		modifier = modifier.minimumInteractiveComponentSize()
+		modifier = modifier
+			.minimumInteractiveComponentSize()
 			.padding(horizontal = DiaryTheme.dimen.diaryHorizontalPadding),
 	)
 }
@@ -87,7 +89,8 @@ private fun Content(
 		}
 	} else {
 		FlowRow(
-			modifier = modifier.verticalScroll(rememberScrollState())
+			modifier = modifier
+				.verticalScroll(rememberScrollState())
 				.padding(DiaryTheme.dimen.itemSpace),
 			horizontalArrangement = Arrangement.spacedBy(DiaryTheme.dimen.itemSpace, Alignment.CenterHorizontally),
 			verticalArrangement = Arrangement.spacedBy(DiaryTheme.dimen.itemSpace, Alignment.CenterVertically),
diff --git a/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/filter/CalendarFilterTagViewModel.kt b/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/filter/CalendarFilterTagViewModel.kt
index 6024f373..4c430fc8 100644
--- a/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/filter/CalendarFilterTagViewModel.kt
+++ b/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/filter/CalendarFilterTagViewModel.kt
@@ -4,7 +4,7 @@ import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
 import io.github.taetae98coding.diary.core.compose.runtime.SkipProperty
 import io.github.taetae98coding.diary.domain.calendar.usecase.DeleteCalendarTagUseCase
-import io.github.taetae98coding.diary.domain.calendar.usecase.FindCalendarFilterTagUseCase
+import io.github.taetae98coding.diary.domain.calendar.usecase.FindCalendarTagFilterUseCase
 import io.github.taetae98coding.diary.domain.calendar.usecase.UpsertCalendarTagUseCase
 import io.github.taetae98coding.diary.library.coroutines.mapCollectionLatest
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -16,9 +16,13 @@ import org.koin.android.annotation.KoinViewModel
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @KoinViewModel
-internal class CalendarFilterTagViewModel(findCalendarFilterTagUseCase: FindCalendarFilterTagUseCase, private val upsertCalendarTagUseCase: UpsertCalendarTagUseCase, private val deleteCalendarTagUseCase: DeleteCalendarTagUseCase) : ViewModel() {
+internal class CalendarFilterTagViewModel(
+	findCalendarTagFilterUseCase: FindCalendarTagFilterUseCase,
+	private val upsertCalendarTagUseCase: UpsertCalendarTagUseCase,
+	private val deleteCalendarTagUseCase: DeleteCalendarTagUseCase,
+) : ViewModel() {
 	val list =
-		findCalendarFilterTagUseCase()
+		findCalendarTagFilterUseCase()
 			.mapLatest { it.getOrNull() }
 			.mapCollectionLatest {
 				TagUiState(
diff --git a/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/filter/TagUiState.kt b/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/filter/TagUiState.kt
index 941c55bd..481f21b5 100644
--- a/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/filter/TagUiState.kt
+++ b/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/filter/TagUiState.kt
@@ -2,4 +2,10 @@ package io.github.taetae98coding.diary.feature.calendar.filter
 
 import io.github.taetae98coding.diary.core.compose.runtime.SkipProperty
 
-public data class TagUiState(val id: String, val title: String, val isSelected: Boolean, val select: SkipProperty<() -> Unit>, val unselect: SkipProperty<() -> Unit>)
+public data class TagUiState(
+	val id: String,
+	val title: String,
+	val isSelected: Boolean,
+	val select: SkipProperty<() -> Unit>,
+	val unselect: SkipProperty<() -> Unit>,
+)
diff --git a/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/home/CalendarHomeHolidayViewModel.kt b/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/home/CalendarHomeHolidayViewModel.kt
index 0a2e9c49..dd924cc8 100644
--- a/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/home/CalendarHomeHolidayViewModel.kt
+++ b/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/home/CalendarHomeHolidayViewModel.kt
@@ -22,7 +22,9 @@ import org.koin.android.annotation.KoinViewModel
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @KoinViewModel
-internal class CalendarHomeHolidayViewModel(findHolidayUseCase: FindHolidayUseCase) : ViewModel() {
+internal class CalendarHomeHolidayViewModel(
+	findHolidayUseCase: FindHolidayUseCase,
+) : ViewModel() {
 	private val yearAndMonth = MutableStateFlow<Pair<Int, Month>?>(null)
 
 	val holidayList =
diff --git a/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/home/CalendarHomeScreen.kt b/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/home/CalendarHomeScreen.kt
index aa516add..b3fd7580 100644
--- a/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/home/CalendarHomeScreen.kt
+++ b/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/home/CalendarHomeScreen.kt
@@ -69,7 +69,8 @@ internal fun CalendarHomeScreen(
 			textItemListProvider = textItemListProvider,
 			holidayListProvider = holidayListProvider,
 			onCalendarItemClick = onCalendarItemClick,
-			modifier = Modifier.fillMaxSize()
+			modifier = Modifier
+				.fillMaxSize()
 				.padding(it)
 				.calendarDateRangeSelectable(
 					state = state.calendarState,
diff --git a/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/home/CalendarHomeScreenState.kt b/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/home/CalendarHomeScreenState.kt
index 8ea19674..a7d393b4 100644
--- a/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/home/CalendarHomeScreenState.kt
+++ b/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/home/CalendarHomeScreenState.kt
@@ -2,4 +2,6 @@ package io.github.taetae98coding.diary.feature.calendar.home
 
 import io.github.taetae98coding.diary.core.calendar.compose.state.CalendarState
 
-internal class CalendarHomeScreenState(val calendarState: CalendarState)
+internal class CalendarHomeScreenState(
+	val calendarState: CalendarState,
+)
diff --git a/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/home/CalendarHomeViewModel.kt b/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/home/CalendarHomeViewModel.kt
index c90d44ad..4468753f 100644
--- a/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/home/CalendarHomeViewModel.kt
+++ b/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/home/CalendarHomeViewModel.kt
@@ -23,7 +23,10 @@ import org.koin.android.annotation.KoinViewModel
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @KoinViewModel
-internal class CalendarHomeViewModel(hasCalendarFilterUseCase: HasCalendarFilterUseCase, findCalendarMemoUseCase: FindCalendarMemoUseCase) : ViewModel() {
+internal class CalendarHomeViewModel(
+	hasCalendarFilterUseCase: HasCalendarFilterUseCase,
+	findCalendarMemoUseCase: FindCalendarMemoUseCase,
+) : ViewModel() {
 	private val yearAndMonth = MutableStateFlow<Pair<Int, Month>?>(null)
 
 	val hasFilter =
diff --git a/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/home/MemoKey.kt b/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/home/MemoKey.kt
index 0bd609c3..75e30093 100644
--- a/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/home/MemoKey.kt
+++ b/app/feature/calendar/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/calendar/home/MemoKey.kt
@@ -3,4 +3,6 @@ package io.github.taetae98coding.diary.feature.calendar.home
 import kotlin.jvm.JvmInline
 
 @JvmInline
-internal value class MemoKey(val id: String)
+internal value class MemoKey(
+	val id: String,
+)
diff --git a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/MemoNavigation.kt b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/MemoNavigation.kt
index 71c2b866..2b6b8717 100644
--- a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/MemoNavigation.kt
+++ b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/MemoNavigation.kt
@@ -3,6 +3,7 @@ package io.github.taetae98coding.diary.feature.memo
 import androidx.navigation.NavController
 import androidx.navigation.NavGraphBuilder
 import androidx.navigation.compose.composable
+import androidx.navigation.navOptions
 import androidx.navigation.navigation
 import io.github.taetae98coding.diary.core.navigation.memo.MemoAddDestination
 import io.github.taetae98coding.diary.core.navigation.memo.MemoDestination
@@ -16,27 +17,37 @@ import kotlin.reflect.typeOf
 import kotlinx.datetime.LocalDate
 
 public fun NavGraphBuilder.memoNavigation(
-	navController: NavController,
+    navController: NavController,
 ) {
-	navigation<MemoDestination>(
-		startDestination = MemoAddDestination(),
-	) {
-		composable<MemoAddDestination>(
-			typeMap = mapOf(typeOf<LocalDate?>() to LocalDateNavType),
-		) {
-			MemoAddRoute(
-				navigateUp = navController::popBackStack,
-				navigateToTagAdd = { navController.navigate(TagAddDestination) },
-				navigateToTagDetail = { navController.navigate(TagDetailDestination(it)) },
-			)
-		}
+    navigation<MemoDestination>(
+        startDestination = MemoAddDestination(),
+    ) {
+        composable<MemoAddDestination>(
+            typeMap = mapOf(typeOf<LocalDate?>() to LocalDateNavType),
+        ) {
+            MemoAddRoute(
+                navigateUp = navController::popBackStack,
+                navigateToTagAdd = { navController.navigate(TagAddDestination) },
+                navigateToTagDetail = {
+                    navController.navigate(
+                        route = TagDetailDestination(it),
+                        navOptions = navOptions { launchSingleTop = true },
+                    )
+                },
+            )
+        }
 
-		composable<MemoDetailDestination> {
-			MemoDetailRoute(
-				navigateUp = navController::popBackStack,
-				navigateToTagAdd = { navController.navigate(TagAddDestination) },
-				navigateToTagDetail = { navController.navigate(TagDetailDestination(it)) },
-			)
-		}
-	}
+        composable<MemoDetailDestination> {
+            MemoDetailRoute(
+                navigateUp = navController::popBackStack,
+                navigateToTagAdd = { navController.navigate(TagAddDestination) },
+                navigateToTagDetail = {
+                    navController.navigate(
+                        route = TagDetailDestination(it),
+                        navOptions = navOptions { launchSingleTop = true },
+                    )
+                },
+            )
+        }
+    }
 }
diff --git a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/add/MemoAddRoute.kt b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/add/MemoAddRoute.kt
index 39d48049..664ff0f2 100644
--- a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/add/MemoAddRoute.kt
+++ b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/add/MemoAddRoute.kt
@@ -37,7 +37,7 @@ internal fun MemoAddRoute(
 	val navigator = rememberListDetailPaneScaffoldNavigator(scaffoldDirective = calculatePaneScaffoldDirective(windowAdaptiveInfo))
 
 	ListDetailPaneScaffold(
-		directive = navigator.scaffoldDirective.copy(defaultPanePreferredWidth = 450.dp),
+		directive = navigator.scaffoldDirective.copy(defaultPanePreferredWidth = 500.dp),
 		value = navigator.scaffoldValue,
 		listPane = {
 			val state = rememberMemoDetailScreenAddState(
diff --git a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/add/MemoAddViewModel.kt b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/add/MemoAddViewModel.kt
index 11cc082b..ccea7968 100644
--- a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/add/MemoAddViewModel.kt
+++ b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/add/MemoAddViewModel.kt
@@ -28,7 +28,11 @@ import org.koin.android.annotation.KoinViewModel
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @KoinViewModel
-internal class MemoAddViewModel(savedStateHandle: SavedStateHandle, private val addMemoUseCase: AddMemoUseCase, pageTagUseCase: PageTagUseCase) : ViewModel() {
+internal class MemoAddViewModel(
+	savedStateHandle: SavedStateHandle,
+	private val addMemoUseCase: AddMemoUseCase,
+	pageTagUseCase: PageTagUseCase,
+) : ViewModel() {
 	val route =
 		savedStateHandle.toRoute<MemoAddDestination>(
 			typeMap = mapOf(typeOf<LocalDate?>() to LocalDateNavType),
@@ -45,7 +49,7 @@ internal class MemoAddViewModel(savedStateHandle: SavedStateHandle, private val
 				started = SharingStarted.WhileSubscribed(5_000),
 				initialValue = null,
 			)
-	private val selectedTag = MutableStateFlow(emptySet<String>())
+	private val selectedTag = MutableStateFlow(setOfNotNull(savedStateHandle.get<String?>(MemoAddDestination.SELECTED_TAG)))
 	private val primaryTag = MutableStateFlow<String?>(null)
 
 	val memoTagList =
diff --git a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailActionButton.kt b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailActionButton.kt
index c4564aa7..498c4f2a 100644
--- a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailActionButton.kt
+++ b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailActionButton.kt
@@ -3,5 +3,9 @@ package io.github.taetae98coding.diary.feature.memo.detail
 internal sealed class MemoDetailActionButton {
 	data object None : MemoDetailActionButton()
 
-	data class FinishAndDetail(val isFinish: Boolean, val onFinishChange: (Boolean) -> Unit, val delete: () -> Unit) : MemoDetailActionButton()
+	data class FinishAndDetail(
+		val isFinish: Boolean,
+		val onFinishChange: (Boolean) -> Unit,
+		val delete: () -> Unit,
+	) : MemoDetailActionButton()
 }
diff --git a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailFloatingButton.kt b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailFloatingButton.kt
index 4fc0315e..7ba4d129 100644
--- a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailFloatingButton.kt
+++ b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailFloatingButton.kt
@@ -3,5 +3,7 @@ package io.github.taetae98coding.diary.feature.memo.detail
 internal sealed class MemoDetailFloatingButton {
 	data object None : MemoDetailFloatingButton()
 
-	data class Add(val onAdd: () -> Unit) : MemoDetailFloatingButton()
+	data class Add(
+		val onAdd: () -> Unit,
+	) : MemoDetailFloatingButton()
 }
diff --git a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailNavigationButton.kt b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailNavigationButton.kt
index 5806fbfa..37a6963a 100644
--- a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailNavigationButton.kt
+++ b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailNavigationButton.kt
@@ -3,5 +3,7 @@ package io.github.taetae98coding.diary.feature.memo.detail
 internal sealed class MemoDetailNavigationButton {
 	data object None : MemoDetailNavigationButton()
 
-	data class NavigateUp(val onNavigateUp: () -> Unit) : MemoDetailNavigationButton()
+	data class NavigateUp(
+		val onNavigateUp: () -> Unit,
+	) : MemoDetailNavigationButton()
 }
diff --git a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailRoute.kt b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailRoute.kt
index c5ae22ce..a9930158 100644
--- a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailRoute.kt
+++ b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailRoute.kt
@@ -11,6 +11,7 @@ import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import androidx.window.core.layout.WindowWidthSizeClass
 import io.github.taetae98coding.diary.core.compose.adaptive.isListVisible
@@ -33,7 +34,7 @@ internal fun MemoDetailRoute(
 	val navigator = rememberListDetailPaneScaffoldNavigator(scaffoldDirective = calculatePaneScaffoldDirective(windowAdaptiveInfo))
 
 	ListDetailPaneScaffold(
-		directive = navigator.scaffoldDirective,
+		directive = navigator.scaffoldDirective.copy(defaultPanePreferredWidth = 500.dp),
 		value = navigator.scaffoldValue,
 		listPane = {
 			val detail by detailViewModel.detail.collectAsStateWithLifecycle()
diff --git a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailScreen.kt b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailScreen.kt
index 271b9850..ecdec0bf 100644
--- a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailScreen.kt
+++ b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailScreen.kt
@@ -121,7 +121,8 @@ internal fun MemoDetailScreen(
 			onTagTitle = onTagTitle,
 			onTag = onTag,
 			tagListProvider = tagListProvider,
-			modifier = Modifier.fillMaxSize()
+			modifier = Modifier
+				.fillMaxSize()
 				.padding(it)
 				.padding(DiaryTheme.dimen.screenPaddingValues),
 		)
@@ -202,7 +203,8 @@ private fun Content(
 	modifier: Modifier = Modifier,
 ) {
 	Column(
-		modifier = Modifier.verticalScroll(state = rememberScrollState())
+		modifier = Modifier
+			.verticalScroll(state = rememberScrollState())
 			.then(modifier),
 		verticalArrangement = Arrangement.spacedBy(DiaryTheme.dimen.itemSpace),
 	) {
@@ -227,7 +229,8 @@ private fun InternalDiaryTag(
 	TagFlow(
 		title = {
 			Row(
-				modifier = Modifier.fillMaxWidth()
+				modifier = Modifier
+					.fillMaxWidth()
 					.clickable(onClick = onTitle)
 					.minimumInteractiveComponentSize()
 					.padding(horizontal = DiaryTheme.dimen.diaryHorizontalPadding),
@@ -245,7 +248,8 @@ private fun InternalDiaryTag(
 				onClick = { onTag(it.id) },
 			)
 		},
-		modifier = modifier.fillMaxWidth()
+		modifier = modifier
+			.fillMaxWidth()
 			.heightIn(min = 150.dp, max = 200.dp),
 	)
 }
@@ -258,7 +262,8 @@ private fun InternalDiaryColor(
 	Row(modifier = modifier) {
 		DiaryColor(
 			state = state.colorState,
-			modifier = Modifier.weight(1F)
+			modifier = Modifier
+				.weight(1F)
 				.height(100.dp),
 		)
 
diff --git a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailScreenState.kt b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailScreenState.kt
index 97d34762..59759996 100644
--- a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailScreenState.kt
+++ b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailScreenState.kt
@@ -21,9 +21,21 @@ internal sealed class MemoDetailScreenState {
 
 	val hostState: SnackbarHostState = SnackbarHostState()
 
-	data class Add(override val coroutineScope: CoroutineScope, override val componentState: DiaryComponentState, override val dateState: DiaryDateState, override val colorState: DiaryColorState) : MemoDetailScreenState()
+	data class Add(
+		override val coroutineScope: CoroutineScope,
+		override val componentState: DiaryComponentState,
+		override val dateState: DiaryDateState,
+		override val colorState: DiaryColorState,
+	) : MemoDetailScreenState()
 
-	data class Detail(val onDelete: () -> Unit, val onUpdate: () -> Unit, override val coroutineScope: CoroutineScope, override val componentState: DiaryComponentState, override val dateState: DiaryDateState, override val colorState: DiaryColorState) : MemoDetailScreenState()
+	data class Detail(
+		val onDelete: () -> Unit,
+		val onUpdate: () -> Unit,
+		override val coroutineScope: CoroutineScope,
+		override val componentState: DiaryComponentState,
+		override val dateState: DiaryDateState,
+		override val colorState: DiaryColorState,
+	) : MemoDetailScreenState()
 
 	val memoDetail: MemoDetail
 		get() {
diff --git a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailScreenUiState.kt b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailScreenUiState.kt
index a80c596e..b5ff6468 100644
--- a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailScreenUiState.kt
+++ b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailScreenUiState.kt
@@ -1,5 +1,13 @@
 package io.github.taetae98coding.diary.feature.memo.detail
 
-internal data class MemoDetailScreenUiState(val isProgress: Boolean = false, val isAdd: Boolean = false, val isDelete: Boolean = false, val isUpdate: Boolean = false, val isTitleBlankError: Boolean = false, val isUnknownError: Boolean = false, val onMessageShow: () -> Unit = {}) {
+internal data class MemoDetailScreenUiState(
+	val isProgress: Boolean = false,
+	val isAdd: Boolean = false,
+	val isDelete: Boolean = false,
+	val isUpdate: Boolean = false,
+	val isTitleBlankError: Boolean = false,
+	val isUnknownError: Boolean = false,
+	val onMessageShow: () -> Unit = {},
+) {
 	val hasMessage = isAdd || isDelete || isUpdate || isTitleBlankError || isUnknownError
 }
diff --git a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailViewModel.kt b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailViewModel.kt
index 381a2d38..52b29663 100644
--- a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailViewModel.kt
+++ b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/MemoDetailViewModel.kt
@@ -50,7 +50,7 @@ internal class MemoDetailViewModel(
 			.mapLatest { it?.detail }
 			.stateIn(
 				scope = viewModelScope,
-				started = SharingStarted.WhileSubscribed(5_000),
+                started = SharingStarted.WhileSubscribed(5_000),
 				initialValue = null,
 			)
 
@@ -66,11 +66,11 @@ internal class MemoDetailViewModel(
 				scope = viewModelScope,
 				started = SharingStarted.WhileSubscribed(5_000),
 				initialValue =
-				MemoDetailActionButton.FinishAndDetail(
-					isFinish = false,
-					onFinishChange = ::onFinishChange,
-					delete = ::delete,
-				),
+					MemoDetailActionButton.FinishAndDetail(
+						isFinish = false,
+						onFinishChange = ::onFinishChange,
+						delete = ::delete,
+					),
 			)
 
 	private fun onFinishChange(isFinish: Boolean) {
diff --git a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/RememberMemoDetailScreenDetailState.kt b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/RememberMemoDetailScreenDetailState.kt
index 66644f6d..012b322a 100644
--- a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/RememberMemoDetailScreenDetailState.kt
+++ b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/detail/RememberMemoDetailScreenDetailState.kt
@@ -16,6 +16,7 @@ internal fun rememberMemoDetailScreenDetailState(
 	detailProvider: () -> MemoDetail?,
 ): MemoDetailScreenState.Detail {
 	val detail = detailProvider()
+    println(detail)
 	val coroutineScope = rememberCoroutineScope()
 	val componentState =
 		rememberDiaryComponentState(
diff --git a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/tag/MemoTagNavigationButton.kt b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/tag/MemoTagNavigationButton.kt
index 7187f450..11579461 100644
--- a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/tag/MemoTagNavigationButton.kt
+++ b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/tag/MemoTagNavigationButton.kt
@@ -3,5 +3,7 @@ package io.github.taetae98coding.diary.feature.memo.tag
 internal sealed class MemoTagNavigationButton {
 	data object None : MemoTagNavigationButton()
 
-	data class NavigateUp(val onNavigateUp: () -> Unit) : MemoTagNavigationButton()
+	data class NavigateUp(
+		val onNavigateUp: () -> Unit,
+	) : MemoTagNavigationButton()
 }
diff --git a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/tag/MemoTagScreen.kt b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/tag/MemoTagScreen.kt
index a672de75..e2174fd0 100644
--- a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/tag/MemoTagScreen.kt
+++ b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/tag/MemoTagScreen.kt
@@ -48,7 +48,8 @@ internal fun MemoTagScreen(
 			onTagAdd = onTagAdd,
 			memoTagListProvider = memoTagListProvider,
 			tagListProvider = tagListProvider,
-			modifier = Modifier.fillMaxWidth()
+			modifier = Modifier
+				.fillMaxWidth()
 				.padding(it)
 				.padding(DiaryTheme.dimen.diaryPaddingValues),
 		)
@@ -67,13 +68,15 @@ private fun Content(
 		verticalArrangement = Arrangement.spacedBy(DiaryTheme.dimen.itemSpace),
 	) {
 		TagFlow(
-			modifier = Modifier.fillMaxWidth()
+			modifier = Modifier
+				.fillMaxWidth()
 				.weight(3F),
 			listProvider = memoTagListProvider,
 			title = {
 				Text(
 					text = "캘린더 태그",
-					modifier = Modifier.fillMaxWidth()
+					modifier = Modifier
+						.fillMaxWidth()
 						.minimumInteractiveComponentSize()
 						.padding(horizontal = DiaryTheme.dimen.diaryHorizontalPadding),
 				)
@@ -83,13 +86,15 @@ private fun Content(
 		)
 
 		TagFlow(
-			modifier = Modifier.fillMaxWidth()
+			modifier = Modifier
+				.fillMaxWidth()
 				.weight(7F),
 			listProvider = tagListProvider,
 			title = {
 				Text(
 					text = "태그",
-					modifier = Modifier.fillMaxWidth()
+					modifier = Modifier
+						.fillMaxWidth()
 						.minimumInteractiveComponentSize()
 						.padding(horizontal = DiaryTheme.dimen.diaryHorizontalPadding),
 				)
diff --git a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/tag/TagFlow.kt b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/tag/TagFlow.kt
index 325367b8..a847418f 100644
--- a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/tag/TagFlow.kt
+++ b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/tag/TagFlow.kt
@@ -52,7 +52,8 @@ internal fun TagFlow(
 			}
 		} else {
 			FlowRow(
-				modifier = Modifier.fillMaxSize()
+				modifier = Modifier
+					.fillMaxSize()
 					.verticalScroll(rememberScrollState())
 					.padding(DiaryTheme.dimen.itemSpace),
 				horizontalArrangement = Arrangement.spacedBy(DiaryTheme.dimen.itemSpace, Alignment.CenterHorizontally),
diff --git a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/tag/TagUiState.kt b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/tag/TagUiState.kt
index b0b8d668..834626d6 100644
--- a/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/tag/TagUiState.kt
+++ b/app/feature/memo/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/memo/tag/TagUiState.kt
@@ -2,4 +2,11 @@ package io.github.taetae98coding.diary.feature.memo.tag
 
 import io.github.taetae98coding.diary.core.compose.runtime.SkipProperty
 
-public data class TagUiState(val id: String, val title: String, val isSelected: Boolean, val color: Int, val select: SkipProperty<() -> Unit>, val unselect: SkipProperty<() -> Unit>)
+public data class TagUiState(
+	val id: String,
+	val title: String,
+	val isSelected: Boolean,
+	val color: Int,
+	val select: SkipProperty<() -> Unit>,
+	val unselect: SkipProperty<() -> Unit>,
+)
diff --git a/app/feature/more/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/more/MoreScreen.kt b/app/feature/more/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/more/MoreScreen.kt
index c7956365..72958308 100644
--- a/app/feature/more/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/more/MoreScreen.kt
+++ b/app/feature/more/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/more/MoreScreen.kt
@@ -34,7 +34,8 @@ internal fun MoreScreen(
 			accountUiStateProvider = accountUiStateProvider,
 			onLogin = onLogin,
 			onJoin = onJoin,
-			modifier = Modifier.fillMaxSize()
+			modifier = Modifier
+				.fillMaxSize()
 				.padding(it)
 				.padding(DiaryTheme.dimen.screenPaddingValues),
 		)
@@ -49,7 +50,8 @@ private fun Content(
 	modifier: Modifier = Modifier,
 ) {
 	Column(
-		modifier = Modifier.verticalScroll(rememberScrollState())
+		modifier = Modifier
+			.verticalScroll(rememberScrollState())
 			.then(modifier),
 	) {
 		MoreAccount(
diff --git a/app/feature/more/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/more/account/MoreAccount.kt b/app/feature/more/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/more/account/MoreAccount.kt
index 013d9def..bf3fae21 100644
--- a/app/feature/more/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/more/account/MoreAccount.kt
+++ b/app/feature/more/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/more/account/MoreAccount.kt
@@ -77,7 +77,8 @@ private fun ProfileImage(
 	modifier: Modifier = Modifier,
 ) {
 	Box(
-		modifier = modifier.size(54.dp)
+		modifier = modifier
+			.size(54.dp)
 			.background(
 				color = LocalContentColor.current.multiplyAlpha(value = 0.38F),
 				shape = CircleShape,
@@ -98,7 +99,8 @@ private fun Email(
 			is MoreAccountUiState.Loading -> {
 				Text(
 					text = "",
-					modifier = modifier.width(100.dp)
+					modifier = modifier
+						.width(100.dp)
 						.shimmer(),
 				)
 			}
diff --git a/app/feature/more/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/more/account/state/MoreAccountUiState.kt b/app/feature/more/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/more/account/state/MoreAccountUiState.kt
index 9df7829d..90b462fb 100644
--- a/app/feature/more/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/more/account/state/MoreAccountUiState.kt
+++ b/app/feature/more/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/more/account/state/MoreAccountUiState.kt
@@ -5,5 +5,8 @@ internal sealed class MoreAccountUiState {
 
 	data object Guest : MoreAccountUiState()
 
-	data class Member(val email: String, val logout: () -> Unit) : MoreAccountUiState()
+	data class Member(
+		val email: String,
+		val logout: () -> Unit,
+	) : MoreAccountUiState()
 }
diff --git a/app/feature/more/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/more/viewmodel/MoreAccountViewModel.kt b/app/feature/more/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/more/viewmodel/MoreAccountViewModel.kt
index 19ee2137..25213164 100644
--- a/app/feature/more/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/more/viewmodel/MoreAccountViewModel.kt
+++ b/app/feature/more/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/more/viewmodel/MoreAccountViewModel.kt
@@ -17,7 +17,10 @@ import org.koin.android.annotation.KoinViewModel
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @KoinViewModel
-internal class MoreAccountViewModel(getAccountUseCase: GetAccountUseCase, private val logoutUseCase: LogoutUseCase) : ViewModel() {
+internal class MoreAccountViewModel(
+	getAccountUseCase: GetAccountUseCase,
+	private val logoutUseCase: LogoutUseCase,
+) : ViewModel() {
 	private val isProgress = MutableStateFlow(false)
 	private val account =
 		getAccountUseCase()
diff --git a/app/feature/tag/build.gradle.kts b/app/feature/tag/build.gradle.kts
index f6887fa8..82cfdaaf 100644
--- a/app/feature/tag/build.gradle.kts
+++ b/app/feature/tag/build.gradle.kts
@@ -6,6 +6,7 @@ kotlin {
     sourceSets {
         commonMain {
             dependencies {
+                implementation(project(":app:domain:memo"))
                 implementation(project(":app:domain:tag"))
             }
         }
diff --git a/app/feature/tag/src/androidMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailScreenPreview.kt b/app/feature/tag/src/androidMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailScreenPreview.kt
index 882125c1..7923c719 100644
--- a/app/feature/tag/src/androidMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailScreenPreview.kt
+++ b/app/feature/tag/src/androidMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailScreenPreview.kt
@@ -30,6 +30,7 @@ private fun DetailPreview() {
 			state = rememberTagDetailScreenDetailState(
 				onUpdate = {},
 				onDelete = {},
+                onMemo = {},
 				detailProvider = {
 					TagDetail(
 						title = "Title",
diff --git a/app/feature/tag/src/androidMain/kotlin/io/github/taetae98coding/diary/feature/tag/memo/TagMemoScreenPreview.kt b/app/feature/tag/src/androidMain/kotlin/io/github/taetae98coding/diary/feature/tag/memo/TagMemoScreenPreview.kt
new file mode 100644
index 00000000..06fc2027
--- /dev/null
+++ b/app/feature/tag/src/androidMain/kotlin/io/github/taetae98coding/diary/feature/tag/memo/TagMemoScreenPreview.kt
@@ -0,0 +1,68 @@
+package io.github.taetae98coding.diary.feature.tag.memo
+
+import androidx.compose.runtime.Composable
+import io.github.taetae98coding.diary.core.compose.runtime.SkipProperty
+import io.github.taetae98coding.diary.core.design.system.preview.DiaryPreview
+import io.github.taetae98coding.diary.core.design.system.theme.DiaryTheme
+import kotlinx.datetime.LocalDate
+
+@DiaryPreview
+@Composable
+private fun LoadingPreview() {
+    DiaryTheme {
+        TagMemoScreen(
+            state = rememberTagMemoScreenState(),
+            navigateButtonProvider = { TagMemoNavigateButton.NavigateUp(onNavigateUp = {}) },
+            uiStateProvider = { TagMemoScreenUiState() },
+            onAdd = {},
+            listProvider = { null },
+            onMemo = {},
+        )
+    }
+}
+
+@DiaryPreview
+@Composable
+private fun EmptyPreview() {
+    DiaryTheme {
+        TagMemoScreen(
+            state = rememberTagMemoScreenState(),
+            navigateButtonProvider = { TagMemoNavigateButton.NavigateUp(onNavigateUp = {}) },
+            uiStateProvider = { TagMemoScreenUiState() },
+            onAdd = {},
+            listProvider = { emptyList() },
+            onMemo = {},
+        )
+    }
+}
+
+@DiaryPreview
+@Composable
+private fun Preview() {
+    DiaryTheme {
+        TagMemoScreen(
+            state = rememberTagMemoScreenState(),
+            navigateButtonProvider = { TagMemoNavigateButton.NavigateUp(onNavigateUp = {}) },
+            uiStateProvider = { TagMemoScreenUiState() },
+            onAdd = {},
+            listProvider = {
+                List(10) {
+                    MemoListItemUiState(
+                        id = it.toString(),
+                        title = "Title $it",
+                        dateRange = if (it % 3 == 0) {
+                            null
+                        } else if (it % 3 == 1) {
+                            LocalDate(2000, 1, 1)..LocalDate(2000, 1, 1)
+                        } else {
+                            LocalDate(2000, 1, 1)..LocalDate(2000, 1, 2)
+                        },
+                        finish = SkipProperty {},
+                        delete = SkipProperty {},
+                    )
+                }
+            },
+            onMemo = {},
+        )
+    }
+}
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/TagNavigate.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/TagNavigate.kt
index afdef0ac..d6e1bc7f 100644
--- a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/TagNavigate.kt
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/TagNavigate.kt
@@ -5,5 +5,7 @@ internal sealed class TagNavigate {
 
 	data object Add : TagNavigate()
 
-	data class Tag(val tagId: String) : TagNavigate()
+	data class Tag(
+		val tagId: String,
+	) : TagNavigate()
 }
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/TagNavigation.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/TagNavigation.kt
index ca5a54d2..cc2c0cb5 100644
--- a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/TagNavigation.kt
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/TagNavigation.kt
@@ -4,7 +4,11 @@ import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
 import androidx.navigation.NavController
 import androidx.navigation.NavGraphBuilder
 import androidx.navigation.compose.composable
+import androidx.navigation.navOptions
+import androidx.navigation.toRoute
 import io.github.taetae98coding.diary.core.compose.adaptive.isListVisible
+import io.github.taetae98coding.diary.core.navigation.memo.MemoAddDestination
+import io.github.taetae98coding.diary.core.navigation.memo.MemoDetailDestination
 import io.github.taetae98coding.diary.core.navigation.tag.TagAddDestination
 import io.github.taetae98coding.diary.core.navigation.tag.TagDestination
 import io.github.taetae98coding.diary.core.navigation.tag.TagDetailDestination
@@ -13,23 +17,39 @@ import io.github.taetae98coding.diary.feature.tag.detail.TagDetailRoute
 
 @OptIn(ExperimentalMaterial3AdaptiveApi::class)
 public fun NavGraphBuilder.tagNavigation(
-	navController: NavController,
+    navController: NavController,
 ) {
-	composable<TagDestination> { backStackEntry ->
-		TagRoute(
-			onScaffoldValueChange = { backStackEntry.savedStateHandle["app_navigation_visible"] = it.isListVisible() },
-		)
-	}
+    composable<TagDestination> { backStackEntry ->
+        TagRoute(
+            navigateToMemoAdd = { navController.navigate(MemoAddDestination(selectedTag = it)) },
+            navigateToMemoDetail = {
+                navController.navigate(
+                    route = MemoDetailDestination(it),
+                    navOptions = navOptions { launchSingleTop = true },
+                )
+            },
+            onScaffoldValueChange = { backStackEntry.savedStateHandle["app_navigation_visible"] = it.isListVisible() },
+        )
+    }
 
-	composable<TagAddDestination> {
-		TagAddRoute(
-			navigateUp = navController::popBackStack,
-		)
-	}
+    composable<TagAddDestination> {
+        TagAddRoute(
+            navigateUp = navController::popBackStack,
+        )
+    }
 
-	composable<TagDetailDestination> {
-		TagDetailRoute(
-			navigateUp = navController::popBackStack,
-		)
-	}
+    composable<TagDetailDestination> { backStackEntry ->
+        val route = backStackEntry.toRoute<TagDetailDestination>()
+
+        TagDetailRoute(
+            navigateUp = navController::popBackStack,
+            navigateToMemoAdd = { navController.navigate(MemoAddDestination(selectedTag = route.tagId)) },
+            navigateToMemoDetail = {
+                navController.navigate(
+                    route = MemoDetailDestination(it),
+                    navOptions = navOptions { launchSingleTop = true },
+                )
+            },
+        )
+    }
 }
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/TagRoute.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/TagRoute.kt
index 6486b655..d0f635f4 100644
--- a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/TagRoute.kt
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/TagRoute.kt
@@ -18,6 +18,7 @@ import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import androidx.window.core.layout.WindowWidthSizeClass
 import io.github.taetae98coding.diary.core.compose.adaptive.isDetailVisible
@@ -35,213 +36,255 @@ import io.github.taetae98coding.diary.feature.tag.list.TagListFloatingButton
 import io.github.taetae98coding.diary.feature.tag.list.TagListScreen
 import io.github.taetae98coding.diary.feature.tag.list.TagListViewModel
 import io.github.taetae98coding.diary.feature.tag.list.rememberTagListScreenState
+import io.github.taetae98coding.diary.feature.tag.memo.TagMemoNavigateButton
+import io.github.taetae98coding.diary.feature.tag.memo.TagMemoScreen
+import io.github.taetae98coding.diary.feature.tag.memo.TagMemoViewModel
+import io.github.taetae98coding.diary.feature.tag.memo.rememberTagMemoScreenState
 import org.koin.compose.viewmodel.koinViewModel
 
 @OptIn(ExperimentalMaterial3AdaptiveApi::class)
 @Composable
 internal fun TagRoute(
-	onScaffoldValueChange: (ThreePaneScaffoldValue) -> Unit,
-	modifier: Modifier = Modifier,
-	listViewModel: TagListViewModel = koinViewModel(),
-	addViewModel: TagAddViewModel = koinViewModel(),
-	detailViewModel: TagDetailViewModel = koinViewModel(),
+    navigateToMemoAdd: (String) -> Unit,
+    navigateToMemoDetail: (String) -> Unit,
+    onScaffoldValueChange: (ThreePaneScaffoldValue) -> Unit,
+    modifier: Modifier = Modifier,
+    listViewModel: TagListViewModel = koinViewModel(),
+    addViewModel: TagAddViewModel = koinViewModel(),
+    detailViewModel: TagDetailViewModel = koinViewModel(),
+    memoViewModel: TagMemoViewModel = koinViewModel(),
 ) {
-	val windowAdaptiveInfo = currentWindowAdaptiveInfo()
-	val navigator = rememberListDetailPaneScaffoldNavigator<String?>(scaffoldDirective = calculatePaneScaffoldDirective(windowAdaptiveInfo))
-
-	var tagNavigate by remember { mutableStateOf<TagNavigate>(TagNavigate.None) }
-	var detailPaneRefreshCount by remember { mutableIntStateOf(0) }
-
-	ListDetailPaneScaffold(
-		directive = navigator.scaffoldDirective,
-		value = navigator.scaffoldValue,
-		listPane = {
-			AnimatedPane {
-				val isFloatingVisible by remember {
-					derivedStateOf {
-						if (navigator.isDetailVisible()) {
-							navigator.currentDestination?.content != null
-						} else {
-							true
-						}
-					}
-				}
-
-				val list by listViewModel.list.collectAsStateWithLifecycle()
-				val uiState by listViewModel.uiState.collectAsStateWithLifecycle()
-
-				TagListScreen(
-					state = rememberTagListScreenState(),
-					floatingButtonProvider = {
-						if (isFloatingVisible) {
-							TagListFloatingButton.Add(
-								onAdd = {
-									if (navigator.isDetailVisible()) {
-										tagNavigate = TagNavigate.Add
-									} else {
-										navigator.navigateTo(ThreePaneScaffoldRole.Primary)
-									}
-								},
-							)
-						} else {
-							TagListFloatingButton.None
-						}
-					},
-					listProvider = { list },
-					onTag = {
-						if (navigator.isDetailVisible() && navigator.currentDestination?.content != null) {
-							tagNavigate = TagNavigate.Tag(it)
-						} else {
-							navigator.navigateTo(ThreePaneScaffoldRole.Primary, it)
-							detailPaneRefreshCount++
-						}
-					},
-					uiStateProvider = { uiState },
-				)
-			}
-		},
-		detailPane = {
-			AnimatedPane {
-				val tagDetail by detailViewModel.tagDetail.collectAsStateWithLifecycle()
-				val isAdd = remember(detailPaneRefreshCount) { navigator.currentDestination?.content == null }
-				val state = if (isAdd) {
-					rememberTagDetailScreenAddState()
-				} else {
-					rememberTagDetailScreenDetailState(
-						onUpdate = {
-							when (val navigate = tagNavigate) {
-								is TagNavigate.Add -> {
-									navigator.navigateTo(ThreePaneScaffoldRole.Primary)
-									detailPaneRefreshCount++
-									tagNavigate = TagNavigate.None
-								}
-
-								is TagNavigate.Tag -> {
-									navigator.navigateTo(ThreePaneScaffoldRole.Primary, navigate.tagId)
-									tagNavigate = TagNavigate.None
-								}
-
-								is TagNavigate.None -> {
-									navigator.navigateBack()
-								}
-							}
-						},
-						onDelete = {
-							navigator.navigateBack()
-							if (windowAdaptiveInfo.windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.EXPANDED) {
-								detailPaneRefreshCount++
-							}
-						},
-						detailProvider = { tagDetail },
-					)
-				}
-				val isNavigateUpVisible = remember(windowAdaptiveInfo) {
-					if (windowAdaptiveInfo.windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.EXPANDED) {
-						!navigator.isListVisible()
-					} else {
-						true
-					}
-				}
-				val detailActionButton by detailViewModel.actionButton.collectAsStateWithLifecycle()
-				val uiState = if (isAdd) {
-					addViewModel.uiState.collectAsStateWithLifecycle()
-				} else {
-					detailViewModel.uiState.collectAsStateWithLifecycle()
-				}
-
-				TagDetailScreen(
-					state = state,
-					titleProvider = {
-						if (isAdd) {
-							"태그 추가"
-						} else {
-							tagDetail?.title
-						}
-					},
-					navigateButtonProvider = {
-						if (isNavigateUpVisible) {
-							TagDetailNavigationButton.NavigateUp(
-								onNavigateUp = {
-									if (isAdd) {
-										navigator.navigateBack()
-									} else {
-										detailViewModel.update(state.tagDetail)
-									}
-								},
-							)
-						} else {
-							TagDetailNavigationButton.None
-						}
-					},
-					actionButtonProvider = {
-						if (isAdd) {
-							TagDetailActionButton.None
-						} else {
-							detailActionButton
-						}
-					},
-					floatingButtonProvider = {
-						if (isAdd) {
-							TagDetailFloatingButton.Add(onAdd = { addViewModel.add(state.tagDetail) })
-						} else {
-							TagDetailFloatingButton.None
-						}
-					},
-					uiStateProvider = { uiState.value },
-				)
-
-				LaunchedEffect(tagNavigate) {
-					when (tagNavigate) {
-						is TagNavigate.Add -> {
-							detailViewModel.update(state.tagDetail)
-						}
-
-						is TagNavigate.Tag -> {
-							detailViewModel.update(state.tagDetail)
-						}
-
-						is TagNavigate.None -> Unit
-					}
-				}
-			}
-		},
-		modifier = modifier,
-	)
-
-	LaunchedScaffoldValue(
-		navigator = navigator,
-		onScaffoldValueChange = onScaffoldValueChange,
-	)
-
-	LaunchedFetch(
-		navigator = navigator,
-		detailViewModel = detailViewModel,
-	)
-
-	KBackHandler(
-		isEnabled = navigator.canNavigateBack(),
-		onBack = navigator::navigateBack,
-	)
+    val windowAdaptiveInfo = currentWindowAdaptiveInfo()
+    val navigator = rememberListDetailPaneScaffoldNavigator<String?>(scaffoldDirective = calculatePaneScaffoldDirective(windowAdaptiveInfo))
+
+    var tagNavigate by remember { mutableStateOf<TagNavigate>(TagNavigate.None) }
+    var detailPaneRefreshCount by remember { mutableIntStateOf(0) }
+
+    ListDetailPaneScaffold(
+        directive = navigator.scaffoldDirective.copy(defaultPanePreferredWidth = 500.dp),
+        value = navigator.scaffoldValue,
+        listPane = {
+            AnimatedPane {
+                val isFloatingVisible by remember {
+                    derivedStateOf {
+                        if (navigator.isDetailVisible()) {
+                            navigator.currentDestination?.content != null
+                        } else {
+                            true
+                        }
+                    }
+                }
+
+                val list by listViewModel.list.collectAsStateWithLifecycle()
+                val uiState by listViewModel.uiState.collectAsStateWithLifecycle()
+
+                TagListScreen(
+                    state = rememberTagListScreenState(),
+                    floatingButtonProvider = {
+                        if (isFloatingVisible) {
+                            TagListFloatingButton.Add(
+                                onAdd = {
+                                    if (navigator.isDetailVisible()) {
+                                        tagNavigate = TagNavigate.Add
+                                    } else {
+                                        navigator.navigateTo(ThreePaneScaffoldRole.Primary)
+                                    }
+                                },
+                            )
+                        } else {
+                            TagListFloatingButton.None
+                        }
+                    },
+                    listProvider = { list },
+                    onTag = {
+                        if (navigator.isDetailVisible() && navigator.currentDestination?.content != null) {
+                            tagNavigate = TagNavigate.Tag(it)
+                        } else {
+                            navigator.navigateTo(ThreePaneScaffoldRole.Primary, it)
+                            detailPaneRefreshCount++
+                        }
+                    },
+                    uiStateProvider = { uiState },
+                )
+            }
+        },
+        detailPane = {
+            AnimatedPane {
+                val tagDetail by detailViewModel.tagDetail.collectAsStateWithLifecycle()
+                val isAdd = remember(detailPaneRefreshCount) { navigator.currentDestination?.content == null }
+                val state = if (isAdd) {
+                    rememberTagDetailScreenAddState()
+                } else {
+                    rememberTagDetailScreenDetailState(
+                        onUpdate = {
+                            when (val navigate = tagNavigate) {
+                                is TagNavigate.Add -> {
+                                    navigator.navigateTo(ThreePaneScaffoldRole.Primary)
+                                    detailPaneRefreshCount++
+                                    tagNavigate = TagNavigate.None
+                                }
+
+                                is TagNavigate.Tag -> {
+                                    navigator.navigateTo(ThreePaneScaffoldRole.Primary, navigate.tagId)
+                                    tagNavigate = TagNavigate.None
+                                }
+
+                                is TagNavigate.None -> {
+                                    navigator.navigateBack()
+                                }
+                            }
+                        },
+                        onDelete = {
+                            navigator.navigateBack()
+                            if (windowAdaptiveInfo.windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.EXPANDED) {
+                                detailPaneRefreshCount++
+                            }
+                        },
+                        onMemo = { navigator.currentDestination?.content?.let { navigator.navigateTo(ThreePaneScaffoldRole.Tertiary, it) } },
+                        detailProvider = { tagDetail },
+                    )
+                }
+                val isNavigateUpVisible by remember(windowAdaptiveInfo) {
+                    derivedStateOf {
+                        if (windowAdaptiveInfo.windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.EXPANDED) {
+                            !navigator.isListVisible()
+                        } else {
+                            true
+                        }
+                    }
+                }
+                val detailActionButton by detailViewModel.actionButton.collectAsStateWithLifecycle()
+                val uiState = if (isAdd) {
+                    addViewModel.uiState.collectAsStateWithLifecycle()
+                } else {
+                    detailViewModel.uiState.collectAsStateWithLifecycle()
+                }
+
+                TagDetailScreen(
+                    state = state,
+                    titleProvider = {
+                        if (isAdd) {
+                            "태그 추가"
+                        } else {
+                            tagDetail?.title
+                        }
+                    },
+                    navigateButtonProvider = {
+                        if (isNavigateUpVisible) {
+                            TagDetailNavigationButton.NavigateUp(
+                                onNavigateUp = {
+                                    if (isAdd) {
+                                        navigator.navigateBack()
+                                    } else {
+                                        detailViewModel.update(state.tagDetail)
+                                    }
+                                },
+                            )
+                        } else {
+                            TagDetailNavigationButton.None
+                        }
+                    },
+                    actionButtonProvider = {
+                        if (isAdd) {
+                            TagDetailActionButton.None
+                        } else {
+                            detailActionButton
+                        }
+                    },
+                    floatingButtonProvider = {
+                        if (isAdd) {
+                            TagDetailFloatingButton.Add(onAdd = { addViewModel.add(state.tagDetail) })
+                        } else {
+                            TagDetailFloatingButton.None
+                        }
+                    },
+                    uiStateProvider = { uiState.value },
+                )
+
+                LaunchedEffect(tagNavigate) {
+                    when (tagNavigate) {
+                        is TagNavigate.Add -> {
+                            detailViewModel.update(state.tagDetail)
+                        }
+
+                        is TagNavigate.Tag -> {
+                            detailViewModel.update(state.tagDetail)
+                        }
+
+                        is TagNavigate.None -> Unit
+                    }
+                }
+            }
+        },
+        modifier = modifier,
+        extraPane = {
+            AnimatedPane {
+                val uiState by memoViewModel.uiState.collectAsStateWithLifecycle()
+                val list by memoViewModel.memoList.collectAsStateWithLifecycle()
+
+                val isNavigateUpVisible = remember(windowAdaptiveInfo) {
+                    if (windowAdaptiveInfo.windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.EXPANDED) {
+                        !navigator.isDetailVisible()
+                    } else {
+                        true
+                    }
+                }
+
+                TagMemoScreen(
+                    state = rememberTagMemoScreenState(),
+                    navigateButtonProvider = {
+                        if (isNavigateUpVisible) {
+                            TagMemoNavigateButton.NavigateUp(onNavigateUp = navigator::navigateBack)
+                        } else {
+                            TagMemoNavigateButton.None
+                        }
+                    },
+                    uiStateProvider = { uiState },
+                    onAdd = { navigator.currentDestination?.content?.let(navigateToMemoAdd) },
+                    listProvider = { list },
+                    onMemo = navigateToMemoDetail,
+                )
+            }
+        },
+    )
+
+    LaunchedScaffoldValue(
+        navigator = navigator,
+        onScaffoldValueChange = onScaffoldValueChange,
+    )
+
+    LaunchedFetch(
+        navigator = navigator,
+        detailViewModel = detailViewModel,
+        memoViewModel = memoViewModel,
+    )
+
+    KBackHandler(
+        isEnabled = navigator.canNavigateBack(),
+        onBack = navigator::navigateBack,
+    )
 }
 
 @OptIn(ExperimentalMaterial3AdaptiveApi::class)
 @Composable
 private fun LaunchedFetch(
-	navigator: ThreePaneScaffoldNavigator<String?>,
-	detailViewModel: TagDetailViewModel,
+    navigator: ThreePaneScaffoldNavigator<String?>,
+    detailViewModel: TagDetailViewModel,
+    memoViewModel: TagMemoViewModel,
 ) {
-	LaunchedEffect(navigator.currentDestination?.content, detailViewModel) {
-		detailViewModel.fetch(navigator.currentDestination?.content)
-	}
+    LaunchedEffect(navigator.currentDestination?.content, detailViewModel) {
+        detailViewModel.fetch(navigator.currentDestination?.content)
+        memoViewModel.fetch(navigator.currentDestination?.content)
+    }
 }
 
 @OptIn(ExperimentalMaterial3AdaptiveApi::class)
 @Composable
 private fun LaunchedScaffoldValue(
-	navigator: ThreePaneScaffoldNavigator<String?>,
-	onScaffoldValueChange: (ThreePaneScaffoldValue) -> Unit,
+    navigator: ThreePaneScaffoldNavigator<String?>,
+    onScaffoldValueChange: (ThreePaneScaffoldValue) -> Unit,
 ) {
-	LaunchedEffect(navigator.scaffoldValue) {
-		onScaffoldValueChange(navigator.scaffoldValue)
-	}
+    LaunchedEffect(navigator.scaffoldValue) {
+        onScaffoldValueChange(navigator.scaffoldValue)
+    }
 }
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/add/TagAddRoute.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/add/TagAddRoute.kt
index 97b390c2..8aa0e745 100644
--- a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/add/TagAddRoute.kt
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/add/TagAddRoute.kt
@@ -7,6 +7,7 @@ import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaf
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import io.github.taetae98coding.diary.feature.tag.detail.TagDetailActionButton
 import io.github.taetae98coding.diary.feature.tag.detail.TagDetailFloatingButton
@@ -24,7 +25,7 @@ internal fun TagAddRoute(
 	val navigator = rememberListDetailPaneScaffoldNavigator()
 
 	ListDetailPaneScaffold(
-		directive = navigator.scaffoldDirective,
+		directive = navigator.scaffoldDirective.copy(defaultPanePreferredWidth = 500.dp),
 		value = navigator.scaffoldValue,
 		listPane = {
 			AnimatedPane {
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/add/TagAddViewModel.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/add/TagAddViewModel.kt
index 3baf723f..d673911a 100644
--- a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/add/TagAddViewModel.kt
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/add/TagAddViewModel.kt
@@ -13,7 +13,9 @@ import kotlinx.coroutines.launch
 import org.koin.android.annotation.KoinViewModel
 
 @KoinViewModel
-internal class TagAddViewModel(private val addTagUseCase: AddTagUseCase) : ViewModel() {
+internal class TagAddViewModel(
+	private val addTagUseCase: AddTagUseCase,
+) : ViewModel() {
 	private val _uiState = MutableStateFlow(TagDetailScreenUiState(onMessageShow = ::clearMessage))
 	val uiState = _uiState.asStateFlow()
 
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/RememberTagDetailScreenDetailState.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/RememberTagDetailScreenDetailState.kt
index ec6bbba2..2b124ee1 100644
--- a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/RememberTagDetailScreenDetailState.kt
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/RememberTagDetailScreenDetailState.kt
@@ -12,6 +12,7 @@ import io.github.taetae98coding.diary.core.model.tag.TagDetail
 internal fun rememberTagDetailScreenDetailState(
 	onUpdate: () -> Unit,
 	onDelete: () -> Unit,
+	onMemo: () -> Unit,
 	detailProvider: () -> TagDetail?,
 ): TagDetailScreenState.Detail {
 	val detail = detailProvider()
@@ -32,6 +33,7 @@ internal fun rememberTagDetailScreenDetailState(
 		TagDetailScreenState.Detail(
 			onUpdate = onUpdate,
 			onDelete = onDelete,
+			onMemo = onMemo,
 			coroutineScope = coroutineScope,
 			componentState = componentState,
 			colorState = colorState,
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailActionButton.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailActionButton.kt
index ffd8b182..2116362a 100644
--- a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailActionButton.kt
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailActionButton.kt
@@ -3,5 +3,9 @@ package io.github.taetae98coding.diary.feature.tag.detail
 internal sealed class TagDetailActionButton {
 	data object None : TagDetailActionButton()
 
-	data class FinishAndDetail(val isFinish: Boolean, val onFinishChange: (Boolean) -> Unit, val delete: () -> Unit) : TagDetailActionButton()
+	data class FinishAndDetail(
+		val isFinish: Boolean,
+		val onFinishChange: (Boolean) -> Unit,
+		val delete: () -> Unit,
+	) : TagDetailActionButton()
 }
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailFloatingButton.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailFloatingButton.kt
index c2fa677f..5e77de56 100644
--- a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailFloatingButton.kt
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailFloatingButton.kt
@@ -3,5 +3,7 @@ package io.github.taetae98coding.diary.feature.tag.detail
 internal sealed class TagDetailFloatingButton {
 	data object None : TagDetailFloatingButton()
 
-	data class Add(val onAdd: () -> Unit) : TagDetailFloatingButton()
+	data class Add(
+		val onAdd: () -> Unit,
+	) : TagDetailFloatingButton()
 }
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailNavigationButton.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailNavigationButton.kt
index 3c5ba3ec..a79b8477 100644
--- a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailNavigationButton.kt
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailNavigationButton.kt
@@ -3,5 +3,7 @@ package io.github.taetae98coding.diary.feature.tag.detail
 internal sealed class TagDetailNavigationButton {
 	data object None : TagDetailNavigationButton()
 
-	data class NavigateUp(val onNavigateUp: () -> Unit) : TagDetailNavigationButton()
+	data class NavigateUp(
+		val onNavigateUp: () -> Unit,
+	) : TagDetailNavigationButton()
 }
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailRoute.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailRoute.kt
index 6d80f0dd..ba884514 100644
--- a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailRoute.kt
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailRoute.kt
@@ -1,54 +1,98 @@
 package io.github.taetae98coding.diary.feature.tag.detail
 
 import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
+import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
 import androidx.compose.material3.adaptive.layout.AnimatedPane
 import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffold
+import androidx.compose.material3.adaptive.layout.ThreePaneScaffoldRole
+import androidx.compose.material3.adaptive.layout.calculatePaneScaffoldDirective
 import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import androidx.window.core.layout.WindowWidthSizeClass
+import io.github.taetae98coding.diary.core.compose.adaptive.isListVisible
+import io.github.taetae98coding.diary.feature.tag.memo.TagMemoNavigateButton
+import io.github.taetae98coding.diary.feature.tag.memo.TagMemoScreen
+import io.github.taetae98coding.diary.feature.tag.memo.TagMemoViewModel
+import io.github.taetae98coding.diary.feature.tag.memo.rememberTagMemoScreenState
 import org.koin.compose.viewmodel.koinViewModel
 
 @OptIn(ExperimentalMaterial3AdaptiveApi::class)
 @Composable
 internal fun TagDetailRoute(
-	navigateUp: () -> Unit,
-	modifier: Modifier = Modifier,
-	detailViewModel: TagDetailViewModel = koinViewModel(),
+    navigateUp: () -> Unit,
+    navigateToMemoAdd: () -> Unit,
+    navigateToMemoDetail: (String) -> Unit,
+    modifier: Modifier = Modifier,
+    detailViewModel: TagDetailViewModel = koinViewModel(),
+    memoViewModel: TagMemoViewModel = koinViewModel(),
 ) {
-	val navigator = rememberListDetailPaneScaffoldNavigator()
+    val windowAdaptiveInfo = currentWindowAdaptiveInfo()
+    val navigator = rememberListDetailPaneScaffoldNavigator(scaffoldDirective = calculatePaneScaffoldDirective(windowAdaptiveInfo))
 
-	ListDetailPaneScaffold(
-		directive = navigator.scaffoldDirective,
-		value = navigator.scaffoldValue,
-		listPane = {
-			AnimatedPane {
-				val tagDetail by detailViewModel.tagDetail.collectAsStateWithLifecycle()
-				val state = rememberTagDetailScreenDetailState(
-					onUpdate = navigateUp,
-					onDelete = navigateUp,
-					detailProvider = { tagDetail },
-				)
-				val actionButton by detailViewModel.actionButton.collectAsStateWithLifecycle()
-				val uiState by detailViewModel.uiState.collectAsStateWithLifecycle()
+    ListDetailPaneScaffold(
+        directive = navigator.scaffoldDirective.copy(defaultPanePreferredWidth = 500.dp),
+        value = navigator.scaffoldValue,
+        listPane = {
+            AnimatedPane {
+                val tagDetail by detailViewModel.tagDetail.collectAsStateWithLifecycle()
+                val state = rememberTagDetailScreenDetailState(
+                    onUpdate = navigateUp,
+                    onDelete = navigateUp,
+                    onMemo = { navigator.navigateTo(ThreePaneScaffoldRole.Primary) },
+                    detailProvider = { tagDetail },
+                )
+                val actionButton by detailViewModel.actionButton.collectAsStateWithLifecycle()
+                val uiState by detailViewModel.uiState.collectAsStateWithLifecycle()
 
-				TagDetailScreen(
-					state = state,
-					titleProvider = { tagDetail?.title },
-					navigateButtonProvider = {
-						TagDetailNavigationButton.NavigateUp(
-							onNavigateUp = { detailViewModel.update(state.tagDetail) },
-						)
-					},
-					actionButtonProvider = { actionButton },
-					floatingButtonProvider = { TagDetailFloatingButton.None },
-					uiStateProvider = { uiState },
-				)
-			}
-		},
-		detailPane = {
-		},
-		modifier = modifier,
-	)
+                TagDetailScreen(
+                    state = state,
+                    titleProvider = { tagDetail?.title },
+                    navigateButtonProvider = {
+                        TagDetailNavigationButton.NavigateUp(
+                            onNavigateUp = { detailViewModel.update(state.tagDetail) },
+                        )
+                    },
+                    actionButtonProvider = { actionButton },
+                    floatingButtonProvider = { TagDetailFloatingButton.None },
+                    uiStateProvider = { uiState },
+                )
+            }
+        },
+        detailPane = {
+            val isNavigateUpVisible by remember(windowAdaptiveInfo) {
+                derivedStateOf {
+                    if (windowAdaptiveInfo.windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.EXPANDED) {
+                        !navigator.isListVisible()
+                    } else {
+                        true
+                    }
+                }
+            }
+
+            val uiState by memoViewModel.uiState.collectAsStateWithLifecycle()
+            val list by memoViewModel.memoList.collectAsStateWithLifecycle()
+
+            TagMemoScreen(
+                state = rememberTagMemoScreenState(),
+                navigateButtonProvider = {
+                    if (isNavigateUpVisible) {
+                        TagMemoNavigateButton.NavigateUp(onNavigateUp = navigator::navigateBack)
+                    } else {
+                        TagMemoNavigateButton.None
+                    }
+                },
+                uiStateProvider = { uiState },
+                onAdd = navigateToMemoAdd,
+                listProvider = { list },
+                onMemo = navigateToMemoDetail,
+            )
+        },
+        modifier = modifier,
+    )
 }
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailScreen.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailScreen.kt
index f451179f..eb18f41b 100644
--- a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailScreen.kt
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailScreen.kt
@@ -6,14 +6,15 @@ import androidx.compose.animation.fadeOut
 import androidx.compose.animation.scaleIn
 import androidx.compose.animation.scaleOut
 import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.rememberScrollState
 import androidx.compose.foundation.verticalScroll
+import androidx.compose.material3.Card
 import androidx.compose.material3.ExperimentalMaterial3Api
 import androidx.compose.material3.IconButton
 import androidx.compose.material3.IconToggleButton
@@ -26,6 +27,7 @@ import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.unit.dp
 import io.github.taetae98coding.diary.core.compose.button.FloatingAddButton
@@ -132,7 +134,8 @@ internal fun TagDetailScreen(
 	) {
 		Content(
 			state = state,
-			modifier = Modifier.fillMaxSize()
+			modifier = Modifier
+				.fillMaxSize()
 				.padding(DiaryTheme.dimen.screenPaddingValues)
 				.padding(it),
 		)
@@ -211,19 +214,35 @@ private fun Content(
 	modifier: Modifier = Modifier,
 ) {
 	Column(
-		modifier = Modifier.verticalScroll(state = rememberScrollState())
+		modifier = Modifier
+			.verticalScroll(state = rememberScrollState())
 			.then(modifier),
 		verticalArrangement = Arrangement.spacedBy(DiaryTheme.dimen.itemSpace),
 	) {
 		DiaryComponent(state = state.componentState)
-		Row {
+		Row(horizontalArrangement = Arrangement.spacedBy(DiaryTheme.dimen.itemSpace)) {
 			DiaryColor(
 				state = state.colorState,
-				modifier = Modifier.weight(1F)
+				modifier = Modifier
+					.weight(1F)
 					.height(100.dp),
 			)
 
-			Spacer(modifier = Modifier.weight(1F))
+			if (state is TagDetailScreenState.Detail) {
+				Card(
+					onClick = state.onMemo,
+					modifier = Modifier
+						.weight(1F)
+						.height(100.dp),
+				) {
+					Box(
+						modifier = Modifier.fillMaxSize(),
+						contentAlignment = Alignment.Center,
+					) {
+						Text(text = "메모")
+					}
+				}
+			}
 		}
 	}
 }
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailScreenState.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailScreenState.kt
index bda9b279..fcc62c27 100644
--- a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailScreenState.kt
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailScreenState.kt
@@ -19,9 +19,20 @@ internal sealed class TagDetailScreenState {
 
 	val hostState: SnackbarHostState = SnackbarHostState()
 
-	data class Add(override val coroutineScope: CoroutineScope, override val componentState: DiaryComponentState, override val colorState: DiaryColorState) : TagDetailScreenState()
-
-	data class Detail(val onUpdate: () -> Unit, val onDelete: () -> Unit, override val coroutineScope: CoroutineScope, override val componentState: DiaryComponentState, override val colorState: DiaryColorState) : TagDetailScreenState()
+	data class Add(
+		override val coroutineScope: CoroutineScope,
+		override val componentState: DiaryComponentState,
+		override val colorState: DiaryColorState,
+	) : TagDetailScreenState()
+
+	data class Detail(
+		val onUpdate: () -> Unit,
+		val onDelete: () -> Unit,
+		val onMemo: () -> Unit,
+		override val coroutineScope: CoroutineScope,
+		override val componentState: DiaryComponentState,
+		override val colorState: DiaryColorState,
+	) : TagDetailScreenState()
 
 	val tagDetail: TagDetail
 		get() {
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailScreenUiState.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailScreenUiState.kt
index ee44c608..64fd3af0 100644
--- a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailScreenUiState.kt
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailScreenUiState.kt
@@ -1,5 +1,13 @@
 package io.github.taetae98coding.diary.feature.tag.detail
 
-internal data class TagDetailScreenUiState(val isProgress: Boolean = false, val isAdd: Boolean = false, val isDelete: Boolean = false, val isUpdate: Boolean = false, val isTitleBlankError: Boolean = false, val isUnknownError: Boolean = false, val onMessageShow: () -> Unit = {}) {
+internal data class TagDetailScreenUiState(
+	val isProgress: Boolean = false,
+	val isAdd: Boolean = false,
+	val isDelete: Boolean = false,
+	val isUpdate: Boolean = false,
+	val isTitleBlankError: Boolean = false,
+	val isUnknownError: Boolean = false,
+	val onMessageShow: () -> Unit = {},
+) {
 	val hasMessage = isAdd || isDelete || isUpdate || isTitleBlankError || isUnknownError
 }
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailViewModel.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailViewModel.kt
index df0699f2..9408acab 100644
--- a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailViewModel.kt
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/detail/TagDetailViewModel.kt
@@ -71,11 +71,11 @@ internal class TagDetailViewModel(
 				scope = viewModelScope,
 				started = SharingStarted.WhileSubscribed(5_000),
 				initialValue =
-				TagDetailActionButton.FinishAndDetail(
-					isFinish = false,
-					onFinishChange = ::onFinishChange,
-					delete = ::delete,
-				),
+					TagDetailActionButton.FinishAndDetail(
+						isFinish = false,
+						onFinishChange = ::onFinishChange,
+						delete = ::delete,
+					),
 			)
 
 	private fun onFinishChange(isFinish: Boolean) {
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/list/TagListFloatingButton.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/list/TagListFloatingButton.kt
index dd938a72..2958713e 100644
--- a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/list/TagListFloatingButton.kt
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/list/TagListFloatingButton.kt
@@ -3,5 +3,7 @@ package io.github.taetae98coding.diary.feature.tag.list
 internal sealed class TagListFloatingButton {
 	data object None : TagListFloatingButton()
 
-	data class Add(val onAdd: () -> Unit) : TagListFloatingButton()
+	data class Add(
+		val onAdd: () -> Unit,
+	) : TagListFloatingButton()
 }
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/list/TagListItemUiState.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/list/TagListItemUiState.kt
index d613088e..37d79eea 100644
--- a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/list/TagListItemUiState.kt
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/list/TagListItemUiState.kt
@@ -2,4 +2,9 @@ package io.github.taetae98coding.diary.feature.tag.list
 
 import io.github.taetae98coding.diary.core.compose.runtime.SkipProperty
 
-internal data class TagListItemUiState(val id: String, val title: String, val finish: SkipProperty<() -> Unit>, val delete: SkipProperty<() -> Unit>)
+internal data class TagListItemUiState(
+	val id: String,
+	val title: String,
+	val finish: SkipProperty<() -> Unit>,
+	val delete: SkipProperty<() -> Unit>,
+)
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/list/TagListScreen.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/list/TagListScreen.kt
index ac9eae39..cf346b4d 100644
--- a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/list/TagListScreen.kt
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/list/TagListScreen.kt
@@ -31,164 +31,169 @@ import io.github.taetae98coding.diary.core.design.system.theme.DiaryTheme
 @OptIn(ExperimentalMaterial3Api::class)
 @Composable
 internal fun TagListScreen(
-	state: TagListScreenState,
-	floatingButtonProvider: () -> TagListFloatingButton,
-	listProvider: () -> List<TagListItemUiState>?,
-	onTag: (String) -> Unit,
-	uiStateProvider: () -> TagListScreenUiState,
-	modifier: Modifier = Modifier,
+    state: TagListScreenState,
+    floatingButtonProvider: () -> TagListFloatingButton,
+    listProvider: () -> List<TagListItemUiState>?,
+    onTag: (String) -> Unit,
+    uiStateProvider: () -> TagListScreenUiState,
+    modifier: Modifier = Modifier,
 ) {
-	Scaffold(
-		modifier = modifier,
-		topBar = {
-			TopAppBar(
-				title = { Text(text = "태그") },
-			)
-		},
-		snackbarHost = { SnackbarHost(hostState = state.hostState) },
-		floatingActionButton = {
-			val button = floatingButtonProvider()
+    Scaffold(
+        modifier = modifier,
+        topBar = {
+            TopAppBar(
+                title = { Text(text = "태그") },
+            )
+        },
+        snackbarHost = { SnackbarHost(hostState = state.hostState) },
+        floatingActionButton = {
+            val button = floatingButtonProvider()
 
-			AnimatedVisibility(
-				visible = button is TagListFloatingButton.Add,
-				enter = scaleIn(),
-				exit = scaleOut(),
-			) {
-				FloatingAddButton(
-					onClick = {
-						if (button is TagListFloatingButton.Add) {
-							button.onAdd()
-						}
-					},
-				)
-			}
-		},
-	) {
-		Content(
-			listProvider = listProvider,
-			onTag = onTag,
-			modifier = Modifier.fillMaxSize()
-				.padding(it),
-		)
-	}
+            AnimatedVisibility(
+                visible = button is TagListFloatingButton.Add,
+                enter = scaleIn(),
+                exit = scaleOut(),
+            ) {
+                FloatingAddButton(
+                    onClick = {
+                        if (button is TagListFloatingButton.Add) {
+                            button.onAdd()
+                        }
+                    },
+                )
+            }
+        },
+    ) {
+        Content(
+            listProvider = listProvider,
+            onTag = onTag,
+            modifier = Modifier
+                .fillMaxSize()
+                .padding(it),
+        )
+    }
 
-	Message(
-		state = state,
-		uiStateProvider = uiStateProvider,
-	)
+    Message(
+        state = state,
+        uiStateProvider = uiStateProvider,
+    )
 }
 
 @Composable
 private fun Message(
-	state: TagListScreenState,
-	uiStateProvider: () -> TagListScreenUiState,
+    state: TagListScreenState,
+    uiStateProvider: () -> TagListScreenUiState,
 ) {
-	val uiState = uiStateProvider()
+    val uiState = uiStateProvider()
 
-	LaunchedEffect(
-		uiState.finishTagId,
-		uiState.deleteTagId,
-		uiState.isUnknownError,
-	) {
-		if (!uiState.hasMessage) return@LaunchedEffect
+    LaunchedEffect(
+        uiState.finishTagId,
+        uiState.deleteTagId,
+        uiState.isUnknownError,
+    ) {
+        if (!uiState.hasMessage) return@LaunchedEffect
 
-		when {
-			!uiState.finishTagId.isNullOrBlank() -> {
-				state.showMessage(
-					message = "태그 완료 ${Emoji.congratulate.random()}",
-					actionLabel = "취소",
-				) {
-					uiState.restartTag(uiState.finishTagId)
-				}
-			}
+        when {
+            !uiState.finishTagId.isNullOrBlank() -> {
+                state.showMessage(
+                    message = "태그 완료 ${Emoji.congratulate.random()}",
+                    actionLabel = "취소",
+                ) {
+                    uiState.restartTag(uiState.finishTagId)
+                }
+            }
 
-			!uiState.deleteTagId.isNullOrBlank() -> {
-				state.showMessage(
-					message = "태그 삭제 ${Emoji.congratulate.random()}",
-					actionLabel = "취소",
-				) {
-					uiState.restoreTag(uiState.deleteTagId)
-				}
-			}
+            !uiState.deleteTagId.isNullOrBlank() -> {
+                state.showMessage(
+                    message = "태그 삭제 ${Emoji.congratulate.random()}",
+                    actionLabel = "취소",
+                ) {
+                    uiState.restoreTag(uiState.deleteTagId)
+                }
+            }
 
-			uiState.isUnknownError -> state.showMessage("알 수 없는 에러가 발생했어요 잠시 후 다시 시도해 주세요 ${Emoji.error.random()}")
-		}
+            uiState.isUnknownError -> state.showMessage("알 수 없는 에러가 발생했어요 잠시 후 다시 시도해 주세요 ${Emoji.error.random()}")
+        }
 
-		uiState.onMessageShow()
-	}
+        uiState.onMessageShow()
+    }
 }
 
 @Composable
 private fun Content(
-	listProvider: () -> List<TagListItemUiState>?,
-	onTag: (String) -> Unit,
-	modifier: Modifier = Modifier,
+    listProvider: () -> List<TagListItemUiState>?,
+    onTag: (String) -> Unit,
+    modifier: Modifier = Modifier,
 ) {
-	val isLoading by remember { derivedStateOf { listProvider() == null } }
-	val isEmpty by remember { derivedStateOf { !isLoading && listProvider().isNullOrEmpty() } }
+    val isLoading by remember { derivedStateOf { listProvider() == null } }
+    val isEmpty by remember { derivedStateOf { !isLoading && listProvider().isNullOrEmpty() } }
 
-	if (isEmpty) {
-		Box(
-			modifier = modifier,
-			contentAlignment = Alignment.Center,
-		) {
-			Text(
-				text = "태그가 없어요 🐼",
-				style = DiaryTheme.typography.headlineMedium,
-			)
-		}
-	} else {
-		LazyColumn(
-			modifier = modifier,
-			contentPadding = DiaryTheme.dimen.screenPaddingValues,
-			verticalArrangement = Arrangement.spacedBy(DiaryTheme.dimen.itemSpace),
-		) {
-			if (isLoading) {
-				items(
-					count = 5,
-					contentType = { "Tag" },
-				) {
-					TagItem(
-						uiState = null,
-						onClick = {},
-					)
-				}
-			} else {
-				items(
-					items = listProvider().orEmpty(),
-					key = { it.id },
-					contentType = { "Tag" },
-				) {
-					TagItem(
-						uiState = it,
-						onClick = { onTag(it.id) },
-						modifier = Modifier.animateItem(),
-					)
-				}
-			}
-		}
-	}
+    if (isEmpty) {
+        Box(
+            modifier = modifier,
+            contentAlignment = Alignment.Center,
+        ) {
+            Text(
+                text = "태그가 없어요 🐼",
+                style = DiaryTheme.typography.headlineMedium,
+            )
+        }
+    } else {
+        LazyColumn(
+            modifier = modifier,
+            contentPadding = DiaryTheme.dimen.screenPaddingValues,
+            verticalArrangement = Arrangement.spacedBy(DiaryTheme.dimen.itemSpace),
+        ) {
+            if (isLoading) {
+                items(
+                    count = 5,
+                    contentType = { "Tag" },
+                ) {
+                    TagItem(
+                        uiState = null,
+                        onClick = {},
+                    )
+                }
+            } else {
+                items(
+                    items = listProvider().orEmpty(),
+                    key = { it.id },
+                    contentType = { "Tag" },
+                ) {
+                    TagItem(
+                        uiState = it,
+                        onClick = { onTag(it.id) },
+                        modifier = Modifier.animateItem(),
+                    )
+                }
+            }
+        }
+    }
 }
 
 @Composable
 private fun TagItem(
-	uiState: TagListItemUiState?,
-	onClick: () -> Unit,
-	modifier: Modifier = Modifier,
+    uiState: TagListItemUiState?,
+    onClick: () -> Unit,
+    modifier: Modifier = Modifier,
 ) {
-	FinishAndDeleteSwipeBox(
-		modifier = modifier,
-		onFinish = { uiState?.finish?.value?.invoke() },
-		onDelete = { uiState?.delete?.value?.invoke() },
-	) {
-		Card(onClick = onClick) {
-			Box(
-				modifier = Modifier.fillMaxSize()
-					.padding(16.dp),
-				contentAlignment = Alignment.Center,
-			) {
-				Text(text = uiState?.title.orEmpty())
-			}
-		}
-	}
+    FinishAndDeleteSwipeBox(
+        modifier = modifier,
+        onFinish = { uiState?.finish?.value?.invoke() },
+        onDelete = { uiState?.delete?.value?.invoke() },
+    ) {
+        Card(onClick = onClick) {
+            Box(
+                modifier = Modifier
+                    .fillMaxSize()
+                    .padding(16.dp),
+                contentAlignment = Alignment.Center,
+            ) {
+                Text(
+                    text = uiState?.title.orEmpty(),
+                    style = DiaryTheme.typography.titleLarge,
+                )
+            }
+        }
+    }
 }
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/list/TagListScreenState.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/list/TagListScreenState.kt
index 63c1af2c..4d095a10 100644
--- a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/list/TagListScreenState.kt
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/list/TagListScreenState.kt
@@ -8,7 +8,9 @@ import kotlinx.coroutines.Job
 import kotlinx.coroutines.isActive
 import kotlinx.coroutines.launch
 
-internal class TagListScreenState(private val coroutineScope: CoroutineScope) {
+internal class TagListScreenState(
+	private val coroutineScope: CoroutineScope,
+) {
 	private var messageJob: Job? = null
 
 	val hostState: SnackbarHostState = SnackbarHostState()
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/list/TagListScreenUiState.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/list/TagListScreenUiState.kt
index e8d91c90..bd7ea03a 100644
--- a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/list/TagListScreenUiState.kt
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/list/TagListScreenUiState.kt
@@ -1,5 +1,12 @@
 package io.github.taetae98coding.diary.feature.tag.list
 
-internal data class TagListScreenUiState(val finishTagId: String? = null, val deleteTagId: String? = null, val isUnknownError: Boolean = false, val restartTag: (String) -> Unit = {}, val restoreTag: (String) -> Unit = {}, val onMessageShow: () -> Unit = {}) {
+internal data class TagListScreenUiState(
+	val finishTagId: String? = null,
+	val deleteTagId: String? = null,
+	val isUnknownError: Boolean = false,
+	val restartTag: (String) -> Unit = {},
+	val restoreTag: (String) -> Unit = {},
+	val onMessageShow: () -> Unit = {},
+) {
 	val hasMessage = !finishTagId.isNullOrBlank() || !deleteTagId.isNullOrBlank() || isUnknownError
 }
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/list/TagListViewModel.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/list/TagListViewModel.kt
index 57b2f346..7cb9a76e 100644
--- a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/list/TagListViewModel.kt
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/list/TagListViewModel.kt
@@ -21,7 +21,13 @@ import org.koin.android.annotation.KoinViewModel
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @KoinViewModel
-internal class TagListViewModel(pageTagUseCase: PageTagUseCase, private val finishTagUseCase: FinishTagUseCase, private val deleteTagUseCase: DeleteTagUseCase, private val restartTagUseCase: RestartTagUseCase, private val restoreTagUseCase: RestoreTagUseCase) : ViewModel() {
+internal class TagListViewModel(
+	pageTagUseCase: PageTagUseCase,
+	private val finishTagUseCase: FinishTagUseCase,
+	private val deleteTagUseCase: DeleteTagUseCase,
+	private val restartTagUseCase: RestartTagUseCase,
+	private val restoreTagUseCase: RestoreTagUseCase,
+) : ViewModel() {
 	private val _uiState =
 		MutableStateFlow(
 			TagListScreenUiState(
@@ -48,18 +54,18 @@ internal class TagListViewModel(pageTagUseCase: PageTagUseCase, private val fini
 				initialValue = null,
 			)
 
-	private fun finish(id: String) {
+	private fun finish(tagId: String) {
 		viewModelScope.launch {
-			finishTagUseCase(id)
-				.onSuccess { _uiState.update { it.copy(finishTagId = id) } }
+			finishTagUseCase(tagId)
+				.onSuccess { _uiState.update { it.copy(finishTagId = tagId) } }
 				.onFailure { _uiState.update { it.copy(isUnknownError = true) } }
 		}
 	}
 
-	private fun delete(id: String) {
+	private fun delete(tagId: String) {
 		viewModelScope.launch {
-			deleteTagUseCase(id)
-				.onSuccess { _uiState.update { it.copy(deleteTagId = id) } }
+			deleteTagUseCase(tagId)
+				.onSuccess { _uiState.update { it.copy(deleteTagId = tagId) } }
 				.onFailure { _uiState.update { it.copy(isUnknownError = true) } }
 		}
 	}
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/memo/MemoListItemUiState.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/memo/MemoListItemUiState.kt
new file mode 100644
index 00000000..c261b49d
--- /dev/null
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/memo/MemoListItemUiState.kt
@@ -0,0 +1,12 @@
+package io.github.taetae98coding.diary.feature.tag.memo
+
+import io.github.taetae98coding.diary.core.compose.runtime.SkipProperty
+import kotlinx.datetime.LocalDate
+
+internal data class MemoListItemUiState(
+    val id: String,
+    val title: String,
+    val dateRange: ClosedRange<LocalDate>?,
+    val finish: SkipProperty<() -> Unit>,
+    val delete: SkipProperty<() -> Unit>,
+)
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/memo/RememberTagMemoScreenState.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/memo/RememberTagMemoScreenState.kt
new file mode 100644
index 00000000..ee8026dd
--- /dev/null
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/memo/RememberTagMemoScreenState.kt
@@ -0,0 +1,14 @@
+package io.github.taetae98coding.diary.feature.tag.memo
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
+
+@Composable
+internal fun rememberTagMemoScreenState(): TagMemoScreenState {
+    val coroutineScope = rememberCoroutineScope()
+
+    return remember {
+        TagMemoScreenState(coroutineScope = coroutineScope)
+    }
+}
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/memo/TagMemoNavigateButton.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/memo/TagMemoNavigateButton.kt
new file mode 100644
index 00000000..5eea12e1
--- /dev/null
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/memo/TagMemoNavigateButton.kt
@@ -0,0 +1,9 @@
+package io.github.taetae98coding.diary.feature.tag.memo
+
+internal sealed class TagMemoNavigateButton {
+	data object None : TagMemoNavigateButton()
+
+	data class NavigateUp(
+		val onNavigateUp: () -> Unit,
+	) : TagMemoNavigateButton()
+}
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/memo/TagMemoScreen.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/memo/TagMemoScreen.kt
new file mode 100644
index 00000000..c1ce1e9c
--- /dev/null
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/memo/TagMemoScreen.kt
@@ -0,0 +1,207 @@
+package io.github.taetae98coding.diary.feature.tag.memo
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.items
+import androidx.compose.material3.Card
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.LocalContentColor
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.SnackbarHost
+import androidx.compose.material3.Text
+import androidx.compose.material3.TopAppBar
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import io.github.taetae98coding.diary.core.compose.button.FloatingAddButton
+import io.github.taetae98coding.diary.core.compose.swipe.FinishAndDeleteSwipeBox
+import io.github.taetae98coding.diary.core.design.system.emoji.Emoji
+import io.github.taetae98coding.diary.core.design.system.icon.NavigateUpIcon
+import io.github.taetae98coding.diary.core.design.system.theme.DiaryTheme
+import io.github.taetae98coding.diary.library.color.multiplyAlpha
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+internal fun TagMemoScreen(
+    state: TagMemoScreenState,
+    navigateButtonProvider: () -> TagMemoNavigateButton,
+    uiStateProvider: () -> TagMemoScreenUiState,
+    onAdd: () -> Unit,
+    listProvider: () -> List<MemoListItemUiState>?,
+    onMemo: (String) -> Unit,
+    modifier: Modifier = Modifier,
+) {
+    Scaffold(
+        modifier = modifier,
+        topBar = {
+            TopAppBar(
+                title = { },
+                navigationIcon = {
+                    when (val button = navigateButtonProvider()) {
+                        is TagMemoNavigateButton.NavigateUp -> {
+                            IconButton(onClick = button.onNavigateUp) {
+                                NavigateUpIcon()
+                            }
+                        }
+
+                        is TagMemoNavigateButton.None -> Unit
+                    }
+                },
+            )
+        },
+        snackbarHost = { SnackbarHost(hostState = state.hostState) },
+        floatingActionButton = { FloatingAddButton(onClick = onAdd) }
+    ) {
+        Content(
+            listProvider = listProvider,
+            onMemo = onMemo,
+            modifier = Modifier
+                .fillMaxSize()
+                .padding(it),
+        )
+    }
+
+    Message(
+        state = state,
+        uiStateProvider = uiStateProvider,
+    )
+}
+
+@Composable
+private fun Message(
+    state: TagMemoScreenState,
+    uiStateProvider: () -> TagMemoScreenUiState,
+) {
+    val uiState = uiStateProvider()
+
+    LaunchedEffect(
+        uiState.finishTagId,
+        uiState.deleteTagId,
+        uiState.isUnknownError,
+    ) {
+        if (!uiState.hasMessage) return@LaunchedEffect
+
+        when {
+            !uiState.finishTagId.isNullOrBlank() -> {
+                state.showMessage(
+                    message = "메모 완료 ${Emoji.congratulate.random()}",
+                    actionLabel = "취소",
+                ) {
+                    uiState.restartTag(uiState.finishTagId)
+                }
+            }
+
+            !uiState.deleteTagId.isNullOrBlank() -> {
+                state.showMessage(
+                    message = "메모 삭제 ${Emoji.congratulate.random()}",
+                    actionLabel = "취소",
+                ) {
+                    uiState.restoreTag(uiState.deleteTagId)
+                }
+            }
+
+            uiState.isUnknownError -> state.showMessage("알 수 없는 에러가 발생했어요 잠시 후 다시 시도해 주세요 ${Emoji.error.random()}")
+        }
+
+        uiState.onMessageShow()
+    }
+}
+
+@Composable
+private fun Content(
+    listProvider: () -> List<MemoListItemUiState>?,
+    onMemo: (String) -> Unit,
+    modifier: Modifier = Modifier,
+) {
+    val isLoading by remember { derivedStateOf { listProvider() == null } }
+    val isEmpty by remember { derivedStateOf { !isLoading && listProvider().isNullOrEmpty() } }
+
+    if (isEmpty) {
+        Box(
+            modifier = modifier,
+            contentAlignment = Alignment.Center,
+        ) {
+            Text(
+                text = "메모가 없어요 🐰",
+                style = DiaryTheme.typography.headlineMedium,
+            )
+        }
+    } else {
+        LazyColumn(
+            modifier = modifier,
+            contentPadding = DiaryTheme.dimen.screenPaddingValues,
+            verticalArrangement = Arrangement.spacedBy(DiaryTheme.dimen.itemSpace),
+        ) {
+            if (isLoading) {
+                items(
+                    count = 5,
+                    contentType = { "Tag" },
+                ) {
+                    MemoItem(
+                        uiState = null,
+                        onClick = {},
+                    )
+                }
+            } else {
+                items(
+                    items = listProvider().orEmpty(),
+                    key = { it.id },
+                    contentType = { "Tag" },
+                ) {
+                    MemoItem(
+                        uiState = it,
+                        onClick = { onMemo(it.id) },
+                        modifier = Modifier.animateItem(),
+                    )
+                }
+            }
+        }
+    }
+}
+
+@Composable
+private fun MemoItem(
+    uiState: MemoListItemUiState?,
+    onClick: () -> Unit,
+    modifier: Modifier = Modifier,
+) {
+    FinishAndDeleteSwipeBox(
+        modifier = modifier,
+        onFinish = { uiState?.finish?.value?.invoke() },
+        onDelete = { uiState?.delete?.value?.invoke() },
+    ) {
+        Card(onClick = onClick) {
+            Column(
+                modifier = Modifier
+                    .fillMaxSize()
+                    .padding(16.dp),
+            ) {
+                MaterialTheme.typography.bodySmall
+                Text(
+                    text = uiState?.title.orEmpty(),
+                    style = DiaryTheme.typography.titleLarge,
+                )
+                if (uiState?.dateRange != null) {
+                    Text(
+                        text = listOf(uiState.dateRange.start, uiState.dateRange.endInclusive)
+                            .distinct()
+                            .joinToString(separator = " ~ "),
+                        color = LocalContentColor.current.multiplyAlpha(0.5F),
+                        style = DiaryTheme.typography.labelSmall,
+                    )
+                }
+            }
+        }
+    }
+}
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/memo/TagMemoScreenState.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/memo/TagMemoScreenState.kt
new file mode 100644
index 00000000..70a24a05
--- /dev/null
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/memo/TagMemoScreenState.kt
@@ -0,0 +1,45 @@
+package io.github.taetae98coding.diary.feature.tag.memo
+
+import androidx.compose.material3.SnackbarDuration
+import androidx.compose.material3.SnackbarHostState
+import androidx.compose.material3.SnackbarResult
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.isActive
+import kotlinx.coroutines.launch
+
+internal class TagMemoScreenState(
+    private val coroutineScope: CoroutineScope,
+) {
+    private var messageJob: Job? = null
+
+    val hostState: SnackbarHostState = SnackbarHostState()
+
+    fun showMessage(
+        message: String,
+        actionLabel: String,
+        onResult: (SnackbarResult) -> Unit,
+    ) {
+        messageJob?.cancel()
+        messageJob =
+            coroutineScope.launch {
+                val result =
+                    hostState.showSnackbar(
+                        message = message,
+                        actionLabel = actionLabel,
+                        duration = SnackbarDuration.Long,
+                    )
+
+                if (isActive) {
+                    onResult(result)
+                }
+            }
+    }
+
+    fun showMessage(
+        message: String,
+    ) {
+        messageJob?.cancel()
+        messageJob = coroutineScope.launch { hostState.showSnackbar(message = message) }
+    }
+}
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/memo/TagMemoScreenUiState.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/memo/TagMemoScreenUiState.kt
new file mode 100644
index 00000000..dd541986
--- /dev/null
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/memo/TagMemoScreenUiState.kt
@@ -0,0 +1,12 @@
+package io.github.taetae98coding.diary.feature.tag.memo
+
+internal data class TagMemoScreenUiState(
+    val finishTagId: String? = null,
+    val deleteTagId: String? = null,
+    val isUnknownError: Boolean = false,
+    val restartTag: (String) -> Unit = {},
+    val restoreTag: (String) -> Unit = {},
+    val onMessageShow: () -> Unit = {},
+) {
+    val hasMessage = !finishTagId.isNullOrBlank() || !deleteTagId.isNullOrBlank() || isUnknownError
+}
diff --git a/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/memo/TagMemoViewModel.kt b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/memo/TagMemoViewModel.kt
new file mode 100644
index 00000000..c0ba1f51
--- /dev/null
+++ b/app/feature/tag/src/commonMain/kotlin/io/github/taetae98coding/diary/feature/tag/memo/TagMemoViewModel.kt
@@ -0,0 +1,114 @@
+package io.github.taetae98coding.diary.feature.tag.memo
+
+import androidx.lifecycle.SavedStateHandle
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import io.github.taetae98coding.diary.core.compose.runtime.SkipProperty
+import io.github.taetae98coding.diary.core.navigation.tag.TagDetailDestination
+import io.github.taetae98coding.diary.domain.memo.usecase.DeleteMemoUseCase
+import io.github.taetae98coding.diary.domain.memo.usecase.FinishMemoUseCase
+import io.github.taetae98coding.diary.domain.memo.usecase.RestartMemoUseCase
+import io.github.taetae98coding.diary.domain.memo.usecase.RestoreMemoUseCase
+import io.github.taetae98coding.diary.domain.tag.usecase.PageTagMemoUseCase
+import io.github.taetae98coding.diary.library.coroutines.mapCollectionLatest
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.mapLatest
+import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.flow.update
+import kotlinx.coroutines.launch
+import org.koin.android.annotation.KoinViewModel
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@KoinViewModel
+internal class TagMemoViewModel(
+    private val savedStateHandle: SavedStateHandle,
+    private val pageTagMemoUseCase: PageTagMemoUseCase,
+    private val finishMemoUseCase: FinishMemoUseCase,
+    private val deleteMemoUseCase: DeleteMemoUseCase,
+    private val restartMemoUseCase: RestartMemoUseCase,
+    private val restoreMemoUseCase: RestoreMemoUseCase,
+) : ViewModel() {
+    private val tagId = savedStateHandle.getStateFlow<String?>(TagDetailDestination.TAG_ID, null)
+
+    private val _uiState =
+        MutableStateFlow(
+            TagMemoScreenUiState(
+                restartTag = ::restart,
+                restoreTag = ::restore,
+                onMessageShow = ::clearMessage,
+            ),
+        )
+    val uiState = _uiState.asStateFlow()
+
+
+    val memoList = tagId
+        .flatMapLatest { pageTagMemoUseCase(it) }
+        .mapLatest { it.getOrNull() }
+        .mapCollectionLatest {
+            val start = it.detail.start
+            val endInclusive = it.detail.endInclusive
+
+            MemoListItemUiState(
+                id = it.id,
+                title = it.detail.title,
+                dateRange = if (start != null && endInclusive != null) {
+                    start..endInclusive
+                } else {
+                    null
+                },
+                finish = SkipProperty { finish(it.id) },
+                delete = SkipProperty { delete(it.id) },
+            )
+        }
+        .stateIn(
+            scope = viewModelScope,
+            started = SharingStarted.WhileSubscribed(5_000),
+            initialValue = null,
+        )
+
+    private fun finish(memoId: String) {
+        viewModelScope.launch {
+            finishMemoUseCase(memoId)
+                .onSuccess { _uiState.update { it.copy(finishTagId = memoId) } }
+                .onFailure { _uiState.update { it.copy(isUnknownError = true) } }
+        }
+    }
+
+    private fun delete(memoId: String) {
+        viewModelScope.launch {
+            deleteMemoUseCase(memoId)
+                .onSuccess { _uiState.update { it.copy(deleteTagId = memoId) } }
+                .onFailure { _uiState.update { it.copy(isUnknownError = true) } }
+        }
+    }
+
+    private fun restart(id: String) {
+        viewModelScope.launch {
+            restartMemoUseCase(id)
+        }
+    }
+
+    private fun restore(id: String) {
+        viewModelScope.launch {
+            restoreMemoUseCase(id)
+        }
+    }
+
+    private fun clearMessage() {
+        _uiState.update {
+            it.copy(
+                finishTagId = null,
+                deleteTagId = null,
+                isUnknownError = false,
+            )
+        }
+    }
+
+    fun fetch(tagId: String?) {
+        savedStateHandle[TagDetailDestination.TAG_ID] = tagId
+    }
+}
diff --git a/app/platform/android/build.gradle.kts b/app/platform/android/build.gradle.kts
index 172f58fc..6c976713 100644
--- a/app/platform/android/build.gradle.kts
+++ b/app/platform/android/build.gradle.kts
@@ -35,8 +35,8 @@ android {
     defaultConfig {
         applicationId = "io.github.taetae98coding.diary"
 
-        versionCode = 4
-        versionName = "1.2.1"
+        versionCode = 5
+        versionName = "1.2.2"
     }
 
     buildTypes {
diff --git a/app/platform/android/src/main/kotlin/io/github/taetae98coding/diary/notification/DefaultNotificationManager.kt b/app/platform/android/src/main/kotlin/io/github/taetae98coding/diary/notification/DefaultNotificationManager.kt
index e8a7a494..7b142149 100644
--- a/app/platform/android/src/main/kotlin/io/github/taetae98coding/diary/notification/DefaultNotificationManager.kt
+++ b/app/platform/android/src/main/kotlin/io/github/taetae98coding/diary/notification/DefaultNotificationManager.kt
@@ -7,11 +7,13 @@ import androidx.core.app.NotificationChannelCompat
 import androidx.core.app.NotificationCompat
 import androidx.core.app.NotificationManagerCompat
 import io.github.taetae98coding.diary.R
-import kotlin.math.abs
 import org.koin.core.annotation.Factory
+import kotlin.math.abs
 
 @Factory
-internal class DefaultNotificationManager(private val context: Context) {
+internal class DefaultNotificationManager(
+	private val context: Context,
+) {
 	fun notify(title: String, description: String?) {
 		if (context.checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) return
 
diff --git a/app/platform/common/src/commonMain/kotlin/io/github/taetae98coding/diary/app/App.kt b/app/platform/common/src/commonMain/kotlin/io/github/taetae98coding/diary/app/App.kt
index a122ce84..8c17a3f2 100644
--- a/app/platform/common/src/commonMain/kotlin/io/github/taetae98coding/diary/app/App.kt
+++ b/app/platform/common/src/commonMain/kotlin/io/github/taetae98coding/diary/app/App.kt
@@ -38,7 +38,8 @@ import kotlinx.coroutines.flow.flowOf
 public fun App() {
 	DiaryTheme {
 		AppScaffold(
-			modifier = Modifier.fillMaxSize()
+			modifier = Modifier
+				.fillMaxSize()
 				.imePadding(),
 		)
 	}
@@ -62,7 +63,8 @@ private fun AppScaffold(
 			)
 
 			isNavigationVisibleFromBackStackEntry ?: visibleDestination.any {
-				backStackEntry?.destination
+				backStackEntry
+					?.destination
 					?.hasRoute(it)
 					?: false
 			}
@@ -77,7 +79,8 @@ private fun AppScaffold(
 				AppNavigation.Calendar,
 				AppNavigation.More,
 			).forEach { navigation ->
-				val isSelected = backStackEntry?.destination
+				val isSelected = backStackEntry
+					?.destination
 					?.hierarchy
 					?.any { it.hasRoute(navigation.route::class) }
 					?: false
diff --git a/app/platform/common/src/commonMain/kotlin/io/github/taetae98coding/diary/app/manager/BackupManager.kt b/app/platform/common/src/commonMain/kotlin/io/github/taetae98coding/diary/app/manager/BackupManager.kt
index 5ab8cfa5..cb4e1d69 100644
--- a/app/platform/common/src/commonMain/kotlin/io/github/taetae98coding/diary/app/manager/BackupManager.kt
+++ b/app/platform/common/src/commonMain/kotlin/io/github/taetae98coding/diary/app/manager/BackupManager.kt
@@ -9,7 +9,9 @@ import kotlinx.coroutines.launch
 import org.koin.core.annotation.Singleton
 
 @Singleton
-public class BackupManager(private val backupUseCase: BackupUseCase) {
+public class BackupManager(
+	private val backupUseCase: BackupUseCase,
+) {
 	public fun attach(lifecycleOwner: LifecycleOwner) {
 		lifecycleOwner.lifecycleScope.launch {
 			lifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) {
diff --git a/app/platform/common/src/commonMain/kotlin/io/github/taetae98coding/diary/app/manager/FCMManager.kt b/app/platform/common/src/commonMain/kotlin/io/github/taetae98coding/diary/app/manager/FCMManager.kt
index 06f6df0b..dc50c1b0 100644
--- a/app/platform/common/src/commonMain/kotlin/io/github/taetae98coding/diary/app/manager/FCMManager.kt
+++ b/app/platform/common/src/commonMain/kotlin/io/github/taetae98coding/diary/app/manager/FCMManager.kt
@@ -9,7 +9,9 @@ import kotlinx.coroutines.launch
 import org.koin.core.annotation.Singleton
 
 @Singleton
-public class FCMManager internal constructor(private val updateFCMTokenUseCase: UpdateFCMTokenUseCase) {
+public class FCMManager internal constructor(
+	private val updateFCMTokenUseCase: UpdateFCMTokenUseCase,
+) {
 	public fun attach(lifecycleOwner: LifecycleOwner) {
 		lifecycleOwner.lifecycleScope.launch {
 			lifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) {
diff --git a/app/platform/common/src/commonMain/kotlin/io/github/taetae98coding/diary/app/manager/FetchManager.kt b/app/platform/common/src/commonMain/kotlin/io/github/taetae98coding/diary/app/manager/FetchManager.kt
index b4543799..3d4a5c2f 100644
--- a/app/platform/common/src/commonMain/kotlin/io/github/taetae98coding/diary/app/manager/FetchManager.kt
+++ b/app/platform/common/src/commonMain/kotlin/io/github/taetae98coding/diary/app/manager/FetchManager.kt
@@ -9,7 +9,9 @@ import kotlinx.coroutines.launch
 import org.koin.core.annotation.Singleton
 
 @Singleton
-public class FetchManager(private val fetchUseCase: FetchUseCase) {
+public class FetchManager(
+	private val fetchUseCase: FetchUseCase,
+) {
 	public fun attach(lifecycleOwner: LifecycleOwner) {
 		lifecycleOwner.lifecycleScope.launch {
 			lifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) {
diff --git a/app/platform/common/src/commonMain/kotlin/io/github/taetae98coding/diary/app/navigation/AppNavigation.kt b/app/platform/common/src/commonMain/kotlin/io/github/taetae98coding/diary/app/navigation/AppNavigation.kt
index 30980511..46ec66a5 100644
--- a/app/platform/common/src/commonMain/kotlin/io/github/taetae98coding/diary/app/navigation/AppNavigation.kt
+++ b/app/platform/common/src/commonMain/kotlin/io/github/taetae98coding/diary/app/navigation/AppNavigation.kt
@@ -5,7 +5,10 @@ import io.github.taetae98coding.diary.core.navigation.memo.MemoDestination
 import io.github.taetae98coding.diary.core.navigation.more.MoreDestination
 import io.github.taetae98coding.diary.core.navigation.tag.TagDestination
 
-internal enum class AppNavigation(val title: String, val route: Any) {
+internal enum class AppNavigation(
+	val title: String,
+	val route: Any,
+) {
 	Memo(
 		title = "메모",
 		route = MemoDestination,
diff --git a/app/platform/common/src/commonMain/kotlin/io/github/taetae98coding/diary/app/state/AppState.kt b/app/platform/common/src/commonMain/kotlin/io/github/taetae98coding/diary/app/state/AppState.kt
index 56764c9a..353992db 100644
--- a/app/platform/common/src/commonMain/kotlin/io/github/taetae98coding/diary/app/state/AppState.kt
+++ b/app/platform/common/src/commonMain/kotlin/io/github/taetae98coding/diary/app/state/AppState.kt
@@ -8,7 +8,9 @@ import io.github.taetae98coding.diary.app.navigation.AppNavigation
 import io.github.taetae98coding.diary.core.navigation.calendar.CalendarHomeDestination
 
 @Stable
-internal class AppState(val navController: NavHostController) {
+internal class AppState(
+	val navController: NavHostController,
+) {
 	fun navigate(navigation: AppNavigation) {
 		val isSelected =
 			navController.currentBackStackEntry
diff --git a/app/platform/jvm/build.gradle.kts b/app/platform/jvm/build.gradle.kts
index dd8e1daa..132048da 100644
--- a/app/platform/jvm/build.gradle.kts
+++ b/app/platform/jvm/build.gradle.kts
@@ -47,7 +47,7 @@ compose {
                 targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
 
                 packageName = "Diary"
-                packageVersion = "1.2.1"
+                packageVersion = "1.2.2"
 
                 macOS {
                     appStore = true
diff --git a/build-logic/src/main/kotlin/plugin/convention/AppDomainPlugin.kt b/build-logic/src/main/kotlin/plugin/convention/AppDomainPlugin.kt
index 6806df88..afb89824 100644
--- a/build-logic/src/main/kotlin/plugin/convention/AppDomainPlugin.kt
+++ b/build-logic/src/main/kotlin/plugin/convention/AppDomainPlugin.kt
@@ -9,10 +9,12 @@ import ext.withKotlinMultiplatform
 import ext.withPlugin
 import org.gradle.api.Plugin
 import org.gradle.api.Project
+import plugin.kotest.KotestJvmPlugin
 import plugin.kotlin.KotlinMultiplatformCommonPlugin
 
 internal class AppDomainPlugin : Plugin<Project> {
     private val kotlinMultiplatformCommonPlugin = KotlinMultiplatformCommonPlugin()
+    private val kotestJvmPlugin = KotestJvmPlugin()
 
     override fun apply(target: Project) {
         val libs = target.libs
@@ -47,5 +49,7 @@ internal class AppDomainPlugin : Plugin<Project> {
             kspCommon(platform(libs.library("koin-annotations-bom")))
             kspCommon(libs.library("koin-compiler"))
         }
+
+        kotestJvmPlugin.apply(target)
     }
 }
diff --git a/build-logic/src/main/kotlin/plugin/kotest/KotestJvmPlugin.kt b/build-logic/src/main/kotlin/plugin/kotest/KotestJvmPlugin.kt
new file mode 100644
index 00000000..3fb24582
--- /dev/null
+++ b/build-logic/src/main/kotlin/plugin/kotest/KotestJvmPlugin.kt
@@ -0,0 +1,41 @@
+package plugin.kotest
+
+import ext.bundle
+import ext.library
+import ext.libs
+import ext.sourceSets
+import ext.withKotlinMultiplatform
+import ext.withPlugin
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.tasks.testing.Test
+import org.gradle.kotlin.dsl.withType
+
+internal class KotestJvmPlugin : Plugin<Project>{
+    override fun apply(target: Project) {
+        val libs = target.libs
+
+        target.withPlugin {
+            apply("io.kotest.multiplatform")
+        }
+
+        target.withKotlinMultiplatform {
+            sourceSets {
+                jvmTest {
+                    dependencies {
+                        implementation(kotlin("reflect"))
+                        implementation(libs.library("kotlinx-coroutines-test"))
+
+                        implementation(libs.bundle("kotest"))
+                        implementation(libs.library("kotest-runner-junit5"))
+                        implementation(libs.library("mockk"))
+                    }
+                }
+            }
+        }
+
+        target.tasks.withType<Test>().configureEach {
+            useJUnitPlatform()
+        }
+    }
+}
diff --git a/build.gradle.kts b/build.gradle.kts
index d1233dc7..72902894 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -10,6 +10,7 @@ plugins {
     alias(libs.plugins.compose).apply(false)
     alias(libs.plugins.compose.compiler).apply(false)
     alias(libs.plugins.room).apply(false)
+    alias(libs.plugins.kotest).apply(false)
 
     alias(libs.plugins.android.application).apply(false)
     alias(libs.plugins.android.library).apply(false)
diff --git a/common/exception/src/commonMain/kotlin/io/github/taetae98coding/diary/common/exception/ApiException.kt b/common/exception/src/commonMain/kotlin/io/github/taetae98coding/diary/common/exception/ApiException.kt
index 39383033..b1dd2529 100644
--- a/common/exception/src/commonMain/kotlin/io/github/taetae98coding/diary/common/exception/ApiException.kt
+++ b/common/exception/src/commonMain/kotlin/io/github/taetae98coding/diary/common/exception/ApiException.kt
@@ -1,3 +1,6 @@
 package io.github.taetae98coding.diary.common.exception
 
-public class ApiException(override val message: String? = null, override val cause: Throwable? = null) : Exception(message, cause)
+public class ApiException(
+	override val message: String? = null,
+	override val cause: Throwable? = null,
+) : Exception(message, cause)
diff --git a/common/exception/src/commonMain/kotlin/io/github/taetae98coding/diary/common/exception/NetworkException.kt b/common/exception/src/commonMain/kotlin/io/github/taetae98coding/diary/common/exception/NetworkException.kt
index 2bb1cedf..348b7edf 100644
--- a/common/exception/src/commonMain/kotlin/io/github/taetae98coding/diary/common/exception/NetworkException.kt
+++ b/common/exception/src/commonMain/kotlin/io/github/taetae98coding/diary/common/exception/NetworkException.kt
@@ -1,3 +1,6 @@
 package io.github.taetae98coding.diary.common.exception
 
-public class NetworkException(override val message: String? = null, override val cause: Throwable? = null) : Exception(message, cause)
+public class NetworkException(
+	override val message: String? = null,
+	override val cause: Throwable? = null,
+) : Exception(message, cause)
diff --git a/common/exception/src/commonMain/kotlin/io/github/taetae98coding/diary/common/exception/account/AccountNotFoundException.kt b/common/exception/src/commonMain/kotlin/io/github/taetae98coding/diary/common/exception/account/AccountNotFoundException.kt
index 0f201b70..318507c5 100644
--- a/common/exception/src/commonMain/kotlin/io/github/taetae98coding/diary/common/exception/account/AccountNotFoundException.kt
+++ b/common/exception/src/commonMain/kotlin/io/github/taetae98coding/diary/common/exception/account/AccountNotFoundException.kt
@@ -1,3 +1,6 @@
 package io.github.taetae98coding.diary.common.exception.account
 
-public class AccountNotFoundException(override val message: String? = null, override val cause: Throwable? = null) : Exception(message, cause)
+public class AccountNotFoundException(
+	override val message: String? = null,
+	override val cause: Throwable? = null,
+) : Exception(message, cause)
diff --git a/common/exception/src/commonMain/kotlin/io/github/taetae98coding/diary/common/exception/account/ExistEmailException.kt b/common/exception/src/commonMain/kotlin/io/github/taetae98coding/diary/common/exception/account/ExistEmailException.kt
index a1919a1f..c6646c2f 100644
--- a/common/exception/src/commonMain/kotlin/io/github/taetae98coding/diary/common/exception/account/ExistEmailException.kt
+++ b/common/exception/src/commonMain/kotlin/io/github/taetae98coding/diary/common/exception/account/ExistEmailException.kt
@@ -1,3 +1,6 @@
 package io.github.taetae98coding.diary.common.exception.account
 
-public class ExistEmailException(override val message: String? = null, override val cause: Throwable? = null) : Exception(message, cause)
+public class ExistEmailException(
+	override val message: String? = null,
+	override val cause: Throwable? = null,
+) : Exception(message, cause)
diff --git a/common/exception/src/commonMain/kotlin/io/github/taetae98coding/diary/common/exception/account/InvalidEmailException.kt b/common/exception/src/commonMain/kotlin/io/github/taetae98coding/diary/common/exception/account/InvalidEmailException.kt
index 3fa63949..1000f812 100644
--- a/common/exception/src/commonMain/kotlin/io/github/taetae98coding/diary/common/exception/account/InvalidEmailException.kt
+++ b/common/exception/src/commonMain/kotlin/io/github/taetae98coding/diary/common/exception/account/InvalidEmailException.kt
@@ -1,3 +1,6 @@
 package io.github.taetae98coding.diary.common.exception.account
 
-public class InvalidEmailException(override val message: String? = "", override val cause: Throwable? = null) : Exception(message, cause)
+public class InvalidEmailException(
+	override val message: String? = "",
+	override val cause: Throwable? = null,
+) : Exception(message, cause)
diff --git a/common/exception/src/commonMain/kotlin/io/github/taetae98coding/diary/common/exception/memo/MemoTitleBlankException.kt b/common/exception/src/commonMain/kotlin/io/github/taetae98coding/diary/common/exception/memo/MemoTitleBlankException.kt
index 527d53fb..9b7cef70 100644
--- a/common/exception/src/commonMain/kotlin/io/github/taetae98coding/diary/common/exception/memo/MemoTitleBlankException.kt
+++ b/common/exception/src/commonMain/kotlin/io/github/taetae98coding/diary/common/exception/memo/MemoTitleBlankException.kt
@@ -1,3 +1,6 @@
 package io.github.taetae98coding.diary.common.exception.memo
 
-public class MemoTitleBlankException(override val message: String? = null, override val cause: Throwable? = null) : Exception(message, cause)
+public class MemoTitleBlankException(
+	override val message: String? = null,
+	override val cause: Throwable? = null,
+) : Exception(message, cause)
diff --git a/common/model/src/commonMain/kotlin/io/github/taetae98coding/diary/common/model/response/DiaryResponse.kt b/common/model/src/commonMain/kotlin/io/github/taetae98coding/diary/common/model/response/DiaryResponse.kt
index 93365f5b..d6babf5b 100644
--- a/common/model/src/commonMain/kotlin/io/github/taetae98coding/diary/common/model/response/DiaryResponse.kt
+++ b/common/model/src/commonMain/kotlin/io/github/taetae98coding/diary/common/model/response/DiaryResponse.kt
@@ -3,7 +3,11 @@ package io.github.taetae98coding.diary.common.model.response
 import kotlinx.serialization.Serializable
 
 @Serializable
-public data class DiaryResponse<T>(val code: Int = 0, val message: String = "", val body: T? = null) {
+public data class DiaryResponse<T>(
+	val code: Int = 0,
+	val message: String = "",
+	val body: T? = null,
+) {
 	public companion object {
 		public val Success: DiaryResponse<Unit> = DiaryResponse(200, "SUCCESS", Unit)
 		public val Created: DiaryResponse<Unit> = DiaryResponse(201, "CREATED", Unit)
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 1137765c..09ea114f 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -24,6 +24,9 @@ datastore = "1.1.1"                         # https://developer.android.com/jetp
 room = "2.7.0-alpha11"                      # https://developer.android.com/jetpack/androidx/releases/room?hl=en
 sqlite = "2.5.0-alpha11"                    # https://developer.android.com/jetpack/androidx/releases/sqlite?hl=en
 
+kotest = "6.0.0.M1"                         # https://github.com/kotest/kotest/releases
+mockk = "1.13.13"                           # https://github.com/mockk/mockk/releases
+
 ### android
 android-material = "1.12.0"                 # https://github.com/material-components/material-components-android/releases
 androidx-activity = "1.9.3"                 # https://developer.android.com/jetpack/androidx/releases/activity?hl=en
@@ -63,6 +66,7 @@ kotlinx-serialization-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-
 
 kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" }
 kotlinx-coroutines-swing = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-swing", version.ref = "kotlinx-coroutines" }
+kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" }
 
 kotlinx-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version.ref = "kotlinx-datetime" }
 
@@ -94,6 +98,12 @@ koin-annotations-bom = { group = "io.insert-koin", name = "koin-annotations-bom"
 koin-annotations = { group = "io.insert-koin", name = "koin-annotations" }
 koin-compiler = { group = "io.insert-koin", name = "koin-ksp-compiler" }
 
+kotest-framework-engin = { group = "io.kotest", name = "kotest-framework-engine", version.ref = "kotest" }
+kotest-assertions = { group = "io.kotest", name = "kotest-assertions-core", version.ref = "kotest" }
+kotest-property = { group = "io.kotest", name = "kotest-property", version.ref = "kotest" }
+kotest-runner-junit5 = { group = "io.kotest", name = "kotest-runner-junit5", version.ref = "kotest" }
+mockk = { group = "io.mockk", name = "mockk", version.ref = "mockk" }
+
 ### android
 android-material = { group = "com.google.android.material", name = "material", version.ref = "android-material" }
 androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "androidx-activity" }
@@ -150,6 +160,8 @@ compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "
 
 room = { id = "androidx.room", version.ref = "room" }
 
+kotest = { id = "io.kotest.multiplatform", version.ref = "kotest" }
+
 ### android
 android-application = { id = "com.android.application", version.ref = "agp" }
 android-library = { id = "com.android.library", version.ref = "agp" }
@@ -179,6 +191,12 @@ room = [
     "sqlite-bundled"
 ]
 
+kotest = [
+    "kotest-framework-engin",
+    "kotest-assertions",
+    "kotest-property"
+]
+
 ktor-server = [
     "ktor-server-netty",
     "ktor-server-config-yaml",
diff --git a/library/coroutines/src/commonMain/kotlin/io/github/taetae98coding/diary/library/coroutines/FlowExt.kt b/library/coroutines/src/commonMain/kotlin/io/github/taetae98coding/diary/library/coroutines/FlowExt.kt
index 470288bc..c70589fc 100644
--- a/library/coroutines/src/commonMain/kotlin/io/github/taetae98coding/diary/library/coroutines/FlowExt.kt
+++ b/library/coroutines/src/commonMain/kotlin/io/github/taetae98coding/diary/library/coroutines/FlowExt.kt
@@ -1,10 +1,10 @@
 package io.github.taetae98coding.diary.library.coroutines
 
-import kotlin.jvm.JvmName
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.mapLatest
+import kotlin.jvm.JvmName
 
 @JvmName("mapCollectionLatest")
 @OptIn(ExperimentalCoroutinesApi::class)
diff --git a/library/koin-datastore/src/jvmMain/kotlin/io/github/taetae98coding/diary/library/koin/datastore/DataStoreExt.jvm.kt b/library/koin-datastore/src/jvmMain/kotlin/io/github/taetae98coding/diary/library/koin/datastore/DataStoreExt.jvm.kt
index f942eda2..2e0c9f92 100644
--- a/library/koin-datastore/src/jvmMain/kotlin/io/github/taetae98coding/diary/library/koin/datastore/DataStoreExt.jvm.kt
+++ b/library/koin-datastore/src/jvmMain/kotlin/io/github/taetae98coding/diary/library/koin/datastore/DataStoreExt.jvm.kt
@@ -1,7 +1,7 @@
 package io.github.taetae98coding.diary.library.koin.datastore
 
-import java.io.File
 import org.koin.core.component.KoinComponent
+import java.io.File
 
 public var koinDataStoreDefaultPath: String = System.getProperty("user.home")
 
diff --git a/library/koin-room/src/jvmMain/kotlin/io/github/taetae98coding/diary/library/koin/room/RoomExt.jvm.kt b/library/koin-room/src/jvmMain/kotlin/io/github/taetae98coding/diary/library/koin/room/RoomExt.jvm.kt
index e4292737..966aec85 100644
--- a/library/koin-room/src/jvmMain/kotlin/io/github/taetae98coding/diary/library/koin/room/RoomExt.jvm.kt
+++ b/library/koin-room/src/jvmMain/kotlin/io/github/taetae98coding/diary/library/koin/room/RoomExt.jvm.kt
@@ -2,8 +2,8 @@ package io.github.taetae98coding.diary.library.koin.room
 
 import androidx.room.Room
 import androidx.room.RoomDatabase
-import java.io.File
 import org.koin.core.component.KoinComponent
+import java.io.File
 
 public var koinRoomDefaultPath: String = System.getProperty("user.home")
 
diff --git a/server/app/src/main/kotlin/io/github/taetae98coding/diary/plugin/ContentNegotiationPlugin.kt b/server/app/src/main/kotlin/io/github/taetae98coding/diary/plugin/ContentNegotiationPlugin.kt
index 0882fd0c..75d9766f 100644
--- a/server/app/src/main/kotlin/io/github/taetae98coding/diary/plugin/ContentNegotiationPlugin.kt
+++ b/server/app/src/main/kotlin/io/github/taetae98coding/diary/plugin/ContentNegotiationPlugin.kt
@@ -11,9 +11,9 @@ internal fun Application.installContentNegotiation() {
 	install(ContentNegotiation) {
 		json(
 			json =
-			Json(DefaultJson) {
-				ignoreUnknownKeys = true
-			},
+				Json(DefaultJson) {
+					ignoreUnknownKeys = true
+				},
 		)
 	}
 }
diff --git a/server/core/model/src/main/kotlin/io/github/taetae98coding/diary/core/model/Account.kt b/server/core/model/src/main/kotlin/io/github/taetae98coding/diary/core/model/Account.kt
index 213358aa..01d5cd8a 100644
--- a/server/core/model/src/main/kotlin/io/github/taetae98coding/diary/core/model/Account.kt
+++ b/server/core/model/src/main/kotlin/io/github/taetae98coding/diary/core/model/Account.kt
@@ -1,3 +1,7 @@
 package io.github.taetae98coding.diary.core.model
 
-public data class Account(val uid: String, val email: String, val password: String)
+public data class Account(
+	val uid: String,
+	val email: String,
+	val password: String,
+)
diff --git a/server/core/model/src/main/kotlin/io/github/taetae98coding/diary/core/model/Memo.kt b/server/core/model/src/main/kotlin/io/github/taetae98coding/diary/core/model/Memo.kt
index 460500a1..5b934687 100644
--- a/server/core/model/src/main/kotlin/io/github/taetae98coding/diary/core/model/Memo.kt
+++ b/server/core/model/src/main/kotlin/io/github/taetae98coding/diary/core/model/Memo.kt
@@ -3,4 +3,16 @@ package io.github.taetae98coding.diary.core.model
 import kotlinx.datetime.Instant
 import kotlinx.datetime.LocalDate
 
-public data class Memo(val id: String, val title: String, val description: String, val start: LocalDate?, val endInclusive: LocalDate?, val color: Int, val owner: String, val primaryTag: String?, val isFinish: Boolean, val isDelete: Boolean, val updateAt: Instant)
+public data class Memo(
+	val id: String,
+	val title: String,
+	val description: String,
+	val start: LocalDate?,
+	val endInclusive: LocalDate?,
+	val color: Int,
+	val owner: String,
+	val primaryTag: String?,
+	val isFinish: Boolean,
+	val isDelete: Boolean,
+	val updateAt: Instant,
+)
diff --git a/server/core/model/src/main/kotlin/io/github/taetae98coding/diary/core/model/MemoAndTagIds.kt b/server/core/model/src/main/kotlin/io/github/taetae98coding/diary/core/model/MemoAndTagIds.kt
index f73b7e72..3a96067a 100644
--- a/server/core/model/src/main/kotlin/io/github/taetae98coding/diary/core/model/MemoAndTagIds.kt
+++ b/server/core/model/src/main/kotlin/io/github/taetae98coding/diary/core/model/MemoAndTagIds.kt
@@ -1,3 +1,6 @@
 package io.github.taetae98coding.diary.core.model
 
-public data class MemoAndTagIds(val memo: Memo, val tagIds: Set<String>)
+public data class MemoAndTagIds(
+	val memo: Memo,
+	val tagIds: Set<String>,
+)
diff --git a/server/core/model/src/main/kotlin/io/github/taetae98coding/diary/core/model/Tag.kt b/server/core/model/src/main/kotlin/io/github/taetae98coding/diary/core/model/Tag.kt
index 2d9ad929..c585e522 100644
--- a/server/core/model/src/main/kotlin/io/github/taetae98coding/diary/core/model/Tag.kt
+++ b/server/core/model/src/main/kotlin/io/github/taetae98coding/diary/core/model/Tag.kt
@@ -2,4 +2,13 @@ package io.github.taetae98coding.diary.core.model
 
 import kotlinx.datetime.Instant
 
-public data class Tag(val id: String, val title: String, val description: String, val color: Int, val owner: String, val isFinish: Boolean, val isDelete: Boolean, val updateAt: Instant)
+public data class Tag(
+	val id: String,
+	val title: String,
+	val description: String,
+	val color: Int,
+	val owner: String,
+	val isFinish: Boolean,
+	val isDelete: Boolean,
+	val updateAt: Instant,
+)
diff --git a/server/domain/account/src/main/kotlin/io/github/taetae98coding/diary/domain/account/usecase/FindAccountUseCase.kt b/server/domain/account/src/main/kotlin/io/github/taetae98coding/diary/domain/account/usecase/FindAccountUseCase.kt
index 23c95ce1..2656ce7f 100644
--- a/server/domain/account/src/main/kotlin/io/github/taetae98coding/diary/domain/account/usecase/FindAccountUseCase.kt
+++ b/server/domain/account/src/main/kotlin/io/github/taetae98coding/diary/domain/account/usecase/FindAccountUseCase.kt
@@ -5,7 +5,10 @@ import io.github.taetae98coding.diary.domain.account.repository.AccountRepositor
 import org.koin.core.annotation.Factory
 
 @Factory
-public class FindAccountUseCase internal constructor(private val hashingPasswordUseCase: HashingPasswordUseCase, private val repository: AccountRepository) {
+public class FindAccountUseCase internal constructor(
+	private val hashingPasswordUseCase: HashingPasswordUseCase,
+	private val repository: AccountRepository,
+) {
 	public suspend operator fun invoke(email: String, password: String): Result<Account?> =
 		runCatching {
 			repository.findByEmail(
diff --git a/server/domain/account/src/main/kotlin/io/github/taetae98coding/diary/domain/account/usecase/HashingPasswordUseCase.kt b/server/domain/account/src/main/kotlin/io/github/taetae98coding/diary/domain/account/usecase/HashingPasswordUseCase.kt
index cca4acb9..a6f18ce9 100644
--- a/server/domain/account/src/main/kotlin/io/github/taetae98coding/diary/domain/account/usecase/HashingPasswordUseCase.kt
+++ b/server/domain/account/src/main/kotlin/io/github/taetae98coding/diary/domain/account/usecase/HashingPasswordUseCase.kt
@@ -1,9 +1,9 @@
 package io.github.taetae98coding.diary.domain.account.usecase
 
-import java.security.MessageDigest
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.withContext
 import org.koin.core.annotation.Factory
+import java.security.MessageDigest
 
 @OptIn(ExperimentalStdlibApi::class)
 @Factory
diff --git a/server/domain/account/src/main/kotlin/io/github/taetae98coding/diary/domain/account/usecase/JoinUseCase.kt b/server/domain/account/src/main/kotlin/io/github/taetae98coding/diary/domain/account/usecase/JoinUseCase.kt
index a393ba1d..50a99918 100644
--- a/server/domain/account/src/main/kotlin/io/github/taetae98coding/diary/domain/account/usecase/JoinUseCase.kt
+++ b/server/domain/account/src/main/kotlin/io/github/taetae98coding/diary/domain/account/usecase/JoinUseCase.kt
@@ -5,13 +5,16 @@ import io.github.taetae98coding.diary.common.exception.account.InvalidEmailExcep
 import io.github.taetae98coding.diary.core.model.Account
 import io.github.taetae98coding.diary.domain.account.repository.AccountRepository
 import io.github.taetae98coding.diary.library.kotlin.regex.email
+import org.koin.core.annotation.Factory
 import kotlin.uuid.ExperimentalUuidApi
 import kotlin.uuid.Uuid
-import org.koin.core.annotation.Factory
 
 @OptIn(ExperimentalUuidApi::class)
 @Factory
-public class JoinUseCase internal constructor(private val hashingPasswordUseCase: HashingPasswordUseCase, private val repository: AccountRepository) {
+public class JoinUseCase internal constructor(
+	private val hashingPasswordUseCase: HashingPasswordUseCase,
+	private val repository: AccountRepository,
+) {
 	public suspend operator fun invoke(email: String, password: String): Result<Unit> =
 		runCatching {
 			// TODO password check
diff --git a/server/domain/fcm/src/main/kotlin/io/github/taetae98coding/diary/domain/fcm/usecase/DeleteFCMTokenUseCase.kt b/server/domain/fcm/src/main/kotlin/io/github/taetae98coding/diary/domain/fcm/usecase/DeleteFCMTokenUseCase.kt
index 9abd99da..90f77c96 100644
--- a/server/domain/fcm/src/main/kotlin/io/github/taetae98coding/diary/domain/fcm/usecase/DeleteFCMTokenUseCase.kt
+++ b/server/domain/fcm/src/main/kotlin/io/github/taetae98coding/diary/domain/fcm/usecase/DeleteFCMTokenUseCase.kt
@@ -4,6 +4,8 @@ import io.github.taetae98coding.diary.domain.fcm.repository.FCMRepository
 import org.koin.core.annotation.Factory
 
 @Factory
-public class DeleteFCMTokenUseCase internal constructor(private val repository: FCMRepository) {
+public class DeleteFCMTokenUseCase internal constructor(
+	private val repository: FCMRepository,
+) {
 	public suspend operator fun invoke(token: String): Result<Unit> = runCatching { repository.delete(token) }
 }
diff --git a/server/domain/fcm/src/main/kotlin/io/github/taetae98coding/diary/domain/fcm/usecase/UpsertFCMTokenUseCase.kt b/server/domain/fcm/src/main/kotlin/io/github/taetae98coding/diary/domain/fcm/usecase/UpsertFCMTokenUseCase.kt
index 12babd64..4589d1f7 100644
--- a/server/domain/fcm/src/main/kotlin/io/github/taetae98coding/diary/domain/fcm/usecase/UpsertFCMTokenUseCase.kt
+++ b/server/domain/fcm/src/main/kotlin/io/github/taetae98coding/diary/domain/fcm/usecase/UpsertFCMTokenUseCase.kt
@@ -4,6 +4,8 @@ import io.github.taetae98coding.diary.domain.fcm.repository.FCMRepository
 import org.koin.core.annotation.Factory
 
 @Factory
-public class UpsertFCMTokenUseCase internal constructor(private val repository: FCMRepository) {
+public class UpsertFCMTokenUseCase internal constructor(
+	private val repository: FCMRepository,
+) {
 	public suspend operator fun invoke(token: String, owner: String): Result<Unit> = runCatching { repository.upsert(token, owner) }
 }
diff --git a/server/domain/memo/src/main/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/FetchMemoUseCase.kt b/server/domain/memo/src/main/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/FetchMemoUseCase.kt
index 5b6ea6a0..78cc73bd 100644
--- a/server/domain/memo/src/main/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/FetchMemoUseCase.kt
+++ b/server/domain/memo/src/main/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/FetchMemoUseCase.kt
@@ -13,7 +13,9 @@ import org.koin.core.annotation.Factory
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @Factory
-public class FetchMemoUseCase internal constructor(private val repository: MemoRepository) {
+public class FetchMemoUseCase internal constructor(
+	private val repository: MemoRepository,
+) {
 	public operator fun invoke(uid: String, updateAt: Instant): Flow<Result<List<MemoAndTagIds>>> =
 		flow { emitAll(repository.findMemoAndTagIdsByUpdateAt(uid, updateAt)) }
 			.mapLatest { Result.success(it) }
diff --git a/server/domain/memo/src/main/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/UpsertMemoUseCase.kt b/server/domain/memo/src/main/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/UpsertMemoUseCase.kt
index acfe9300..6f713f1a 100644
--- a/server/domain/memo/src/main/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/UpsertMemoUseCase.kt
+++ b/server/domain/memo/src/main/kotlin/io/github/taetae98coding/diary/domain/memo/usecase/UpsertMemoUseCase.kt
@@ -7,7 +7,9 @@ import kotlinx.coroutines.flow.first
 import org.koin.core.annotation.Factory
 
 @Factory
-public class UpsertMemoUseCase internal constructor(private val repository: MemoRepository) {
+public class UpsertMemoUseCase internal constructor(
+	private val repository: MemoRepository,
+) {
 	public suspend operator fun invoke(list: List<MemoAndTagIds>): Result<Unit> {
 		return runCatching {
 			// TODO Permission Check
@@ -26,13 +28,13 @@ public class UpsertMemoUseCase internal constructor(private val repository: Memo
 					}.map {
 						it.copy(
 							memo =
-							it.memo.copy(
-								title =
-								it.memo.title.ifBlank {
-									val origin = originMap[it.memo.id] ?: throw TagTitleBlankException()
-									origin.title
-								},
-							),
+								it.memo.copy(
+									title =
+										it.memo.title.ifBlank {
+											val origin = originMap[it.memo.id] ?: throw TagTitleBlankException()
+											origin.title
+										},
+								),
 						)
 					}
 
diff --git a/server/domain/tag/src/main/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/FetchTagUseCase.kt b/server/domain/tag/src/main/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/FetchTagUseCase.kt
index 42baa61e..9c813172 100644
--- a/server/domain/tag/src/main/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/FetchTagUseCase.kt
+++ b/server/domain/tag/src/main/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/FetchTagUseCase.kt
@@ -13,7 +13,9 @@ import org.koin.core.annotation.Factory
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @Factory
-public class FetchTagUseCase internal constructor(private val repository: TagRepository) {
+public class FetchTagUseCase internal constructor(
+	private val repository: TagRepository,
+) {
 	public operator fun invoke(uid: String, updateAt: Instant): Flow<Result<List<Tag>>> =
 		flow { emitAll(repository.findByUpdateAt(uid, updateAt)) }
 			.mapLatest { Result.success(it) }
diff --git a/server/domain/tag/src/main/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/UpsertTagUseCase.kt b/server/domain/tag/src/main/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/UpsertTagUseCase.kt
index a087b4bd..7363c101 100644
--- a/server/domain/tag/src/main/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/UpsertTagUseCase.kt
+++ b/server/domain/tag/src/main/kotlin/io/github/taetae98coding/diary/domain/tag/usecase/UpsertTagUseCase.kt
@@ -7,7 +7,9 @@ import kotlinx.coroutines.flow.first
 import org.koin.core.annotation.Factory
 
 @Factory
-public class UpsertTagUseCase internal constructor(private val repository: TagRepository) {
+public class UpsertTagUseCase internal constructor(
+	private val repository: TagRepository,
+) {
 	public suspend operator fun invoke(list: List<Tag>): Result<Unit> {
 		return runCatching {
 			// TODO Permission Check
@@ -26,10 +28,10 @@ public class UpsertTagUseCase internal constructor(private val repository: TagRe
 					}.map {
 						it.copy(
 							title =
-							it.title.ifBlank {
-								val origin = originMap[it.id] ?: throw TagTitleBlankException()
-								origin.title
-							},
+								it.title.ifBlank {
+									val origin = originMap[it.id] ?: throw TagTitleBlankException()
+									origin.title
+								},
 						)
 					}