Initial commit — life-helper Phase 1~5 완료 상태

4 SoT 모듈:
- huberman-protocols.md (v4, 29 Huberman 원자 프로토콜, 33 인용 검증 완료)
- habit-todo-methodologies.md (21 방법론 + 6 가드레일 + 5-Tier Reward + L0~L3 프레임)
- habit-breaking-protocols.md (끊기 8 카테고리 + 공통 5 프레임 + 의학적 면책)
- nutrition/ 별도 Gitea repo (joungmin/nutrition) — .gitignore 처리

데이터 모델:
- data-model.md — entity 관계 + R1~R8 운영 규칙 + 예시
- schema/ — JSON Schema 18개 (Draft 2020-12), R1~R8을 enum + application + UI 3층 강제

운영 가드레일:
- 동시 active build ≤ 3, break ≤ 1
- 일일 운영 ≤ 2분
- frame.level ∈ {L2, L3} (L0/L1 거부)
- tracker_entry.value = done/blank 2값
- phase = 6주 사이클
- reward는 누적 milestone(T0~T4)만, 매일 직후 X
- "Never miss twice"

진행 중: Dose Variant 설계 결정 대기 (SESSION-LOG.md Pending #1)
This commit is contained in:
2026-06-08 14:47:17 +09:00
commit 3141bf005f
26 changed files with 3420 additions and 0 deletions

59
schema/_index.json Normal file
View File

@@ -0,0 +1,59 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://life-helper.local/schema/_index.json",
"title": "life-helper schema index v1",
"description": "전체 스키마 목록 + 운영 규칙 메타. 자세한 설계는 data-model.md 참조.",
"version": "1.0.0",
"schemas": {
"catalog": {
"protocol": "./protocol.schema.json",
"break_protocol": "./break_protocol.schema.json",
"common_frame": "./common_frame.schema.json",
"methodology": "./methodology.schema.json",
"frame_pattern": "./frame_pattern.schema.json",
"reward_menu_item": "./reward_menu_item.schema.json",
"reference": "./reference.schema.json"
},
"user_data": {
"user": "./user.schema.json",
"phase": "./phase.schema.json",
"habit": "./habit.schema.json",
"if_then_rule": "./if_then_rule.schema.json",
"tracker_entry": "./tracker_entry.schema.json",
"lapse_log": "./lapse_log.schema.json",
"urge_log": "./urge_log.schema.json",
"reward_declaration": "./reward_declaration.schema.json",
"reward_claim": "./reward_claim.schema.json",
"reflection": "./reflection.schema.json"
},
"shared": {
"enums": "./enums.schema.json"
}
},
"operational_rules": [
{ "id": "R1", "rule": "user당 동시 active build habit ≤ 3", "enforced_in": "habit query / application layer" },
{ "id": "R2", "rule": "user당 동시 active break habit ≤ 1", "enforced_in": "habit query / application layer" },
{ "id": "R3", "rule": "habit.frame.level ∈ {L2, L3} 강제 (L0/L1 거부)", "enforced_in": "habit.schema.json (enum)" },
{ "id": "R4", "rule": "reward_declaration은 phase.started_at + 7일 이내에만 생성", "enforced_in": "application layer" },
{ "id": "R5", "rule": "tracker_entry.value ∈ {done, blank} 2값만", "enforced_in": "tracker_entry.schema.json (enum)" },
{ "id": "R6", "rule": "phase.duration_weeks = 6 default, 6주 중간 anchor 변경 warning", "enforced_in": "application layer" },
{ "id": "R7", "rule": "if_then_rule.then_action 회피 키워드 감지 시 warning", "enforced_in": "client-side linter" },
{ "id": "R8", "rule": "habit 일일 운영 ≤ 2분 (UX 제약)", "enforced_in": "UI design (not in schema)" }
],
"id_format": {
"scheme": "ULID with type prefix",
"examples": {
"user": "u_01J9XYZ...",
"habit": "hb_01J9XYZ...",
"tracker_entry": "te_01J9XYZ...",
"phase": "ph_01J9XYZ...",
"lapse_log": "ll_01J9XYZ...",
"urge_log": "ul_01J9XYZ...",
"reward_declaration": "rd_01J9XYZ...",
"reward_claim": "rc_01J9XYZ...",
"if_then_rule": "if_01J9XYZ...",
"reflection": "rf_01J9XYZ...",
"reference": "ref_doi_10_1136_bmj_j2353"
}
}
}

