chore: complete v1.0 Member Notes System milestone

Archive roadmap and requirements to milestones/v1.0-*.
Evolve PROJECT.md with validated requirements and decisions.
Reorganize ROADMAP.md with milestone grouping.
Delete REQUIREMENTS.md (fresh for next milestone).

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
This commit is contained in:
2026-02-13 15:07:30 +08:00
parent 3e9bf153dc
commit 25779933cc
7 changed files with 237 additions and 239 deletions

View File

@@ -2,7 +2,7 @@
## What This Is
An enhancement to the existing admin member list that adds per-member note-taking capability. Any admin user can quickly add timestamped text notes to any member, and see a note count badge on the member list. Designed primarily for the chairman (理事長) to track observations and follow-ups, but shared across all admin roles.
An enhancement to the existing admin member list that adds per-member note-taking capability with inline quick-add and expandable history panel. Any admin user can add timestamped text notes to any member, view full note history with search, and see note count badges — all without leaving the member list page. Designed primarily for the chairman (理事長) but shared across all admin roles.
## Core Value
@@ -12,26 +12,20 @@ The chairman can annotate any member with timestamped notes directly from the me
### Validated
<!-- Existing capabilities inferred from codebase -->
- ✓ Member lifecycle management (pending → active → expired/suspended) — existing
- ✓ Admin member list with search, filter, CRUD — existing
- ✓ Role-based access control via Spatie permissions — existing
- ✓ Multi-tier financial approval workflows — existing
- ✓ CMS (articles, pages, documents) with headless API — existing
- ✓ Issue tracking systemexisting
- ✓ Audit logging on business-critical actions — existing
- ✓ Member profile with LINE ID — existing
- ✓ Per-member notes with text + timestamp, stored in DB — v1.0
- ✓ Inline quick-add note UI on the admin member list (no page navigation) — v1.0
- ✓ Note count badge displayed on each member row in the list — v1.0
- ✓ Click badge to expand/view full note history for that member — v1.0
- ✓ All admin roles can view and write notes (shared visibility) — v1.0
- ✓ Notes display author name and creation datetime — v1.0
- ✓ Notes management (view history, search, chronological order) — v1.0
- ✓ Dark mode fully supportedv1.0
- ✓ All UI text in Traditional Chinese — v1.0
- ✓ Works across paginated member list pages — v1.0
### Active
- [ ] Per-member notes with text + timestamp, stored in DB
- [ ] Inline quick-add note UI on the admin member list (no page navigation)
- [ ] Note count badge displayed on each member row in the list
- [ ] Click badge to expand/view full note history for that member
- [ ] All admin roles can view and write notes (shared visibility)
- [ ] Notes display author name and creation datetime
- [ ] Notes management (view history, chronological order)
(None — v1.0 complete, awaiting next milestone definition)
### Out of Scope
@@ -41,15 +35,20 @@ The chairman can annotate any member with timestamped notes directly from the me
- Note editing or deletion — append-only for audit integrity
- Dashboard/summary statistics — just the annotated member list
- API endpoint for notes — admin-only, no public/headless API needed
- Real-time updates (WebSocket) — single-user note-taking doesn't need sync
## Context
- The existing admin member list is at `/admin/members` with full CRUD, search, and filtering
- The chairman (理事長) role maps to `finance_chair` in the RBAC system
- The `admin` middleware allows access to anyone with the `admin` role or any permissions
- UI is Blade + Tailwind CSS + Alpine.js — inline interactions fit naturally with Alpine.js
- All UI text is hardcoded Traditional Chinese
- The member list uses standard Laravel pagination
Shipped v1.0 with 3,989 lines added across 29 files.
Tech stack: Laravel 10, Blade, Tailwind CSS, Alpine.js 3.4 + @alpinejs/collapse.
11 feature tests with 86 assertions covering API, UI rendering, and data contracts.
Key files:
- `app/Models/Note.php` — Polymorphic note model with author relationship
- `app/Http/Controllers/Admin/MemberNoteController.php` — CRUD endpoints
- `resources/views/admin/members/index.blade.php` — Inline UI with per-member `<tbody x-data>`
- `database/migrations/*_create_notes_table.php` — Schema with indexes
- `tests/Feature/Admin/MemberNoteTest.php` — 11 tests
## Constraints
@@ -63,10 +62,16 @@ The chairman can annotate any member with timestamped notes directly from the me
| Decision | Rationale | Outcome |
|----------|-----------|---------|
| Enhance existing member list vs new page | User wants notes integrated into existing workflow, not a separate tool | — Pending |
| Shared notes (all admin roles) | Chairman wants transparency; secretary and others should see same notes | — Pending |
| Append-only notes (no edit/delete) | Maintains audit integrity for member observations | — Pending |
| Alpine.js inline UI | Matches existing stack; avoids full page reloads for quick note-taking | — Pending |
| Enhance existing member list vs new page | User wants notes integrated into existing workflow | ✓ Good |
| Shared notes (all admin roles) | Chairman wants transparency; secretary and others should see same notes | ✓ Good |
| Append-only notes (no edit/delete) | Maintains audit integrity for member observations | ✓ Good |
| Alpine.js inline UI | Matches existing stack; avoids full page reloads for quick note-taking | ✓ Good |
| Polymorphic relationship (morphMap) | Future extensibility to other entities (issues, payments) | ✓ Good |
| morphMap instead of enforceMorphMap | Avoids breaking Spatie Laravel Permission's morph usage | ✓ Good |
| Per-member `<tbody x-data>` wrapper | Allows sibling `<tr>` elements to share Alpine state (template x-data is inert) | ✓ Good |
| Client-side search via computed property | Notes dataset is small (<20/member), no server-side filtering needed | ✓ Good |
| Explicit `latest('created_at')` ordering | Prevents bugs from implicit DB insertion order | ✓ Good |
| JSON responses for admin endpoints | Phase 2+ consumes via AJAX from Alpine.js | ✓ Good |
---
*Last updated: 2026-02-13 after initialization*
*Last updated: 2026-02-13 after v1.0 milestone*