Appearance
データモデル・ER図
ステータス: ドラフト(2026-04-15 起案) 対象: M1 で扱う主要エンティティのスキーマ。関連: requirements.md / auth-rbac.md(策定予定) 注意: M1 のモックはインメモリ/JSON でこのスキーマを模擬する。DB・マイグレーションは M2 で ADR-0002 等で正式化する。
1. エンティティ一覧(概要)
| エンティティ | 概要 |
|---|---|
| Organization | 組織(送出し機関・日本語学校・受入企業) |
| User | 利用者(学習者・講師・OA・企業採用 等) |
| RoleAssignment | User × Organization × Role の紐付け |
| Cohort | 研修期(クラス・期別) |
| Enrollment | 学習者 × Cohort 参加記録 |
| Curriculum | カリキュラム |
| CurriculumItem | カリキュラム内の項目(単語/動画/クイズ/テスト割当) |
| VocabularySet | 単語セット |
| Vocabulary | 単語 |
| VocabularyProgress | 学習者 × 単語 の習得状態 |
| Video | 動画 |
| VideoWatchLog | 動画視聴ログ(時間・区間・スキップ) |
| Quiz | クイズ |
| QuizQuestion | 設問 |
| QuizAttempt | 受験試行 |
| QuizAnswer | 回答(試行内の個別回答) |
| Exam | 試験 |
| ExamResult | 試験結果 |
| StudyTimeLog | 学習時間ログ(申告・実測) |
| AttendanceLog | 出席ログ |
| CredibilityScore | 学習行動の一貫性スコア |
| Appeal | 異議申立 |
| ConsentRecord | 同意履歴 |
| AuditLog | 監査ログ |
| DisclosurePolicy | 学習者の企業開示可否フラグ |
2. ER図(Mermaid)
mermaid
erDiagram
Organization ||--o{ RoleAssignment : has
User ||--o{ RoleAssignment : has
RoleAssignment }o--|| Organization : scopes
Organization ||--o{ Cohort : manages
Cohort ||--o{ Enrollment : includes
Enrollment }o--|| User : learner
Cohort ||--o{ Curriculum : uses
Curriculum ||--o{ CurriculumItem : contains
CurriculumItem }o--|| VocabularySet : may_reference
CurriculumItem }o--|| Video : may_reference
CurriculumItem }o--|| Quiz : may_reference
CurriculumItem }o--|| Exam : may_reference
VocabularySet ||--o{ Vocabulary : contains
User ||--o{ VocabularyProgress : tracks
Vocabulary ||--o{ VocabularyProgress : for
User ||--o{ VideoWatchLog : watches
Video ||--o{ VideoWatchLog : has
Quiz ||--o{ QuizQuestion : contains
User ||--o{ QuizAttempt : takes
Quiz ||--o{ QuizAttempt : has
QuizAttempt ||--o{ QuizAnswer : contains
QuizQuestion ||--o{ QuizAnswer : answered_by
User ||--o{ ExamResult : earns
Exam ||--o{ ExamResult : of
User ||--o{ StudyTimeLog : logs
User ||--o{ AttendanceLog : logs
User ||--o{ CredibilityScore : scored
User ||--o{ Appeal : raises
User ||--o{ ConsentRecord : consents
User ||--o{ DisclosurePolicy : sets
User ||--o{ AuditLog : acted3. テーブル定義(主要)
3.1 User
| カラム | 型 | 制約 | 備考 |
|---|---|---|---|
| id | uuid | PK | |
| text | unique, not null | ||
| password_hash | text | not null | bcrypt 等 |
| display_name | text | ||
| locale | text | default 'ja' | ja/vi/en |
| status | text | default 'active' | active/suspended/deleted |
| created_at | timestamptz | ||
| updated_at | timestamptz |
3.2 Organization
| カラム | 型 | 制約 | 備考 |
|---|---|---|---|
| id | uuid | PK | |
| name | text | not null | |
| kind | text | sending/school/employer/training | |
| country | text | JP/VN 等 |
3.3 RoleAssignment
| カラム | 型 | 制約 | 備考 |
|---|---|---|---|
| id | uuid | PK | |
| user_id | uuid | FK → User | |
| organization_id | uuid | FK → Organization | |
| role | text | learner/teacher/org_admin/trainer/employer/sending_manager/operator | |
| created_at | timestamptz |
3.4 Cohort(研修期/クラス)
| カラム | 型 | 制約 | 備考 |
|---|---|---|---|
| id | uuid | PK | |
| organization_id | uuid | FK | |
| name | text | 例: 2026年春期 A組 | |
| start_date | date | ||
| end_date | date | ||
| phase | text | pre-departure/in-japan-onboarding |
3.5 VocabularyProgress
| カラム | 型 | 制約 | 備考 |
|---|---|---|---|
| id | uuid | PK | |
| user_id | uuid | FK | |
| vocabulary_id | uuid | FK | |
| status | text | new/learning/mastered/forgotten | |
| last_seen_at | timestamptz | ||
| correct_count | int | default 0 | |
| incorrect_count | int | default 0 |
3.5b QuizAttempt / QuizAnswer
QuizAttempt
| カラム | 型 | 制約 | 備考 |
|---|---|---|---|
| id | uuid | PK | |
| user_id | uuid | FK | |
| quiz_id | uuid | FK | |
| started_at | timestamptz | not null | |
| ended_at | timestamptz | ||
| duration_seconds | int | not null, default 0 | 実測所要時間(エンドイベントで確定) |
| score | numeric | 総合スコア | |
| status | text | in_progress/submitted/abandoned |
QuizAnswer
| カラム | 型 | 制約 | 備考 |
|---|---|---|---|
| id | uuid | PK | |
| attempt_id | uuid | FK → QuizAttempt | |
| question_id | uuid | FK → QuizQuestion | |
| answer | jsonb | 選択肢ID or 入力文字列 | |
| is_correct | boolean | ||
| response_time_ms | int | not null | 設問表示〜回答までの時間 |
3.6 VideoWatchLog
| カラム | 型 | 制約 | 備考 |
|---|---|---|---|
| id | uuid | PK | |
| user_id | uuid | FK | |
| video_id | uuid | FK | |
| session_id | uuid | 1視聴セッション | |
| watched_seconds | int | 実再生秒数 | |
| distinct_segments | jsonb | [{start, end}, ...] 視聴区間 | |
| skipped_segments | jsonb | スキップ区間 | |
| completed | boolean | ||
| created_at | timestamptz |
3.7 StudyTimeLog
| カラム | 型 | 制約 | 備考 |
|---|---|---|---|
| id | uuid | PK | |
| user_id | uuid | FK | |
| log_date | date | ||
| reported_minutes | int | 申告時間 | |
| measured_minutes | int | 実測(ログ合算) | |
| source | text | self-report/calculated |
3.8 CredibilityScore
| カラム | 型 | 制約 | 備考 |
|---|---|---|---|
| id | uuid | PK | |
| user_id | uuid | FK | |
| period_start | date | ||
| period_end | date | ||
| score | numeric(4,2) | 0.00 〜 1.00 | |
| breakdown | jsonb | 指標ごとのスコア内訳 | |
| version | text | 算出ロジックのバージョン |
3.9 Appeal(異議申立)
| カラム | 型 | 制約 | 備考 |
|---|---|---|---|
| id | uuid | PK | |
| user_id | uuid | FK | 申立者 |
| target_kind | text | credibility_score/exam_result 等 | |
| target_id | uuid | ||
| reason | text | ||
| status | text | open/reviewing/accepted/rejected | |
| assignee_id | uuid | FK → User | OA |
3.10 ConsentRecord
| カラム | 型 | 制約 | 備考 |
|---|---|---|---|
| id | uuid | PK | |
| user_id | uuid | FK | |
| consent_kind | text | learning_log/employer_disclosure 等 | |
| version | text | 文言バージョン | |
| status | text | granted/withdrawn | |
| occurred_at | timestamptz |
3.11 DisclosurePolicy
| カラム | 型 | 制約 | 備考 |
|---|---|---|---|
| id | uuid | PK | |
| user_id | uuid | FK | |
| employer_org_id | uuid | FK → Organization | nullable(全企業対象) |
| visible | boolean | 企業ロールへの公開可否 |
3.12 AuditLog
| カラム | 型 | 制約 | 備考 |
|---|---|---|---|
| id | uuid | PK | |
| actor_user_id | uuid | FK → User | |
| actor_role | text | ||
| action | text | 例: employer.view_report | |
| target_user_id | uuid | 閲覧対象(必要時) | |
| meta | jsonb | ||
| occurred_at | timestamptz |
4. データ保持ポリシー(ドラフト)
- 学習ログ(Video/Quiz/StudyTime):学習者アクティブ期間 + 3年(Q5 で確定)
- 監査ログ:最低 1年(法令準拠で見直し)
- 同意履歴:撤回後も撤回記録として永続保持(削除しない)
- 削除請求:ユーザー識別子を匿名化、学習ログを匿名 ID に付け替え(解析上の有用性維持と個人特定不能の両立)
5. 計測指標(計算式ドラフト)
- 単語習得率 = mastered / total-assigned
- 実測学習時間 = Σ(VideoWatchLog.watched_seconds + QuizAttempt所要時間) を日別集計
- 申告 vs 実測乖離 = |reported_minutes - measured_minutes| / reported_minutes
- 一貫性スコア = 重み付き合算(乖離・スキップ率・回答バラツキ 等)。重み・閾値は別途定義(G4 ゲート)
6. 未確定事項
- 単語習得判定のアルゴリズム(間隔反復、正答率閾値)
- 試験の出題形式(紙/オンライン)に伴う Exam スキーマ拡張
- 越境データ移転のためのフィールド匿名化範囲
7. 改訂履歴
- 2026-04-15: 初版ドラフト作成