Beneficiary Care

Development plan + system mock-up · Area 1 · Quỹ Hoa Mặt Trời

An internal beneficiary management system — markdown profiles + SQLite + a small dashboard, kept on a private Drive, never a SaaS.

The picture in one paragraph

Every child the Foundation supports gets one structured profile on a private Foundation Shared Drive: identity, programme, progress notes, and benefits delivered. A small set of Python tools in this repo writes to that store; a tiny FastAPI dashboard lets principals and trustees read the cohort and add light updates; Claude assists with entry drafting and report writing. No public surface; the Drive's membership list is the access boundary. The 8-petal model is the spine that runs through every record — every note and benefit row carries a petal anchor, so storytelling and Area-4 reporting can both surface it.

Architecture · what lives where

Private Foundation Drive This repo (code + tools) AI engine

Private Foundation Drive

  • profiles/journey-NNNN.mdFour-block markdown profile per child. Canonical record.
  • benefits-ledger/journey-NNNN/Dated entries + receipts + handover photos.
  • intake/<YYYY-Www>/Raw inbox: notebook write-ups, Zalo exports, scanned letters.
  • indexes/by-cohort, by-school, by-child/_search.md
  • registry-beneficiary.sqlitechild / benefit / profile_entry tables. WAL.
  • cohort-dashboard/<YYYY-Qn>.mdQuarterly trustee summary, generated.
  • funding_sources.yamlEnum of contribution refs. Area-3-maintained.

This repo · tools/

  • beneficiary_registry_migrate.pyCreates the 3 SQLite tables. One-shot, idempotent.
  • beneficiary_validate.pySchema check on a profile file. bundle_validate analogue.
  • beneficiary_promote.pyPromote an intake item to a profile entry + SQL row.
  • benefit_record.pyWrite a ledger entry + benefit row. Enum-validates funding_source.
  • benefit_report.pySQL views → markdown for Area-4. HXL-CSV emitter.
  • beneficiary_index_rebuild.pyNightly indexes + quarterly cohort dashboard.
  • beneficiary_consistency_check.pyDrift between SQL rows ↔ markdown files.
  • media_sanitise.py --verifyExisting media-line tool, reused at promotion boundary.

UI + AI

  • app/ (FastAPI)Internal dashboard. Cohort view + child detail + add-note + analytics.
  • beneficiary-recorder agentClaude Opus structures a raw drop into a profile entry.
  • report-writer (Claude)Drafts the monthly Area-4 narrative from benefit_report SQL output.
  • journey-writer (Stream C)Reads Block 3 + ledger; drafts long-form progress narrative.
  • HMT Foundation WorkspaceGoogle Workspace; Drive desktop client mounts the private Drive locally.

The five-step pathway

The same shape as the media line's intake → curate → draft → QC → review-queue, scoped to a child's record. Steps 1–3 run weekly; step 4 only on escalation; step 5 quarterly.

Step 1
Drop
Coordinator drops raw materials into intake/<YYYY-Www>/<journey-id>/. EXIF stripped here.
Step 2
Review
Monday-morning pass: _review.md notes which items get promoted, kept as context, or escalated.
Step 3
Promote
Claude drafts a structured entry from the raw drop; Coordinator edits + approves; beneficiary_promote.py commits it.
Step 4
Safeguarding
Only on escalation. Safeguarding lead reads the proposed entry + raw drop, signs off in commit message.
Step 5
Archive
Quarterly: move intake/intake-archive/<YYYY-Qn>/. Profiles are living docs, never archived.

AI + automation · what runs unattended

Entry drafting (Claude)

claude-opus-4-7 · beneficiary-recorder · on demand

Reads a raw drop (notebook scan, Zalo thread, report-card PDF) and returns a markdown progress-note in the canonical shape. Factual structuring, not tone.

Report writing (Claude)

claude-opus-4-7 · report_child / cohort / school · on demand + monthly

