Files
life-helper/data-model.md
joungmin 29befe4d97 [Architect] Refs #204 — apply OQ decisions: diet_pattern (19th), ADR-0002 normalize dose_variants
- OQ-1: dose_variants 정규화 결정을 ADR-0002 로 승격 (ADR-0001 = 왜, ADR-0002 = 어떻게).
- OQ-3: nutrition diet 패턴 5개를 별도 diet_pattern 카탈로그(19번째 SoT)로 분리.
  · 02-catalog §8 신규, 인덱스 IDX_diet_patterns_evidence / IDX_diet_patterns_kfit.
  · 05-seed: diet_patterns.json (5행) 추가, 로딩 순서 끝에 배치.
  · 04-migrations: v1 테이블 합계 = Catalog 8 + User 11 + 부속 1 + meta_kv = 21.
- README §2/§3/§6/§11 갱신: 18→19 SoT, AC-2 에 diet_pattern=5 검증 추가.
- README §12 OQ → Resolved Open Questions 표 (OQ-1~OQ-8 결정 결과).
- habit_dose_variant → habit_dose_variants 표기 통일.
- fn-weekly-minimum-ratio, 03-drift-schema-user 의 ADR-0002 cross-link.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-11 17:13:04 +09:00

10 KiB

life-helper 데이터 모델 (v1)

목적: 본 프로젝트의 3개 마크다운 SoT(huberman-protocols.md, habit-todo-methodologies.md, habit-breaking-protocols.md)와 메모리 원칙(feedback_sustainable_minimal.md, feedback_reward_ladder.md, feedback_positive_framing.md)을 앱에서 쓸 수 있는 데이터 구조로 정형화.

선택된 형식: JSON Schema (Draft 2020-12). SQL/TS 변환은 추후. user_id 기반 → 단일 사용자 local-first와 멀티 사용자 클라우드 모두 호환.