View File

@@ -0,0 +1,54 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://life-helper.local/schema/break_protocol.schema.json",
"title": "Break Protocol (끊기 카테고리)",
"description": "habit-breaking-protocols.md §2의 카테고리별 프로토콜.",
"type": "object",
"required": ["id", "category", "title", "huberman_summary", "phases", "default_common_frames"],
"additionalProperties": false,
"properties": {
"id": { "type": "string", "description": "보통 category 값과 동일" },
"category": { "$ref": "enums.schema.json#/$defs/BreakCategory" },
"title": { "type": "string" },
"huberman_summary": { "type": "string", "description": "Huberman 핵심 메시지 요약" },
"frame_examples": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["level", "text"],
"properties": {
"level": { "$ref": "enums.schema.json#/$defs/FrameLevelAllowed" },
"text": { "type": "string" }
}
}
},
"phases": {
"type": "array",
"description": "단계식 프로토콜 (예: 4주 알코올 점진 감량)",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["week", "goal"],
"properties": {
"week": { "type": "integer", "minimum": 1 },
"goal": { "type": "string" },
"environment_design": { "type": "string" },
"if_then_examples": { "type": "array", "items": { "type": "string" } }
}
}
},
"default_common_frames": {
"type": "array",
"items": { "$ref": "enums.schema.json#/$defs/CommonFrameId" },
"description": "이 카테고리에 권장되는 공통 프레임 ID 목록"
},
"tools": {
"type": "array",
"items": { "type": "string" },
"description": "추천 도구 (DNS 필터·앱·하드웨어)"
},
"medical_warning": { "type": "string", "description": "의학적 면책/응급 경고" },
"reference_ids": { "type": "array", "items": { "type": "string" } }
}
}

View File

@@ -0,0 +1,23 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://life-helper.local/schema/common_frame.schema.json",
"title": "Common Frame (끊기 공통 프레임 5개)",
"description": "habit-breaking-protocols.md §1 — Dopamine Reset · Urge Surf · Environment Design · Relapse Recovery · Recovery Stack.",
"type": "object",
"required": ["id", "title", "what", "why", "how", "check"],
"additionalProperties": false,
"properties": {
"id": { "$ref": "enums.schema.json#/$defs/CommonFrameId" },
"title": { "type": "string" },
"what": { "type": "string" },
"why": { "type": "string" },
"dose": { "type": "string" },
"how": { "type": "array", "items": { "type": "string" } },
"check": { "type": "string" },
"applicable_break_categories": {
"type": "array",
"items": { "$ref": "enums.schema.json#/$defs/BreakCategory" }
},
"reference_ids": { "type": "array", "items": { "type": "string" } }
}
}

82
schema/enums.schema.json Normal file
View File