Composes the narrative wrapper around the SQL view for per-child, per-cohort, and per-school reports. Claims trace back to the structured sections; no invented detail. Audience filter narrows what's included.

Stream-C journeys (Claude)

claude-opus-4-7 · journey-writer · on demand

Reads Block 3 + benefits ledger only; drafts a long-form progress narrative. The format choice when the Coordinator wants a journey-shaped piece, not an event piece.

Safeguarding watchlist (signal job)

safeguarding_watchlist.py · monthly + daily-keyword

Scheduled job, no AI. Seven simple rules — absence >60d, followup overdue, benefit anomaly, status drift, keyword hit, coordinator drift, sibling cluster — surface items into the lead's triage queue. Job never signs off gate 8; the named human still decides.

Build sequence

Seven phases, in increasing operational risk. The hand-rolled pilot (B-zero) runs in parallel with the first two coding phases — the data shape gets stress-tested by a real coordinator on real cases before the code locks.

B0
Parallel to B1+B2

Operational pilot · one school, five children

Pick one partner school + one coordinator + five children. The coordinator drafts five profiles by hand in the canonical markdown shape, drops five weeks of intake material, walks the pathway end-to-end on paper.

What's true after B0: five real profiles in the canonical shape; coordinator can describe the weekly rhythm; the schema's last-mile adjustments feed B2's prompt.
B1
1–2 days · code

Data shapes + registry migration

The schema lands. SQLite on the private Drive gets the three tables; the profile validator runs against fixture profiles.

  • beneficiary_registry_migrate.py — creates child, benefit, profile_entry
  • beneficiary_validate.py — frontmatter + petal + append-only checks
  • 2 example synthetic profiles in tests/fixtures/beneficiary/
What's true after B1: SQLite is queryable; a profile file can be validated; tests pass against synthetic fixtures.
B2
3–5 days · code + agent

Intake + promotion (Claude-assisted)

A coordinator can take a raw drop, get a Claude-drafted entry, edit it, and commit it to the profile + SQL.

  • beneficiary-recorder agent + /record skill — the Claude-Opus prompt
  • beneficiary_promote.py — the operational verb (commit + index update)
  • Pre-commit hook: media_sanitise.py --verify on intake files
  • Fake-API tests via the CaptionEngine-style protocol pair
What's true after B2: the weekly pathway works end-to-end on the operator box. The Coordinator can run a week's drops through the pipeline in < 1 hour.
B3
3–5 days · code

Benefits ledger + Area-4 hooks

The Foundation can write a benefit, query by month/programme/school/funding-source/petal, and emit a draft narrative for the monthly report.

  • benefit_record.py — write a ledger entry; validates funding_source against funding_sources.yaml
  • benefit_report.py — SQL views → markdown for Area-4; HXL-CSV emitter
  • Claude drafts the narrative wrapper around the numbers
What's true after B3: "where did the money go this month" is one command. Sponsor queries (funding_source = X) are one query.
B4
2–3 days · code

Indexes + cohort dashboard

The three indexes (by-cohort, by-school, by-child) and the quarterly cohort dashboard regenerate nightly. Drift between SQL rows ↔ markdown files surfaces in a daily check.

  • beneficiary_index_rebuild.py — nightly rebuild
  • beneficiary_consistency_check.py — selftest exits zero on a clean run
What's true after B4: a coordinator scanning the by-cohort index sees the family cluster at a glance; trustees read the quarterly dashboard directly.
B5
3–4 days · code + Claude

Parameterised reports (per-child / per-cohort / per-school)

Three CLI tools sharing one backbone: SQL view → Claude-drafted narrative → markdown / PDF / HXL-CSV. Same code path runs from the dashboard and from the scheduled monthly publication run.

  • tools/report_child.py — single journey-NNNN; case review, hand-off, sponsor view
  • tools/report_cohort.py — programme × cohort year (e.g. Cùng em tiến bước 2026)
  • tools/report_school.py — partner school; the principal's monthly read
  • Audience filter (coordinator / safeguarding / principal / trustee / sponsor) narrows what each output includes
