| 항목 | 내용 |
| 기능 ID | FEAT-CARE |
| 연결 시스템 | 마스터 시스템② 보고(건강·복약 케어) · ⑤ 가족연결 |
| 한 줄 정의 | 복약/혈압 등을 정해진 시간에 알리고 기록하며, 미복약이 반복되면 가족·돌봄에 자동 보고 |
| 관련 액터 | PWA실벗서버아리가족 |
설계 철학 — 알림은 "잔소리"가 아니라 아리의 다정한 챙김이어야 합니다. 그리고 거른 약은 조용히 가족에게 보고되어, 멀리 있어도 안심하게 만듭니다.
▍설계 7계층 체크리스트
| 계층 | 이 문서의 섹션 |
| ① UI | 복약 알림 카드 SCR-CARE-01 / 건강 기록 화면 |
| ② Flow | 복약 상태 머신 + 미복약 에스컬레이션 |
| ③ Data | medications / med_logs / health_records (확장) |
| ④ API | 복약 등록·확인·기록·건강측정 엔드포인트 |
| ⑤ Seq | 예약 알림 → 복약확인 → 미복약 보고 시퀀스 |
| ⑥ Comp | 알림 스케줄러·복약 워커 구조 |
| ⑦ Test | 검수 체크리스트 |
② Flow · 복약 상태 머신
예약됨→
알림 발송→
대기(스누즈)→
복약완료
/
미복약→보고
▍미복약 에스컬레이션
| 시점 | 동작 |
| 정시 | 복약 알림(푸시+TTS) 발송, 상태=알림발송 |
| +15분 무응답 | 1회 재알림(스누즈) |
| +30분 무응답 | 아리가 안부 말걸기 ("약 챙기셨어요?") |
| +60분 미확인 | 상태=미복약 기록 → 가족에게 조용히 보고(설정 시) |
③ Data · DB 스키마
기존 p25의 medications·med_logs·health_records 재활용 + 미복약 보고용 컬럼 확장.
MariaDB · UTF8MB4 · InnoDB
CREATE TABLE medications (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT NOT NULL,
name VARCHAR(100),
dosage VARCHAR(60), -- '1정', '5mg'
times JSON, -- ["08:00","20:00"]
photo_url VARCHAR(255),
report_family TINYINT DEFAULT 1, -- 미복약 시 가족 보고 여부
is_active TINYINT DEFAULT 1,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE med_logs (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
med_id BIGINT NOT NULL,
scheduled_at DATETIME NOT NULL,
status ENUM('taken','missed','snoozed') DEFAULT 'snoozed',
taken_at DATETIME,
reported TINYINT DEFAULT 0, -- 가족 보고 완료 플래그
UNIQUE KEY uq_sched (med_id, scheduled_at), -- 멱등성: 중복 알림 방지
FOREIGN KEY (med_id) REFERENCES medications(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
설계 포인트 — med_logs의 UNIQUE(med_id, scheduled_at)로 같은 시간 알림 중복 생성을 원천 차단. 스케줄러가 여러 번 돌아도 안전.
④ API · 엔드포인트 명세
| M | 경로 | 설명 |
| GET | /care/medications | 내 복약 목록·오늘 일정 |
| POST | /care/medications | 복약 등록(이름·시간·사진) |
| POST | /care/logs/{id}/take | 복약 확인("먹었어요") |
| POST | /care/health | 건강 측정값 기록(혈압·혈당·체중) |
| GET | /care/health/weekly | 주간 건강 추이 |
POST /api/v1/care/logs/123/take · 200
{
"success": true,
"data": { "status":"taken", "taken_at":"2026-06-18T08:12:00+09:00",
"message":"잘 하셨어요! 오늘도 건강하세요 😊" }
}
⑥ Comp · 컴포넌트 / 모듈 구조
프론트엔드 (PWA)
features/care/
├─ MedicationCard.js # 복약 알림 카드
├─ HealthInputView.js # 건강 측정 입력
├─ HealthChart.js # 주간 그래프
└─ careApi.js
백엔드 (PHP)
app/
├─ Controllers/CareController.php
├─ Services/
│ ├─ MedicationService.php # 등록·확인·일정
│ └─ HealthService.php # 측정값·추이
└─ Jobs/
├─ MedReminderJob.php # cron 알림 발송(멱등)
└─ MissedMedReportJob.php # 미복약 가족 보고
| 모듈 | 책임 |
MedReminderJob | 분단위 cron. med_logs를 멱등 생성하고 푸시/TTS 발송. 여러 번 실행돼도 중복 알림 없음. |
MissedMedReportJob | 미복약 판정 + 가족 보고. 존엄 가드(과보고 방지) 적용. |
⑦ Test · 검수 체크리스트
| ID | 시나리오 | 기대 결과 |
| T-01 | 복약 시간 도래 | 푸시+TTS 알림, 복약 카드 표시 |
| T-02 | "먹었어요 ✓" 탭 | status=taken, 격려 메시지, 홈 위젯 ✓ 반영 |
| T-03 | 15분 무응답 | 1회 재알림(스누즈) |
| T-04 | 60분 미확인 + report_family=1 | status=missed, 가족에게 보고 발송 |
| T-05 | 스케줄러 중복 실행 | UNIQUE 제약으로 중복 알림 0건 |
| T-06 | 혈압 위험 수치 입력 | 경고 색상 + (설정) 가족 알림 |
완료 판정 — T-01~T-06 통과 시 FEAT-CARE 완료. T-05(멱등)·T-04(가족 보고)가 신뢰성의 핵심.
기능설계 ④ 완성 — 챙김과 보고를 7계층으로 설계했습니다. 멀리 있는 가족도 "오늘 약 드셨다"를 알 수 있습니다.