@@ -0,0 +1,82 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://life-helper.local/schema/enums.schema.json",
"title": "Shared Enums",
"description": "모든 스키마에서 $ref로 재사용되는 열거형 정의.",
"$defs": {
"HabitType": { "type": "string", "enum": ["build", "break"] },
"HabitStatus": { "type": "string", "enum": ["active", "paused", "completed", "abandoned"] },
"FrameLevel": {
"type": "string",
"enum": ["L0", "L1", "L2", "L3"],
"description": "L0=회피형(거부), L1=단순대체(임시), L2=조건부 긍정(권장), L3=정체성(6주 후 권장)"
},
"FrameLevelAllowed": {
"type": "string",
"enum": ["L2", "L3"],
"description": "habit.frame.level은 L2/L3만 허용 (R3)"
},
"TrackerValue": {
"type": "string",
"enum": ["done", "blank"],
"description": "○/공백 2값만 (R5)"
},
"RewardTier": {
"type": "string",
"enum": ["T0", "T1", "T2", "T3", "T4"],
"description": "T0=매일 직후 Celebration, T1=3회 스트릭, T2=7일, T3=30일, T4=42일(6주)"
},
"HALT": {
"type": "string",
"enum": ["hungry", "angry", "lonely", "tired", "none"]
},
"ProtocolCategory": {
"type": "string",
"enum": ["health", "meditation", "motivation", "habit", "learning", "diet"]
},
"BreakCategory": {
"type": "string",
"enum": [
"alcohol", "nicotine", "porn_masturbation", "social_media",
"sugar", "caffeine", "cannabis", "behavioral"
]
},
"CommonFrameId": {
"type": "string",
"enum": [
"dopamine_reset", "urge_surf", "environment_design",
"relapse_recovery", "recovery_stack"
]
},
"EvidenceStrength": {
"type": "string",
"enum": ["strong_rct", "meta_analysis", "observational", "mechanistic", "expert_opinion"],
"description": "출처 강도 레이블"
},
"ReferenceKind": {
"type": "string",
"enum": ["paper", "podcast_episode", "book", "url", "korean_explainer"],
"description": "korean_explainer는 한국어 해설자(인플루언서) cross-reference 전용 — 핵심 인용 X"
},
"DateString": {
"type": "string",
"format": "date",
"description": "YYYY-MM-DD"
},
"DateTimeString": {
"type": "string",
"format": "date-time",
"description": "ISO 8601 (timezone 포함 권장)"
},
"TimeOfDay": {
"type": "string",
"pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$",
"description": "HH:MM (24시간)"
},
"Ulid": {
"type": "string",
"pattern": "^[a-z]+_[0-9A-HJKMNP-TV-Z]{26}$",
"description": "타입 prefix + ULID. 예: hb_01J9XYZ..."
}
}
}

View File

@@ -0,0 +1,24 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://life-helper.local/schema/frame_pattern.schema.json",
"title": "Frame Pattern (L0→L2/L3 변환표)",
"description": "habit-todo-methodologies.md §언어 프레이밍 — 회피형 입력을 긍정 프레임으로 자동 변환 제안.",
"type": "object",
"required": ["id", "avoidance_keyword", "l0_example", "l2_suggestion"],
"additionalProperties": false,
"properties": {
"id": { "type": "string" },
"domain": {
"type": "string",
"enum": ["food", "drink", "smoking", "screen", "porn", "sleep", "exercise", "general"]
},
"avoidance_keyword": {
"type": "string",
"description": "감지할 회피형 키워드 (끊기/안/그만/줄이기/멈추기 등)"
},
"l0_example": { "type": "string", "description": "원본 회피형 예시" },
"l1_simple_replace": { "type": "string", "description": "단순 대체 (임시)" },
"l2_suggestion": { "type": "string", "description": "조건부 긍정 (default 추천)" },
"l3_identity": { "type": "string", "description": "정체성 프레임 (6주 후 권장)" }
}
}

57
schema/habit.schema.json Normal file
View File