What's true after B5: "give me everything about this child" is one button. "Give me Q2's view of this school" is one query. Reports save to reports/<YYYY>/ for diffable comparison over time.
B6
3–4 days · code + cron

Safeguarding watchlist (monthly autonomous signal run)

The named safeguarding sign-off stays manual; what becomes autonomous is the signal detection that feeds the lead's triage queue. The job reads the registry monthly + profile markdown, applies seven independent rules, surfaces items the lead reviews.

  • tools/safeguarding_watchlist.py — runs monthly (full sweep) + daily (keyword-only narrower pass)
  • Seven signals: absence (60d), followup overdue (45d), benefit anomaly (90d zero), status drift, keyword hit, coordinator drift, sibling cluster
  • Each item lands in the watchlist_item SQL table with an audit trail
  • 01_Beneficiaries/watchwords.yaml — lead reviews quarterly
  • Job never clears gate 8. Surfaces signals, never makes decisions.
What's true after B6: on the 1st of each month the lead opens the dashboard's watchlist screen and sees a triaged queue. The Coordinator's weekly review becomes the first-line catch; the watchlist is the second-line backstop.
B7
5–8 days · app

FastAPI dashboard for principals + trustees + safeguarding lead

A small internal web app on top of the SQLite store. Read the cohort, see one child's full record, add a progress note, generate reports, triage the safeguarding watchlist. Two-way sync: the app writes to the same store the markdown tools do; coordinators still own the canonical markdown.

  • app/ — FastAPI + a typed schema layer over the SQLite
  • Read + light data entry: progress notes, followups, benefits
  • Reports surface: per-child / per-cohort / per-school generation with audience picker
  • Safeguarding watchlist screen: each item is a card the lead acts on (dismiss / coord-followup / escalate / re-surface)
  • Login via Google Workspace; charts via CSS + light JS
What's true after B7: a principal logs in, sees their school's cohort, generates a monthly report; a trustee sees cohort-level analytics; the safeguarding lead works their triage queue on the 1st of every month. See the mock-up below.

Stack summary

LayerChoiceWhy
StorageMarkdown profiles + SQLite (WAL)Human-readable canonical record + fast queryable shape. No Postgres / no SaaS DB at this scale.
HostingPrivate Google Shared Drive + Drive desktop clientFoundation already lives in Google Workspace; the Drive's own membership list is the access boundary.
ToolsPython 3.11; 6–8 small CLI scriptsEach < 200 LOC; matches the media-line discipline; selftest on every tool.
AIClaude Opus 4.7 · Anthropic SDK · prompt cachingAlready wired for the media line; reuses the CaptionEngine pattern.
AppFastAPI + HTMX, server-rendered HTMLNo SPA build pipeline; a single Python developer can run the whole stack; Cloud Run or a single VM deploys it.
AuthGoogle Workspace SSOPrincipals + trustees already have Workspace accounts; no separate user DB.
BackupDrive revision history + nightly SQLite snapshotDrive gives version history on every file; SQLite snapshot rotated weekly.

The dashboard — a clickable mock-up

High-fidelity prototype of the B5 FastAPI dashboard. Click the tabs to walk through the screens — login, cohort list, one child's profile, adding a progress note (Claude-assisted), the benefits ledger, the analytics view, and the report-export panel. Mock data; no real persistence.

app.hmt-foundation.org.vn/login
— signed out —

Cohort 2026 156 students · 6 schools