machine-readable schema: ./schema/*.json (엔티티별 분리) 본 문서: 엔티티 관계 + 설계 의도 + 운영 규칙 + 사용 예시


§1. 엔티티 분류

Catalog (read-only seed data, 앱에 번들)

엔티티 SoT 원본 설명
protocol huberman-protocols.md + nutrition/diet-protocols.md 원자 프로토콜 (category로 health/meditation/motivation/habit/learning/diet 구분)
break_protocol habit-breaking-protocols.md §2 끊기 카테고리 8개
common_frame habit-breaking-protocols.md §1 끊기 공통 프레임 5개 (Dopamine Reset 등)
methodology habit-todo-methodologies.md 21개 습관/투두 방법론
frame_pattern 동 문서 §"언어 프레이밍" L0→L1/L2/L3 변환 예시
reward_menu_item 동 문서 §"리워드 시스템" 추천 보상 메뉴
reference 모든 SoT의 출처 필드 DOI/URL/책 인용
diet_pattern nutrition/diet-protocols.md §2 식이 패턴 5개 (지중해/저탄수/IF/Plant-Based/한식) — 의견 분열 영역, 사용자 선택 메뉴

User Data (사용자가 생성·변경)

엔티티 설명 핵심 제약
user 사용자 (단일/멀티 호환) id 필수
phase 6주 사이클 1개 user당 동시 active 1개
habit 사용자 습관 (build 또는 break) active build ≤ 3, active break ≤ 1
tracker_entry 일일 ○/공백 체크 (habit_id, date) unique
if_then_rule Implementation Intentions habit당 ≤ 3개 권장
lapse_log LEARN 5필드 (재발 일지) break 습관 위주
urge_log 충동 발생/통과 기록 (선택) break 습관 위주
reward_declaration 사전 선언 보상 (T0~T4) phase 시작 시점에만
reward_claim 실제 milestone 달성 기록 declaration 참조
reflection 주/월 회고 텍스트 자유

§2. 관계 다이어그램

user (1)
 ├─< phase (n)  -- 시점별 6주 사이클
 │   └─< reward_declaration (n)  -- 이 phase 동안의 T0~T4 사전 선언
 │
 └─< habit (n)
     ├── protocol_id  or  break_protocol_id   (catalog 참조, XOR)
     ├── frame {level, original_text, framed_text}  -- L2 또는 L3 강제
     ├── anchor {when, after_what, where}  -- Tiny Habits
     ├── stack_position  -- after-this-then-that 순서 (선택)
     ├─< if_then_rule (n)
     ├─< tracker_entry (n, daily)
     ├─< lapse_log (n)         -- break 위주
     ├─< urge_log (n, 선택)    -- break 위주
     └─< reward_claim (n)      -- milestone 달성 시

catalog 측:

protocol  ──< protocol_reference >── reference  (M:N)
break_protocol ──< break_reference >── reference
methodology ──< methodology_reference >── reference

§3. 운영 규칙 (DB level constraint로 적용)

본 프로젝트 메모리에서 도출된 가드레일을 schema에 박는다.

ID 규칙 적용 위치 출처
R1 user당 동시 active build habit ≤ 3 habit.status='active' AND type='build' 집계 feedback_sustainable_minimal.md
R2 user당 동시 active break habit ≤ 1 habit.status='active' AND type='break' 집계 project_habit_breaking_module.md
R3 habit.frame.level ∈ {L2, L3} 강제 (L0 거부) enum 제약 feedback_positive_framing.md
R4 reward_declarationphase.started_at 후 7일 안에만 생성 timestamp 검증 feedback_reward_ladder.md (사전성)
R5 tracker_entry.value ∈ {done, blank} 2값만 enum (×·이모지 X) 6 가드레일 #6
R6 phase.duration_weeks = 6 (default), 6주 전 anchor 변동 X 변경 시 warning 6 가드레일 #5
R7 if_then_rule.then_action 회피 키워드 감지 시 warning 클라이언트 검증 코끼리 회피 UX
R8 habit 일일 운영 ≤ 2분 (tracker UI 30~60초) UX 제약 (DB X) 6 가드레일 #2
R9 habit.dose_variants[] 개수 제한 없음. 단 체크인 화면은 "장소 1탭 + 컨디션 1탭 → 추천 + override" 흐름으로 R8 유지. is_minimum=true variant는 0개 이상 허용 (강제 X). application + UI docs/adr/0001-dose-variants.md
R10 reflection.scope='weekly'minimum_ratio (해당 주 done 중 is_minimum 비율) 표시. 강제 임계값 없음 — hint 용도. application 계산 docs/adr/0001-dose-variants.md

§4. 핵심 enum 정의

HabitType: ["build", "break"]
HabitStatus: ["active", "paused", "completed", "abandoned"]
FrameLevel: ["L0", "L1", "L2", "L3"]   # L0/L1은 입력 차단 (warning + 변환 제안)
TrackerValue: ["done", "blank"]         # ○/공백 2값
RewardTier: ["T0", "T1", "T2", "T3", "T4"]
                                          # T0=매일 / T1=3회 스트릭 / T2=7일 / T3=30일 / T4=42일(6주)
LapseFieldHALT: ["hungry", "angry", "lonely", "tired", "none"]
ProtocolCategory: ["health", "meditation", "motivation", "habit", "learning", "diet"]
                                          # huberman-protocols.md §1~§5 + nutrition/diet-protocols.md (별도 모듈)
BreakCategory: ["alcohol", "nicotine", "porn_masturbation",
                "social_media", "sugar", "caffeine", "cannabis", "behavioral"]
CommonFrameId: ["dopamine_reset", "urge_surf",
                "environment_design", "relapse_recovery", "recovery_stack"]

§5. JSON Schema 파일 목록 (./schema/)

Catalog

  • protocol.schema.json — Huberman atomic protocol
  • break_protocol.schema.json — 끊기 카테고리
  • common_frame.schema.json — 끊기 공통 프레임 5개
  • methodology.schema.json — 21개 방법론
  • frame_pattern.schema.json — L0→L2/L3 변환표
  • reward_menu_item.schema.json — 보상 메뉴
  • reference.schema.json — DOI/URL/책

User

  • user.schema.json
  • phase.schema.json
  • habit.schema.json
  • if_then_rule.schema.json
  • tracker_entry.schema.json
  • lapse_log.schema.json
  • urge_log.schema.json
  • reward_declaration.schema.json
  • reward_claim.schema.json
  • reflection.schema.json

메타

  • enums.schema.json — 위 §4 enum 통합 정의 ($ref로 재사용)
  • _index.json — 전체 스키마 인덱스 + 운영 규칙 메타

§6. 사용 예시 (단일 사용자, build 습관 1개)

habit (build, L2 프레임)

{
  "id": "hb_01J9...",
  "user_id": "u_local_default",
  "type": "build",
  "status": "active",
  "title": "아침 햇빛 10분",
  "protocol_id": "huberman_1_1_morning_sunlight",
  "break_protocol_id": null,
  "frame": {
    "level": "L2",
    "original_text": "햇빛 안 빼먹기",
    "framed_text": "기상 직후 야외에서 햇빛 10분 받기"
  },
  "anchor": {
    "when": "06:30",
    "after_what": "기상 직후",
    "where": "현관 앞 야외"
  },
  "if_then_rules": [
    { "if": "비 오는 날이면", "then": "20분으로 늘려서 우산 쓰고 나간다" }
  ],
  "started_at": "2026-06-04",
  "phase_id": "ph_2026Q2_1",
  "stack_position": 1
}

tracker_entry (일일)

{ "id": "te_...", "habit_id": "hb_01J9...", "date": "2026-06-04", "value": "done", "logged_at": "2026-06-04T06:42:00+09:00" }

reward_declaration (phase 시작 시 사전 선언)

{
  "id": "rd_...",
  "phase_id": "ph_2026Q2_1",
  "habit_id": "hb_01J9...",
  "tier": "T3",
  "milestone_rule": "30일 중 24일 이상 done",
  "reward_text": "주말 1박 단기 여행",
  "estimated_cost_krw": 150000,
  "declared_at": "2026-06-04T20:00:00+09:00"
}

habit (break, L3 프레임)

{
  "id": "hb_brk_01...",
  "user_id": "u_local_default",
  "type": "break",
  "status": "active",
  "title": "평일 무알콜",
  "protocol_id": null,
  "break_protocol_id": "alcohol",
  "common_frame_ids": ["dopamine_reset", "environment_design", "recovery_stack"],
  "frame": {
    "level": "L3",
    "original_text": "술 끊기",
    "framed_text": "나는 평일 무알콜인 사람이다"
  },
  "anchor": { "when": "18:00", "after_what": "퇴근", "where": "집 거실" },
  "phase_id": "ph_2026Q2_1"
}

lapse_log (LEARN 5)

{
  "id": "ll_...",
  "habit_id": "hb_brk_01...",
  "date": "2026-06-10",
  "label_text": "회식에서 맥주 2잔. 데이터로 처리.",
  "examine_halt": ["tired", "lonely"],
  "antecedent": ["회식 자리", "20시 늦은 식사", "동료 권유"],
  "replan": "If 회식 공지 받으면, then 첫잔 무알콜 사전 선언 + 동료에게 알림",
  "next_action": "다음 평일은 즉시 정상 진행. Never miss twice."
}

§7. 단일 vs 멀티 사용자 호환 전략

  • 모든 user data 엔티티에 user_id 필수 필드.
  • 단일 사용자 local 앱: user_id = "u_local_default" 고정.
  • 클라우드 멀티 사용자: auth 서비스의 sub/uid를 그대로 user_id로 매핑.
  • catalog 엔티티에는 user_id 없음 (모든 사용자 공유).
  • ID 형식: ULID 권장 (hb_01J9...). prefix는 엔티티 타입.

§8. 마이그레이션 노트

  • v1은 minimal viable. 다음 항목은 v2 이후 고려:
    • habit_stack (Atomic Habits #5 — 여러 habit 묶음 운영)
    • dashboard_preference (사용자별 트래커 UI 옵션)
    • notification_rule (알림/cron 트리거)
    • social_link (Recovery Stack의 "1-person check-in" 파트너)
    • integration_* (Apple Health / Google Fit / Notion sync)
  • enum 추가는 backward compatible. enum 제거/이름 변경은 마이그레이션 스크립트 필수.

§9. 다음 단계 제안

  1. 본 문서 + ./schema/*.json 리뷰.
  2. seed catalog 데이터 채우기 (Huberman 29개 + break 8개 + methodology 21개) — ./seed/*.json.
  3. 검증기(Ajv 등)로 schema 적합성 확인.
  4. UI 와이어프레임 (트래커 30초, 대시보드 1화면 등) — 별도 문서.
  5. 백엔드 결정 (SQLite local-first 권장 → 추후 Supabase 등으로 확장).