@@ -0,0 +1,57 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://life-helper.local/schema/habit.schema.json",
"title": "Habit (사용자 습관 — build 또는 break)",
"description": "active 상태에서 build ≤ 3, break ≤ 1 (R1/R2). frame.level은 L2/L3만 허용 (R3).",
"type": "object",
"required": ["id", "user_id", "type", "status", "title", "frame", "anchor", "started_at"],
"additionalProperties": false,
"properties": {
"id": { "type": "string" },
"user_id": { "type": "string" },
"phase_id": { "type": "string", "description": "소속 phase. null이면 phase 외 운영" },
"type": { "$ref": "enums.schema.json#/$defs/HabitType" },
"status": { "$ref": "enums.schema.json#/$defs/HabitStatus" },
"title": { "type": "string", "description": "사용자가 보는 짧은 제목 (≤ 20자 권장)" },
"protocol_id": { "type": ["string", "null"], "description": "catalog protocol 참조 (type=build)" },
"break_protocol_id": { "type": ["string", "null"], "description": "catalog break_protocol 참조 (type=break)" },
"common_frame_ids": {
"type": "array",
"items": { "$ref": "enums.schema.json#/$defs/CommonFrameId" },
"description": "type=break 시 활성화할 공통 프레임 ID"
},
"frame": {
"type": "object",
"additionalProperties": false,
"required": ["level", "framed_text"],
"properties": {
"level": { "$ref": "enums.schema.json#/$defs/FrameLevelAllowed" },
"original_text": { "type": "string", "description": "사용자의 최초 입력 (L0일 수 있음, 감사 목적)" },
"framed_text": { "type": "string", "description": "L2 또는 L3로 변환된 최종 문장" }
}
},
"anchor": {
"type": "object",
"additionalProperties": false,
"properties": {
"when": { "$ref": "enums.schema.json#/$defs/TimeOfDay" },
"after_what": { "type": "string", "description": "Tiny Habits anchor — 직전 행동" },
"where": { "type": "string" }
}
},
"stack_position": {
"type": "integer", "minimum": 1,
"description": "Atomic Habits #5 habit stacking 순서"
},
"min_dose": { "type": "string", "description": "시작 doseo (Tiny Habits)" },
"target_dose": { "type": "string" },
"started_at": { "$ref": "enums.schema.json#/$defs/DateString" },
"ended_at": { "$ref": "enums.schema.json#/$defs/DateString" },
"tags": { "type": "array", "items": { "type": "string" } },
"x_constraint": {
"description": "참고용 메타 — 검증은 application layer에서 수행 (XOR protocol_id vs break_protocol_id)",
"type": "string",
"const": "type=build → protocol_id 채움 / type=break → break_protocol_id 채움 (반대쪽은 null)"
}
}
}

View File

@@ -0,0 +1,27 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://life-helper.local/schema/if_then_rule.schema.json",
"title": "If-Then Rule (Implementation Intention)",
"description": "Gollwitzer If-Then. habit당 ≤ 3개 권장. then_action에 회피 키워드 감지 시 warning (R7).",
"type": "object",
"required": ["id", "habit_id", "if_condition", "then_action"],
"additionalProperties": false,
"properties": {
"id": { "type": "string" },
"habit_id": { "type": "string" },
"if_condition": {
"type": "string",
"description": "if 절. 시간/맥락/감정/직전 행동 기반 (예: 'If 22시 평일에 충동 나면')"
},
"then_action": {
"type": "string",
"description": "then 절. 긍정 행동 (예: 'then 거실에서 산책 5분 + 차가운 물 한 잔')"
},
"trigger_type": {
"type": "string",
"enum": ["time", "location", "emotion", "preceding_action", "urge"]
},
"priority": { "type": "integer", "minimum": 1, "maximum": 3, "default": 1 },
"created_at": { "$ref": "enums.schema.json#/$defs/DateTimeString" }
}
}

View File

@@ -0,0 +1,39 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://life-helper.local/schema/lapse_log.schema.json",
"title": "Lapse Log (LEARN 5필드)",
"description": "habit-breaking-protocols.md §1.4 — 재발 후 24시간 안에 작성. 자기비판 차단 + 데이터화.",
"type": "object",
"required": ["id", "habit_id", "date", "label_text", "examine_halt", "antecedent", "replan", "next_action"],
"additionalProperties": false,
"properties": {
"id": { "type": "string" },
"habit_id": { "type": "string" },
"date": { "$ref": "enums.schema.json#/$defs/DateString" },
"label_text": {
"type": "string",
"description": "L (Label) — 'lapse 발생. 실패가 아닌 데이터.' 형태"
},
"examine_halt": {
"type": "array",
"items": { "$ref": "enums.schema.json#/$defs/HALT" },
"description": "E (Examine HALT) — Hungry/Angry/Lonely/Tired 중 해당 항목"
},
"antecedent": {
"type": "array",
"items": { "type": "string" },
"minItems": 1,
"maxItems": 5,
"description": "A (Antecedent) — 트리거 3개 이상 권장 (시간/장소/사람/감정/직전 행동)"
},
"replan": {
"type": "string",
"description": "R (Replan) — 추가 If-Then 또는 환경 디자인 1개"
},
"next_action": {
"type": "string",
"description": "N (Next) — 24시간 안에 즉시 실행. 'Never miss twice'"
},
"created_at": { "$ref": "enums.schema.json#/$defs/DateTimeString" }
}
}

