Skip to content

データモデル

iOS(ローカル)

JournalEntry

フィールド説明
idUUID
dateDate
textString日記本文
tags[String]タグ一覧
deletedAtDate?ソフトデリート用

TaskItem

フィールド説明
idUUID
titleString
descriptionString?
isCompletedBool
createdAtDate
completedAtDate?
intentString?やる前の意図
achievementVisionString?達成イメージ
notesString?メモ
factString?やったこと(ふりかえり)
insightString?気づいたこと(ふりかえり)
nextActionString?次にやりたいこと(ふりかえり)
sortOrderInt並び順
deletedAtDate?ソフトデリート用

CoachSession

フィールド説明
idUUID
messages[CoachMessage]
summaryString?セッション要約
emotionLabelString?検出された感情
isActiveBool
createdAtDate

CoachMessage

フィールド説明
idUUID
roleMessageRoleuser / coach
contentString
metadataMessageMetadata?感情、Cycle要素、提案アクション
createdAtDate

AuthUser

フィールド説明
userIdString
appleUserIdString
emailString?
fullNameString?
createdAtDate

Backend(Firestore)

コレクション構造

users/{userId}
  ├── apple_user_id: string
  ├── email: string
  ├── display_name: string
  ├── settings: map
  ├── created_at: timestamp

  ├── sessions/{sessionId}
  │     ├── title: string
  │     ├── cycle_element: string
  │     ├── created_at: timestamp
  │     │
  │     └── messages/{messageId}
  │           ├── role: string (user | assistant)
  │           ├── content: string
  │           ├── metadata: map
  │           └── created_at: timestamp

  └── tasks/{taskId}
        ├── title: string
        ├── description: string
        ├── status: string (pending | completed)
        ├── session_id: string
        ├── cycle_element: string
        ├── created_at: timestamp

        └── reflections/{reflectionId}
              ├── what_i_did: string
              ├── what_i_noticed: string
              ├── what_i_want_to_try: string
              ├── overall_feeling: string
              └── created_at: timestamp

API側のリクエスト/レスポンス形式は docs/api/openapi.yaml を参照。

なぜFirestoreか

Cloud SQL(PostgreSQL)ではなくFirestoreを選んだ理由:

  • コスト: Cloud SQLは最小でも月$10の常時起動コスト。Firestoreは個人利用なら無料枠内
  • スケールtoゼロ: Cloud Runと合わせて完全にゼロコスト運用が可能
  • データ構造: users/sessions/messages の入れ子構造がドキュメントDBに自然に対応
  • 構成のシンプルさ: VPC ConnectorやプライベートIP接続が不要

ストレージ方式

現在(ローカルファースト)

データ保存先
Journaljournals.json(DocumentsDirectory)
Taskstasks.json(DocumentsDirectory)
TaskArchive日付別JSONファイル
CoachSessionUserDefaults
AuthTokenKeychain
TagsUserDefaults (availableTags)

なぜこうしたか

JSONファイル保存にした理由: CoreDataはマイグレーション管理が重く、現段階のデータ量(個人利用)ではオーバー。将来的にAPI同期に移行する前提なので、ローカルは軽量に保つ判断。JSONなら構造が見えやすく、デバッグも容易。