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:
59
schema/_index.json
Normal file
59
schema/_index.json
Normal 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
54
schema/break_protocol.schema.json
Normal file
54
schema/break_protocol.schema.json
Normal 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" } }
|
||||
}
|
||||
}
|
||||
23
schema/common_frame.schema.json
Normal file
23
schema/common_frame.schema.json
Normal 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
82
schema/enums.schema.json
Normal 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..."
|
||||
}
|
||||
}
|
||||
}
|
||||
24
schema/frame_pattern.schema.json
Normal file
24
schema/frame_pattern.schema.json
Normal 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
57
schema/habit.schema.json
Normal 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)"
|
||||
}
|
||||
}
|
||||
}
|
||||
27
schema/if_then_rule.schema.json
Normal file
27
schema/if_then_rule.schema.json
Normal 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" }
|
||||
}
|
||||
}
|
||||
39
schema/lapse_log.schema.json
Normal file
39
schema/lapse_log.schema.json
Normal 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" }
|
||||
}
|
||||
}
|
||||
30
schema/methodology.schema.json
Normal file
30
schema/methodology.schema.json
Normal 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
32
schema/phase.schema.json
Normal 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)"
|
||||
}
|
||||
}
|
||||
}
|
||||
51
schema/protocol.schema.json
Normal file
51
schema/protocol.schema.json
Normal 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"]
|
||||
}
|
||||
}
|
||||
}
|
||||
23
schema/reference.schema.json
Normal file
23
schema/reference.schema.json
Normal 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": "근거 한계 / 인용 주의" }
|
||||
}
|
||||
}
|
||||
22
schema/reflection.schema.json
Normal file
22
schema/reflection.schema.json
Normal 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" }
|
||||
}
|
||||
}
|
||||
24
schema/reward_claim.schema.json
Normal file
24
schema/reward_claim.schema.json
Normal 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": "보상을 받고 난 후 짧은 회고 (옵션)"
|
||||
}
|
||||
}
|
||||
}
|
||||
34
schema/reward_declaration.schema.json
Normal file
34
schema/reward_declaration.schema.json
Normal 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" }
|
||||
}
|
||||
}
|
||||
36
schema/reward_menu_item.schema.json
Normal file
36
schema/reward_menu_item.schema.json
Normal 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": "끊기 습관과 충돌하는 보상 차단 (예: 알코올 끊기에 와인 보상 금지)"
|
||||
}
|
||||
}
|
||||
}
|
||||
17
schema/tracker_entry.schema.json
Normal file
17
schema/tracker_entry.schema.json
Normal 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": "선택. 길게 쓰지 말 것" }
|
||||
}
|
||||
}
|
||||
26
schema/urge_log.schema.json
Normal file
26
schema/urge_log.schema.json
Normal 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
45
schema/user.schema.json
Normal 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 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user