View File

@@ -0,0 +1,30 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://life-helper.local/schema/methodology.schema.json",
"title": "Methodology (21개 방법론)",
"description": "habit-todo-methodologies.md의 방법론 카드.",
"type": "object",
"required": ["id", "name", "originator", "one_line_definition", "core_unit", "huberman_fit_score"],
"additionalProperties": false,
"properties": {
"id": { "type": "string", "description": "예: atomic_habits, gtd, tiny_habits" },
"name": { "type": "string" },
"originator": { "type": "string", "description": "창시자 + 연도" },
"one_line_definition": { "type": "string" },
"core_unit": { "type": "string", "description": "핵심 작업 단위 (habit / task / project ...)" },
"procedure": { "type": "array", "items": { "type": "string" } },
"tools": { "type": "array", "items": { "type": "string" } },
"strengths": { "type": "array", "items": { "type": "string" } },
"weaknesses": { "type": "array", "items": { "type": "string" } },
"good_for": { "type": "string", "description": "잘 맞는 사용자 프로파일" },
"huberman_fit_score": {
"type": "integer", "minimum": 1, "maximum": 5,
"description": "Huberman 결합 적합도 ⭐1~5"
},
"is_core_engine": {
"type": "boolean",
"description": "본 프로젝트의 핵심 운영 엔진 (Atomic Habits / Tiny Habits / Implementation Intentions만 true)"
},
"reference_ids": { "type": "array", "items": { "type": "string" } }
}
}

32
schema/phase.schema.json Normal file
View File

@@ -0,0 +1,32 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://life-helper.local/schema/phase.schema.json",
"title": "Phase (6주 사이클)",
"description": "사용자당 동시 active phase는 1개 권장. 6주 단위 운영.",
"type": "object",
"required": ["id", "user_id", "started_at", "duration_weeks", "status"],
"additionalProperties": false,
"properties": {
"id": { "type": "string" },
"user_id": { "type": "string" },
"title": { "type": "string", "description": "예: '2026 Q2 1차 — 아침 루틴 정착'" },
"started_at": { "$ref": "enums.schema.json#/$defs/DateString" },
"ended_at": { "$ref": "enums.schema.json#/$defs/DateString" },
"duration_weeks": { "type": "integer", "minimum": 1, "default": 6 },
"status": { "type": "string", "enum": ["active", "completed", "abandoned"] },
"habit_ids": {
"type": "array",
"items": { "type": "string" },
"description": "이 phase에 등록된 habit. build ≤ 3, break ≤ 1 (R1/R2)"
},
"intention_text": {
"type": "string",
"description": "이번 6주에 만들고 싶은 정체성 (L3 미리보기)"
},
"reward_declarations_locked": {
"type": "boolean",
"default": false,
"description": "phase 시작 후 7일 지나면 자동 true → 추가 reward_declaration 차단 (R4)"
}
}
}

View File