JourneyNameSchool · ClassProgrammeLast updateStatus
journey-0042 Nguyễn Thị Mai · nữ · 14t+1 sib THCS Tân Khánh · 8A2Cùng em tiến bước18/05/2026 active
journey-0017 Nguyễn Thị Lan · nữ · 16t+1 sib THCS Tân Khánh · 10B1Cùng em tiến bước15/05/2026 active
journey-0043 Trần Văn Đức · nam · 13t THCS Tân Khánh · 8A1Cùng em tiến bước16/05/2026 active
journey-0044 Lê Thị Hồng · nữ · 15t THCS Tân Khánh · 9CCùng em tiến bước12/05/2026 active
journey-0045 Phạm Minh Tuấn · nam · 12t THCS Tân Khánh · 7BCùng em tiến bước08/05/2026 paused
journey-1102 Nguyễn Văn An · nam · 11t THCS Vụ Bản · 6ANâng bước tương lai10/05/2026 active
journey-1118 Đặng Thị Hà · nữ · 17t THCS Vụ Bản · 11A2Nâng bước tương lai14/05/2026 graduated
journey-1135 Vũ Hoàng Long · nam · 14t+2 sib THCS Vụ Bản · 8BNâng bước tương lai20/05/2026 active
journey-1136 Vũ Hoàng Mai · nữ · 9t+2 sib Tiểu học An Ninh · 4BCùng em tiến bước19/05/2026 active
journey-2071 Hoàng Thị Mỹ Linh · nữ · 8t Tiểu học An Ninh · 3ACùng em tiến bước22/05/2026 active
journey-2092 Bùi Quang Huy · nam · 10t Tiểu học An Ninh · 5CTrao gửi yêu thương11/03/2026 paused
journey-3018 Đỗ Thanh Hằng · nữ · 15t THCS Liên Minh · 9ATrao gửi yêu thương17/05/2026 active
Showing 12 of 156 · View all · · Export to Sheets
Cohort › journey-0042 · Nguyễn Thị Mai

Nguyễn Thị Mai journey-0042 · active

Identity & background

Date of birth
14/03/2012 · 14 tuổi
School · class
THCS Tân Khánh · 8A2 · Cô Lan
Home
Thôn 3, xã Tân Khánh, Vụ Bản, Ninh Bình
Primary carer
Mẹ — Nguyễn Thị Hoa · 0912 345 678
Household
Mẹ + 2 chị em; chị gái là cựu HMT
Siblings in HMT
Background
Đi học 6 km bằng xe đạp. Tự tin trong nhóm nhỏ, ít nói trong lớp đông. Trường ghi nhận em đi học đều đặn cả học kỳ 1.

Programme & cohort

Programme
Cùng em tiến bước · cohort 2026
Coordinator
Cô Thuỷ (backup: Cô Hà)
Entered on
08/02/2026 · 3 tháng 10 ngày
Status
active

Progress notes (Block 3, most recent first)

18/05/2026 · Thăm trường học kỳ 2
Nguồn: coordinator-visitNgười ghi: Cô ThuỷCánh 1 · Hỗ trợ học tập
Đọc trôi chảy hơn so với học kỳ trước; cô giáo nhận xét em tự tin hơn khi phát biểu trong lớp. Môn Toán vẫn còn yếu; cô Lan đề nghị bổ sung một buổi học thêm trước khi vào học kỳ 3.
file gốc: intake/2026-W21/2026-05-18__truong-1__tham-truong.md
02/05/2026 · Sinh hoạt kỹ năng tháng 5
Nguồn: coordinatorNgười ghi: Cô HàCánh 3 · Cảm xúc và ứng xử
Em chủ động phát biểu trong nhóm về chủ đề "lòng biết ơn"; chia sẻ một câu chuyện về mẹ. Lần đầu em mở lời trong sinh hoạt cả tháng.
file gốc: intake/2026-W18/2026-05-02__sinh-hoat-thang-5.md
22/04/2026 · Hội thi nhảy dây toàn trường
Nguồn: schoolNgười ghi: THCS Tân KhánhCánh 5 · Sức khỏe thể chất
Đội của em đoạt giải Ba khối 8. Em là một trong hai bạn dẻo dai nhất nhóm.
file gốc: intake/2026-W17/2026-04-22__hoi-thi-nhay-day.pdf
10/04/2026 · Học bạ học kỳ 2
Nguồn: schoolNgười ghi: THCS Tân KhánhCánh 1 · Hỗ trợ học tập
Xếp hạng lớp tăng so với học kỳ 1; chuyên cần 96%. Không có cảnh báo.
file gốc: intake/2026-W15/2026-04-10__hoc-ba.pdf
08/02/2026 · Nhập chương trình
Nguồn: coordinator-intakeNgười ghi: Cô ThuỷCánh 1 · Hỗ trợ học tập
Đã trao đợt học bổng đầu tiên (xem sổ phúc lợi). Gia đình đón nhận sự hỗ trợ; mẹ em đề nghị giữ chị gái (journey-0017) cùng lịch nhận đồ dùng học tập.
Cohortjourney-0042 › Add progress note

