docs: accept adr 0005 journal module decisions
This commit is contained in:
@@ -1,16 +1,128 @@
|
||||
# 0005 — Journal / mood tracking research
|
||||
# 0005 — Journal / mood tracking
|
||||
|
||||
Date: 2026-07-03
|
||||
Status: proposed
|
||||
Status: accepted (2026-07-04)
|
||||
|
||||
## Context
|
||||
|
||||
Journal module (task 86) needs mood multi-select, charts over time, and insights. Research existing libraries/components for mood tracking or journaling and record build-vs-adopt. Gitea: [#20](https://gitea.ginnoir.com/ginnoir/famapp/issues/20) (epic [#19](https://gitea.ginnoir.com/ginnoir/famapp/issues/19)).
|
||||
Journal module (task 86) needs per-user entries, mood multi-select, charts over time, insights, and `/api/v1/journal` endpoints. ADR research included [Giftyaning/Mood-Tracker](https://github.com/Giftyaning/Mood-Tracker) (Gitea [#20](https://gitea.ginnoir.com/ginnoir/famapp/issues/20), epic [#19](https://gitea.ginnoir.com/ginnoir/famapp/issues/19)).
|
||||
|
||||
## Build-vs-adopt: Mood-Tracker
|
||||
|
||||
**Decision: do not adopt the repo.**
|
||||
|
||||
| Factor | Mood-Tracker | famapp need |
|
||||
| ---------- | -------------------------- | ------------------------------------------- |
|
||||
| License | None | Must have clear reuse rights |
|
||||
| Stack | Vite SPA, JS, localStorage | Next.js 15, TypeScript, Postgres, Authentik |
|
||||
| Mood model | Single-select, 5 presets | Multi-select fixed catalog |
|
||||
| Fields | Title + plain text | Optional title + TipTap HTML, stress, pills |
|
||||
| API / auth | None | `/api/v1/` + session + bearer token |
|
||||
| Code shape | One 672-line `App.jsx` | `src/modules/journal/` manifest pattern |
|
||||
|
||||
**Borrow (reimplement in TypeScript):** mood→numeric scoring, day streak, week-over-week trend, insight card layout. Not copied source.
|
||||
|
||||
## What we decided (2026-07-04)
|
||||
|
||||
| # | Topic | Choice |
|
||||
| --- | -------------- | --------------------------------------------------------------------------------------------------- |
|
||||
| 1 | Charts | **Build natively + Recharts** for mood/stress trends and correlation views |
|
||||
| 2 | Moods | **Fixed catalog** (~8–12 presets with emoji + color); **multi-select** |
|
||||
| 3 | Entries | **Multiple per day** allowed |
|
||||
| 4 | Stress | Optional **1–10** slider |
|
||||
| 5 | Insights v1 | **Core + correlations** — streak, top mood, avg stress; stress↔mood and pills↔avg-mood simple stats |
|
||||
| 6 | Index calendar | **Month grid** with dots on days that have entries; tap day → filtered list |
|
||||
| 7 | Entry shape | **Optional title** + rich-text body (shared `RichTextEditor`) |
|
||||
| 8 | Chart points | **All entries** as individual points; x-axis uses **datetime** (not date-only rollup) |
|
||||
|
||||
## Decision
|
||||
|
||||
To be filled when research completes.
|
||||
### Module: `src/modules/journal/`
|
||||
|
||||
Standard module layout: `schema.ts`, `manifest.tsx`, `server/`, `components/`, app routes under `/journal`.
|
||||
|
||||
### Data model
|
||||
|
||||
Table `journal_entries`:
|
||||
|
||||
- `household_id` — household scope for DB consistency
|
||||
- `user_id` — **per-user privacy**; all reads/writes filter `user_id = current user`
|
||||
- `recorded_at` timestamptz — required date+time (defaults to now on create)
|
||||
- `title` text nullable — optional
|
||||
- `body` text — HTML from shared rich-text editor (ADR 0004)
|
||||
- `moods` jsonb — array of catalog mood ids (multi-select)
|
||||
- `stress` smallint nullable — 1–10
|
||||
- `pills_taken` boolean nullable
|
||||
|
||||
No household-shared journal in v1. Wife cannot see Matt's entries and vice versa.
|
||||
|
||||
### Mood catalog
|
||||
|
||||
Fixed in code (`src/modules/journal/mood-catalog.ts`): ids, label, emoji, color, numeric score for analytics. Users pick from catalog only (no custom tags in v1).
|
||||
|
||||
### UI surfaces
|
||||
|
||||
| Route | Purpose |
|
||||
| ------------------------------- | -------------------------------------------------------------------------------------- |
|
||||
| `/journal` | Recent 5–10 entries, browse all link, month calendar, links to mood tracker + insights |
|
||||
| `/journal/new`, `/journal/[id]` | Create/edit entry (date/time required; rest optional) |
|
||||
| `/journal/mood` | Recharts mood/stress over time (all entry points) |
|
||||
| `/journal/insights` | Streak, top mood, correlations |
|
||||
|
||||
Rich text: `RichTextEditor` / `RichTextContent` from `src/components/rich-text/`. No share viewer in v1.
|
||||
|
||||
### Insights v1
|
||||
|
||||
- Entry streak (consecutive days with ≥1 entry)
|
||||
- Most common mood (selected period)
|
||||
- Average stress (7d / 30d)
|
||||
- Week-over-week mood trend (score-based)
|
||||
- **Correlations:** simple aggregates — avg mood score on days pills taken vs not; stress vs mood score scatter or grouped averages
|
||||
|
||||
No ML / sentiment analysis in v1.
|
||||
|
||||
### API
|
||||
|
||||
Additive on ADR 0006 foundation:
|
||||
|
||||
- `GET/POST /api/v1/journal/entries`
|
||||
- `GET/PATCH/DELETE /api/v1/journal/entries/:id`
|
||||
|
||||
Bearer token and session auth. Responses scoped to **token owner's user id** for journal (household token acts as owner user for API mutations per existing pattern, but journal entries are always stored with the authenticated user's id).
|
||||
|
||||
Document in `docs/api/openapi.yaml`.
|
||||
|
||||
### Testing
|
||||
|
||||
- Playwright: `tests/e2e/journal.spec.ts` — create minimal entry → list → detail → mood tracker loads
|
||||
- Unit tests for mood scoring / streak helpers where non-trivial
|
||||
|
||||
## Consequences
|
||||
|
||||
To be filled when research completes.
|
||||
### Positive
|
||||
|
||||
- Recharts gives proper time-series without maintaining custom chart code for long trends.
|
||||
- Fixed mood catalog keeps insights comparable across entries.
|
||||
- Per-user privacy matches personal journal expectations.
|
||||
- Reuses rich-text stack from task 85.
|
||||
|
||||
### Trade-offs
|
||||
|
||||
- All-entry chart points mean busy days show multiple dots; datetime x-axis required.
|
||||
- Fixed catalog may miss nuance — body text carries freeform detail.
|
||||
- Correlation stats are descriptive only (no causation); keep copy honest in UI.
|
||||
- Recharts adds bundle weight on `/journal/mood` and `/journal/insights` only (route-level code split).
|
||||
|
||||
### Out of scope (ADR)
|
||||
|
||||
- Household-shared journals
|
||||
- LLM agent tools for journal (task 88)
|
||||
- Custom user-defined mood tags
|
||||
- Share links for journal entries
|
||||
|
||||
## References
|
||||
|
||||
- Task brief: `docs/tasks/86-journal-module.md`
|
||||
- Rich text: `docs/decisions/0004-rich-text-editor.md`
|
||||
- API: `docs/decisions/0006-api-llm-agent.md`
|
||||
- Mood-Tracker research: https://github.com/Giftyaning/Mood-Tracker
|
||||
|
||||
@@ -27,6 +27,6 @@ What this costs us, what it buys us.
|
||||
- [0002 — List realtime uses Postgres NOTIFY and SSE](0002-list-sse-notify.md)
|
||||
- [0003 — Release workflow (commitlint + release-it)](0003-release-workflow.md)
|
||||
- [0004 — Rich-text editor library and storage format](0004-rich-text-editor.md) (accepted 2026-07-04)
|
||||
- [0005 — Journal / mood tracking research](0005-journal-research.md) (proposed)
|
||||
- [0005 — Journal / mood tracking](0005-journal-research.md) (accepted 2026-07-04)
|
||||
- [0006 — API auth and LLM agent architecture](0006-api-llm-agent.md) (accepted 2026-07-04)
|
||||
<!-- END AUTO-GENERATED -->
|
||||
|
||||
Reference in New Issue
Block a user