@@ -0,0 +1,51 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://life-helper.local/schema/protocol.schema.json",
"title": "Protocol (원자 프로토콜 — Huberman + Diet)",
"description": "huberman-protocols.md와 diet-protocols.md의 atomic protocol 카탈로그. 7필드 통일 구조.",
"type": "object",
"required": ["id", "category", "title", "what", "when", "dose", "why", "how", "check"],
"additionalProperties": false,
"properties": {
"id": { "type": "string", "description": "예: huberman_1_1_morning_sunlight" },
"category": { "$ref": "enums.schema.json#/$defs/ProtocolCategory" },
"title": { "type": "string", "description": "한국어 제목" },
"title_en": { "type": "string" },
"what": { "type": "string", "description": "무엇을" },
"when": { "type": "string", "description": "언제" },
"dose": { "type": "string", "description": "얼마나 (수치 + 단위)" },
"why": { "type": "string", "description": "왜 (메커니즘)" },
"how": {
"type": "array",
"items": { "type": "string" },
"minItems": 1,
"description": "절차 단계 (순서대로)"
},
"check": { "type": "string", "description": "체크 방법" },
"caution": { "type": "string", "description": "주의 (옵션)" },
"default_anchor": {
"type": "object",
"additionalProperties": false,
"properties": {
"when": { "$ref": "enums.schema.json#/$defs/TimeOfDay" },
"after_what": { "type": "string" },
"where": { "type": "string" }
},
"description": "사용자가 habit에 채택할 때의 default anchor 제안"
},
"min_dose_for_start": {
"type": "string",
"description": "Tiny Habits 시작 doseo (예: '햇빛 2분', '운동 1세트'). 6주 사이클 첫 주용."
},
"reference_ids": {
"type": "array",
"items": { "type": "string" },
"description": "reference.id 배열"
},
"evidence_strength": { "$ref": "enums.schema.json#/$defs/EvidenceStrength" },
"source_doc": {
"type": "string",
"enum": ["huberman-protocols.md", "diet-protocols.md"]
}
}
}

View File

@@ -0,0 +1,23 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://life-helper.local/schema/reference.schema.json",
"title": "Reference (인용 출처)",
"type": "object",
"required": ["id", "kind", "title"],
"additionalProperties": false,
"properties": {
"id": { "type": "string", "description": "안정 식별자. 예: ref_doi_10_1136_bmj_j2353" },
"kind": { "$ref": "enums.schema.json#/$defs/ReferenceKind" },
"title": { "type": "string" },
"authors": { "type": "array", "items": { "type": "string" } },
"year": { "type": "integer", "minimum": 1900, "maximum": 2100 },
"journal": { "type": "string", "description": "kind=paper 시" },
"doi": { "type": "string", "description": "kind=paper 시 우선" },
"url": { "type": "string", "format": "uri" },
"episode_number": { "type": "integer", "description": "kind=podcast_episode (HL ep #N)" },
"publisher": { "type": "string", "description": "kind=book 시" },
"evidence_strength": { "$ref": "enums.schema.json#/$defs/EvidenceStrength" },
"verified": { "type": "boolean", "description": "DOI/URL 실제 확인 여부" },
"note": { "type": "string", "description": "근거 한계 / 인용 주의" }
}
}

View File

@@ -0,0 +1,22 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://life-helper.local/schema/reflection.schema.json",
"title": "Reflection (주/월/6주 회고)",
"description": "자유 텍스트 회고. 주간 또는 phase 종료 시점에 작성.",
"type": "object",
"required": ["id", "user_id", "scope", "period_start", "period_end"],
"additionalProperties": false,
"properties": {
"id": { "type": "string" },
"user_id": { "type": "string" },
"scope": { "type": "string", "enum": ["weekly", "monthly", "phase_end"] },
"period_start": { "$ref": "enums.schema.json#/$defs/DateString" },
"period_end": { "$ref": "enums.schema.json#/$defs/DateString" },
"phase_id": { "type": ["string", "null"] },
"kept": { "type": "string", "description": "잘 유지된 것 (Atomic Habits 4법칙 관점)" },
"missed": { "type": "string", "description": "결석/lapse 패턴 — 자책 아닌 데이터 처리" },
"adjust": { "type": "string", "description": "다음 주기에 바꿀 것 1개만" },
"identity_note": { "type": "string", "description": "L3 정체성 변화 감각 (옵션)" },
"created_at": { "$ref": "enums.schema.json#/$defs/DateTimeString" }
}
}