Add a progress note for Nguyễn Thị Mai

📎 Drop a notebook scan, Zalo export, report-card PDF, photo — or click to browse
EXIF/GPS strip runs automatically on upload
✓ 2026-05-25__tham-truong.md uploaded · sanitised
🌻 Claude drafted this from the raw upload
"Em đến lớp đầy đủ tuần này. Cô Lan nhận xét em làm bài tập Toán cẩn thận hơn, dù vẫn cần thêm thời gian. Em đã chủ động hỏi thầy thêm bài về phân số."

Trigger only if attendance pattern, disclosure, or family situation warrants a second pair of eyes.

Cohortjourney-0042 › Benefits ledger

Benefits ledger Nguyễn Thị Mai

Benefit IDDateCategoryDescriptionPetalAmountFunding sourceReceipt
ben-2026-0042-00108/02/2026 scholarship Học bổng học kỳ 1, đợt 1 trên 3 1 2,500,000 đ general📎 bien-nhan-ky.pdf
ben-2026-0042-00215/02/2026 supplies Đồ dùng học tập học kỳ 1 1 450,000 đ general📎 anh-trao-do-dung.jpg
ben-2026-0042-00312/04/2026 scholarship Học bổng học kỳ 2, đợt 2 trên 3 1 2,500,000 đ contribution-2026-Q1-anon-7📎 bien-nhan-ky.pdf
ben-2026-0042-00403/05/2026 gift Quà Tết Đoan Ngọ — bánh + sách 8 180,000 đ general📎 thu-cam-on-gia-dinh.jpg
YTD total · 4 benefits
5,630,000 đ
By funding source
general: 3,130,000 đ · contribution-2026-Q1-anon-7: 2,500,000 đ

Cohort analytics Q2 2026 · all schools

Active children
156
+12 this quarter
Benefits delivered
487M đ
+18% vs Q1
Progress notes filed
412
+87 vs Q1
Partner schools
6
stable

Benefits by month (2026)

VNĐ · all programmes · all schools
JanFebMarAprMay

8-petal coverage · this quarter

Share of progress notes by petal
1 · Học tập 32%
2 · Thuyết trình 13%
3 · Cảm xúc 16%
4 · Sáng tạo 11%
5 · Thể chất 11%
6 · Thế giới quan 8%
7 · Nghề nghiệp 9%
8 · Lan toả 10%

Schools at a glance

Active children · benefits YTD · notes filed
THCS Tân Khánh32112M đ108 notes
THCS Vụ Bản2894M đ78 notes
Tiểu học An Ninh2671M đ64 notes
THCS Liên Minh2468M đ58 notes
THCS Hợp Lý2379M đ61 notes
Tiểu học Tân Khánh2363M đ43 notes

Benefits by category · Q2

Top categories this quarter
Scholarship312M đ · 64%
Supplies86M đ · 18%
Gift42M đ · 9%
Transport28M đ · 6%
Mentoring · other19M đ · 4%

Reports & exports

