Skip to content

Commit 06fbf59

Browse files
KayWalkerKayWalker
authored andcommitted
feat: add mindcare notifications
1 parent 06041f8 commit 06fbf59

34 files changed

+11923
-93
lines changed

README.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,22 @@ GROQ_API_KEY=your_key ./scripts/run.sh run
101101

102102
## 🛠 변경 사항 (Changelog)
103103

104-
### v1.4.11 (Current)
104+
### v1.4.12 (Current)
105+
* **마음 케어 알림 활성화 UX:**
106+
* **설정 토글 추가:** 마음 케어 알림을 설정에서 구독/해제 가능
107+
* **첫 활성화 환영 다이얼로그:** SharedPreferences 기반 1회 안내 + 재활성화 SnackBar 피드백
108+
* **Analytics 이벤트 추가:** mindcare_enabled / mindcare_disabled 로깅
109+
* **마음 케어 발송 인프라 구축:**
110+
* **Cloud Functions 추가:** 매일 오전 9시(KST) 자동 발송, 관리자용 HTTP API(수동 발송/메시지 추가/상태 조회)
111+
* **FCM 토픽 발송 서비스:** mindlog_mindcare 토픽 메시지 전송 및 공통 payload 구성
112+
* **Firestore 구성/보안:** 메시지/발송 로그/통계 컬렉션, rules 및 indexes 추가
113+
* **문서/자산 정리:**
114+
* **개인정보 처리방침 경로 변경:** `docs/legal/privacy-policy.md` 기준으로 assets 연동
115+
* **테스트 보강:**
116+
* **에러/서킷브레이커/업데이트:** FailureMapper, 예외/Failure, CircuitBreaker, UpdateService, NotificationService 테스트 추가
117+
* **UI/도메인:** MindcareWelcomeDialog 위젯 테스트, NotificationSettings 엔티티 테스트 추가
118+
119+
### v1.4.11
105120
* **트러블슈팅 문서 시스템 추가:**
106121
* **트러블슈팅 게시판:** GitHub Pages에 알려진 이슈와 해결 방법을 확인할 수 있는 페이지 추가
107122
* **웹 모달 마크다운 뷰어:** MD 파일을 다운로드 없이 웹에서 바로 확인 가능

WARP.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CLAUDE.md

docs/archive/update.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
{
2-
"latestVersion": "1.4.11",
2+
"latestVersion": "1.4.12",
33
"minSupportedVersion": "1.3.0",
44
"forceUpdate": false,
55
"androidUrl": "https://play.google.com/store/apps/details?id=com.mindlog.mindlog",
66
"iosUrl": "",
77
"changelog": {
8+
"1.4.12": [
9+
"마음 케어 알림을 설정에서 켜고 끌 수 있어요.",
10+
"처음 켤 때 안내 팝업이 표시돼요.",
11+
"매일 아침 따뜻한 마음 케어 메시지가 도착해요."
12+
],
813
"1.4.11": [
914
"트러블슈팅 게시판이 추가되어 알려진 이슈를 웹에서 바로 확인할 수 있어요.",
1015
"MD 파일을 다운로드 없이 웹 모달에서 바로 확인 가능해요.",
@@ -66,5 +71,5 @@
6671
"설정 화면에서 앱 버전을 바로 확인할 수 있어요."
6772
]
6873
},
69-
"updatedAt": "2026-01-09"
74+
"updatedAt": "2026-01-10"
7075
}

docs/assets/web/index.html

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -126,22 +126,22 @@ <h3>반응형 UI</h3>
126126
<section id="updates" class="updates">
127127
<div class="container">
128128
<h2 class="section-title">최근 개선</h2>
129-
<p class="section-lede">v1.4.11에서는 트러블슈팅 문서 시스템을 추가하고 Release 빌드 알림 안정성을 강화했어요.</p>
129+
<p class="section-lede">v1.4.12에서는 마음 케어 알림을 정식으로 열고, 매일 아침 자동 발송 시스템을 구축했어요.</p>
130130
<div class="updates-grid">
131131
<article class="update-card">
132-
<span class="update-tag">Documentation</span>
133-
<h3>트러블슈팅 게시판</h3>
134-
<p>알려진 이슈와 해결 방법을 웹에서 바로 확인할 수 있어요.</p>
132+
<span class="update-tag">Feature</span>
133+
<h3>마음 케어 알림</h3>
134+
<p>설정에서 알림을 켜면 매일 아침 따뜻한 메시지를 받을 수 있어요.</p>
135135
</article>
136136
<article class="update-card">
137-
<span class="update-tag">UX</span>
138-
<h3>웹 모달 마크다운 뷰어</h3>
139-
<p>MD 파일을 다운로드 없이 웹 모달에서 바로 확인 가능해요.</p>
137+
<span class="update-tag">Onboarding</span>
138+
<h3>첫 활성화 안내</h3>
139+
<p>처음 켤 때 안내 다이얼로그로 기능 사용 방법을 바로 확인할 수 있어요.</p>
140140
</article>
141141
<article class="update-card">
142-
<span class="update-tag">Stability</span>
143-
<h3>알림 안정성 강화</h3>
144-
<p>Release 빌드에서 예약 알림이 정상 동작하도록 수정했어요.</p>
142+
<span class="update-tag">Automation</span>
143+
<h3>자동 발송 시스템</h3>
144+
<p>Firebase Functions 기반으로 정해진 시간에 메시지가 자동 발송되도록 구성했어요.</p>
145145
</article>
146146
</div>
147147
</div>