View File

@@ -0,0 +1,24 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://life-helper.local/schema/reward_claim.schema.json",
"title": "Reward Claim (실제 milestone 달성 기록)",
"description": "reward_declaration의 milestone_rule이 충족된 시점 + 사용자가 실제 보상을 받았는지.",
"type": "object",
"required": ["id", "declaration_id", "milestone_reached_at", "fulfilled"],
"additionalProperties": false,
"properties": {
"id": { "type": "string" },
"declaration_id": { "type": "string" },
"milestone_reached_at": { "$ref": "enums.schema.json#/$defs/DateTimeString" },
"fulfilled": {
"type": "boolean",
"description": "사용자가 실제로 보상을 받았는지 (선언만 하고 안 받을 수도 있음)"
},
"fulfilled_at": { "$ref": "enums.schema.json#/$defs/DateTimeString" },
"reflection": {
"type": "string",
"maxLength": 500,
"description": "보상을 받고 난 후 짧은 회고 (옵션)"
}
}
}

View File

@@ -0,0 +1,34 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://life-helper.local/schema/reward_declaration.schema.json",
"title": "Reward Declaration (사전 선언 보상)",
"description": "phase.started_at 후 7일 안에만 생성 가능 (R4). 사후 즉흥 결정 차단 — variable schedule 강박 방지.",
"type": "object",
"required": ["id", "phase_id", "habit_id", "tier", "milestone_rule", "reward_text", "declared_at"],
"additionalProperties": false,
"properties": {
"id": { "type": "string" },
"phase_id": { "type": "string" },
"habit_id": { "type": "string" },
"tier": { "$ref": "enums.schema.json#/$defs/RewardTier" },
"milestone_rule": {
"type": "string",
"description": "체크 조건 (예: '7일 중 6일 done', '30일 중 24일 done', '3회 연속 done')"
},
"milestone_machine_rule": {
"type": "object",
"additionalProperties": false,
"description": "선택 — 기계 평가용. 예: { window_days: 30, min_done: 24 }",
"properties": {
"window_days": { "type": "integer", "minimum": 1 },
"min_done": { "type": "integer", "minimum": 1 },
"require_consecutive": { "type": "boolean" }
}
},
"reward_text": { "type": "string", "description": "사용자가 본인 언어로 작성 (SDT autonomy)" },
"reward_menu_item_id": { "type": ["string", "null"], "description": "카탈로그에서 선택했다면 참조" },
"estimated_cost_krw": { "type": "integer", "minimum": 0 },
"is_effort_tied": { "type": "boolean" },
"declared_at": { "$ref": "enums.schema.json#/$defs/DateTimeString" }
}
}

View File

@@ -0,0 +1,36 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://life-helper.local/schema/reward_menu_item.schema.json",
"title": "Reward Menu Item (보상 메뉴 카탈로그)",
"description": "사용자가 reward_declaration 만들 때 고를 수 있는 추천 메뉴. 사용자 자유 입력도 가능 (custom=true).",
"type": "object",
"required": ["id", "tier_recommended", "title"],
"additionalProperties": false,
"properties": {
"id": { "type": "string" },
"tier_recommended": { "$ref": "enums.schema.json#/$defs/RewardTier" },
"title": { "type": "string" },
"description": { "type": "string" },
"estimated_cost_krw_range": {
"type": "object",
"additionalProperties": false,
"properties": {
"min": { "type": "integer", "minimum": 0 },
"max": { "type": "integer", "minimum": 0 }
}
},
"is_effort_tied": {
"type": "boolean",
"description": "Huberman-친화: effort 자체와 연결된 보상 (등산/장거리 라이딩 등) — T4 권장"
},
"tags": {
"type": "array",
"items": { "type": "string", "enum": ["experience", "object", "social", "rest", "learning", "hobby"] }
},
"avoid_for_break_habits": {
"type": "array",
"items": { "$ref": "enums.schema.json#/$defs/BreakCategory" },
"description": "끊기 습관과 충돌하는 보상 차단 (예: 알코올 끊기에 와인 보상 금지)"
}
}
}