Three parameterised reports — per-child, per-cohort, per-school — drawn from registry-beneficiary.sqlite + the markdown profiles. Each runs Claude over the SQL view to compose a narrative wrapper, then exports to markdown / PDF / HXL-CSV. The audience picker narrows what's included.

📄 Per-child report

Identity + programme + progress-notes timeline + benefits ledger + 8-petal coverage + followups + Claude narrative. Use case: case review, hand-off, sponsor view.

📊 Per-cohort report

Headline counts + 8-petal coverage at cohort level + benefits totals + top progress-note themes + status distribution + Claude narrative. Use case: trustee quarterly review of one programme.

🏫 Per-school report

School headline + children list + benefits to this school + progress notes by source + 8-petal coverage + followups outstanding + Claude narrative. Use case: principal's monthly read; quarterly check-in.

Standing reports & exports

Auto-built or one-click; no parameters.

Monthly transparency report · May 2026

Where the money went: benefits by school × programme × category × petal, with the Claude-drafted narrative for the Area-4 publication. Built from the per-cohort + per-school views aggregated.
Last generated: 2 days ago · ready

Quarterly cohort dashboard · Q2 2026

Programme × school × counts × benefits totals × 8-petal breakdown across all programmes. Trustees read this directly.
Auto-builds quarterly · last: 2026-04-01

HXL-CSV export · all benefits 2026

One row per benefit, HXL-tagged (#org #date #activity #sector #adm1 #value+vnd). For external aggregation / IATI later.
Generated on demand

Followups outstanding · all schools

Every needs_followups line across all profiles, grouped by Coordinator, sorted by age. The Monday-morning surface.
Live view · 47 items outstanding

Safeguarding watchlist May 2026 · 7 items

🛡 Monthly run · 2026-05-01 · The job applied 7 rules across all 156 active children. It surfaces signals; every clearance and escalation is still a human decision. Items below: dismiss / coordinator-followup / escalate / re-surface next month.
All signals (7) Absence (2) Followup overdue (2) Benefit anomaly (1) Status drift (1) Keyword (1)
⚠ Keyword surfaced 2026-05-01 · daily pass · seen 24 hours ago

journey-0044 · Lê Thị Hồng · THCS Tân Khánh · 9C

Signal: Watchword "nghỉ học dài" appeared in progress note dated 2026-04-28 by Cô Thuỷ.

"… em xin nghỉ học dài hơn dự kiến vì gia đình có chuyện. Mẹ chưa nói rõ là chuyện gì."

⏱ Absence >60d surfaced 2026-05-01 · monthly run

journey-0045 · Phạm Minh Tuấn · THCS Tân Khánh · 7B · paused

Signal: No new progress note since 2026-02-21 (74 days ago). Status moved to paused on 2026-03-15 without an explanatory follow-up note.

Last note: "Em không tham gia sinh hoạt tháng 2. Đang tìm hiểu lý do."

📌 Followup overdue surfaced 2026-05-01 · monthly run · 52 days old

journey-1102 · Nguyễn Văn An · THCS Vụ Bản · 6A

Signal: Followup item "Thăm gia đình cuối tháng 3" set 2026-03-10; no progress note since then references the visit.

💰 Benefit anomaly surfaced 2026-05-01 · monthly run

journey-2092 · Bùi Quang Huy · Tiểu học An Ninh · 5C · paused

Signal: Zero benefits delivered in the last 90 days; cohort median for Trao gửi yêu thương in the same window is 2 entries. Status was paused on 2026-02-08.

🔄 Status drift surfaced 2026-05-01 · monthly run

journey-3018 · Đỗ Thanh Hằng · THCS Liên Minh · 9A

Signal: Status changed active → paused → active within 11 days (2026-04-20 → 2026-05-01). No progress note in that window explains the round trip.

5 of 7 items shown · 2 dismissed earlier this month · View dismissed

Mock data; no real persistence. Click any tab above to switch screens. Click a row in the cohort list to open the profile.