firebase.json

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,51 @@
1-
{"flutter":{"platforms":{"android":{"default":{"projectId":"mindlog-7e235","appId":"1:274694888964:android:0d38372910eb25c6dedf51","fileOutput":"android/app/google-services.json"}},"ios":{"default":{"projectId":"mindlog-7e235","appId":"1:274694888964:ios:29f64395b977e39ddedf51","uploadDebugSymbols":false,"fileOutput":"ios/Runner/GoogleService-Info.plist"}},"dart":{"lib/firebase_options.dart":{"projectId":"mindlog-7e235","configurations":{"android":"1:274694888964:android:0d38372910eb25c6dedf51","ios":"1:274694888964:ios:29f64395b977e39ddedf51"}}}}}}
1+
{
2+
"flutter": {
3+
"platforms": {
4+
"android": {
5+
"default": {
6+
"projectId": "mindlog-7e235",
7+
"appId": "1:274694888964:android:0d38372910eb25c6dedf51",
8+
"fileOutput": "android/app/google-services.json"
9+
}
10+
},
11+
"ios": {
12+
"default": {
13+
"projectId": "mindlog-7e235",
14+
"appId": "1:274694888964:ios:29f64395b977e39ddedf51",
15+
"uploadDebugSymbols": false,
16+
"fileOutput": "ios/Runner/GoogleService-Info.plist"
17+
}
18+
},
19+
"dart": {
20+
"lib/firebase_options.dart": {
21+
"projectId": "mindlog-7e235",
22+
"configurations": {
23+
"android": "1:274694888964:android:0d38372910eb25c6dedf51",
24+
"ios": "1:274694888964:ios:29f64395b977e39ddedf51"
25+
}
26+
}
27+
}
28+
}
29+
},
30+
"functions": [
31+
{
32+
"source": "functions",
33+
"codebase": "default",
34+
"ignore": [
35+
"node_modules",
36+
".git",
37+
"firebase-debug.log",
38+
"firebase-debug.*.log",
39+
"*.local"
40+
],
41+
"predeploy": [
42+
"npm --prefix \"$RESOURCE_DIR\" run lint",
43+
"npm --prefix \"$RESOURCE_DIR\" run build"
44+
]
45+
}
46+
],
47+
"firestore": {
48+
"rules": "firestore.rules",
49+
"indexes": "firestore.indexes.json"
50+
}
51+
}

firestore.indexes.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"indexes": [
3+
{
4+
"collectionGroup": "mindcare_messages",
5+
"queryScope": "COLLECTION",
6+
"fields": [
7+
{ "fieldPath": "scheduledAt", "order": "ASCENDING" },
8+
{ "fieldPath": "status", "order": "ASCENDING" }
9+
]
10+
},
11+
{
12+
"collectionGroup": "mindcare_messages",
13+
"queryScope": "COLLECTION",
14+
"fields": [
15+
{ "fieldPath": "status", "order": "ASCENDING" },
16+
{ "fieldPath": "createdAt", "order": "ASCENDING" }
17+
]
18+
}
19+
],
20+
"fieldOverrides": []
21+
}

firestore.rules

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
rules_version = '2';
2+
3+
/**
4+
* MindLog Firestore 보안 규칙
5+
*
6+
* 마음케어 관련 컬렉션:
7+
* - mindcare_messages: 발송 메시지 저장
8+
* - mindcare_sent_log: 발송 이력 (중복 방지)
9+
* - mindcare_stats: 발송 통계
10+
*
11+
* 보안 정책:
12+
* - 클라이언트 읽기/쓰기 차단 (Functions만 접근)
13+
* - Admin SDK는 규칙 우회 (자동)
14+
*/
15+
service cloud.firestore {
16+
match /databases/{database}/documents {
17+
18+
// 마음케어 메시지 - Functions만 접근
19+
match /mindcare_messages/{messageId} {
20+
allow read, write: if false;
21+
}
22+
23+
// 발송 로그 - Functions만 접근
24+
match /mindcare_sent_log/{logId} {
25+
allow read, write: if false;
26+
}
27+
28+
// 발송 통계 - Functions만 접근
29+
match /mindcare_stats/{statId} {
30+
allow read, write: if false;
31+
}
32+
33+
// 스케줄 설정 - Functions만 접근
34+
match /mindcare_schedules/{scheduleId} {
35+
allow read, write: if false;
36+
}
37+
38+
// 기타 문서는 기본 거부
39+
match /{document=**} {
40+
allow read, write: if false;
41+
}
42+
}
43+
}

functions/.eslintrc.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
module.exports = {
2+
root: true,
3+
env: {
4+
es6: true,
5+
node: true,
6+
},
7+
extends: [
8+
"eslint:recommended",
9+
"plugin:import/errors",
10+
"plugin:import/warnings",
11+
"plugin:import/typescript",
12+
"plugin:@typescript-eslint/recommended",
13+
],
14+
parser: "@typescript-eslint/parser",
15+
parserOptions: {
16+
project: ["tsconfig.json"],
17+
sourceType: "module",
18+
},
19+
ignorePatterns: [
20+
"/lib/**/*",
21+
],
22+
plugins: [
23+
"@typescript-eslint",
24+
"import",
25+
],
26+
rules: {
27+
"quotes": ["error", "double"],
28+
"import/no-unresolved": 0,
29+
"indent": ["error", 2],
30+
"@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }],
31+
"max-len": ["warn", { "code": 100 }],
32+
},
33+
};

functions/.gitignore

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Compiled JavaScript files
2+
lib/
3+
4+
# Node modules
5+
node_modules/
6+
7+
# TypeScript cache
8+
*.tsbuildinfo
9+
10+
# Environment files
11+
.env
12+
.env.local
13+
14+
# IDE
15+
.idea/
16+
.vscode/
17+
*.swp
18+
*.swo
19+
20+
# Logs
21+
*.log
22+
npm-debug.log*
23+
24+
# OS
25+
.DS_Store
26+
Thumbs.db

0 commit comments

Comments
 (0)