View File

@@ -0,0 +1,17 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://life-helper.local/schema/tracker_entry.schema.json",
"title": "Tracker Entry (일일 ○/공백)",
"description": "(habit_id, date) unique. value는 done/blank 2값만 (R5). 일일 운영 30~60초.",
"type": "object",
"required": ["id", "habit_id", "date", "value"],
"additionalProperties": false,
"properties": {
"id": { "type": "string" },
"habit_id": { "type": "string" },
"date": { "$ref": "enums.schema.json#/$defs/DateString" },
"value": { "$ref": "enums.schema.json#/$defs/TrackerValue" },
"logged_at": { "$ref": "enums.schema.json#/$defs/DateTimeString" },
"note": { "type": "string", "maxLength": 200, "description": "선택. 길게 쓰지 말 것" }
}
}

View File

@@ -0,0 +1,26 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://life-helper.local/schema/urge_log.schema.json",
"title": "Urge Log (충동 발생/통과)",
"description": "habit-breaking-protocols.md §1.2 Urge Surf. 선택 사항. 비율(통과/발생)이 시간 따라 상승 추적.",
"type": "object",
"required": ["id", "habit_id", "occurred_at", "passed"],
"additionalProperties": false,
"properties": {
"id": { "type": "string" },
"habit_id": { "type": "string" },
"occurred_at": { "$ref": "enums.schema.json#/$defs/DateTimeString" },
"intensity_before": { "type": "integer", "minimum": 0, "maximum": 10 },
"intensity_after": { "type": "integer", "minimum": 0, "maximum": 10 },
"duration_seconds": { "type": "integer", "minimum": 0 },
"body_location": {
"type": "array",
"items": { "type": "string", "enum": ["chest", "throat", "abdomen", "hands", "head", "other"] }
},
"passed": { "type": "boolean", "description": "true=urge surf 성공, false=행동으로 이어짐(lapse)" },
"method_used": {
"type": "string",
"enum": ["cyclic_sighing", "walk", "water", "social_contact", "if_then_action", "other"]
}
}
}

45
schema/user.schema.json Normal file
View File

@@ -0,0 +1,45 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://life-helper.local/schema/user.schema.json",
"title": "User",
"description": "단일 local 사용자는 id='u_local_default' 고정. 멀티는 auth uid 매핑.",
"type": "object",
"required": ["id", "created_at"],
"additionalProperties": false,
"properties": {
"id": { "type": "string", "description": "ULID 또는 'u_local_default'" },
"display_name": { "type": "string" },
"locale": { "type": "string", "default": "ko-KR" },
"timezone": { "type": "string", "default": "Asia/Seoul" },
"created_at": { "$ref": "enums.schema.json#/$defs/DateTimeString" },
"preferences": {
"type": "object",
"additionalProperties": false,
"properties": {
"celebration_style": {
"type": "string",
"enum": ["verbal", "gesture", "emoji", "silent"],
"default": "verbal",
"description": "T0 매일 직후 Celebration 방식 (Fogg's Shine)"
},
"warn_on_avoidance_keywords": { "type": "boolean", "default": true },
"preferred_methodology_ids": {
"type": "array",
"items": { "type": "string" },
"description": "기본 운영 엔진 선택 (default: atomic_habits + tiny_habits + implementation_intentions)"
},
"huberman_stack_enabled": {
"type": "object",
"additionalProperties": false,
"properties": {
"morning_sunlight": { "type": "boolean", "default": true },
"exercise": { "type": "boolean", "default": true },
"nsdr": { "type": "boolean", "default": true },
"cyclic_sighing": { "type": "boolean", "default": false },
"social_checkin": { "type": "boolean", "default": false }
}
}
}
}
}
}