Files
usher-manage-stack/.planning/PROJECT.md
gbanyan 25779933cc 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>
2026-02-13 15:07:30 +08:00

4.1 KiB

Member Notes System (會員備註系統)

What This Is

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

The chairman can annotate any member with timestamped notes directly from the member list, without navigating away from the page.

Requirements

Validated

  • ✓ 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 supported — v1.0
  • ✓ All UI text in Traditional Chinese — v1.0
  • ✓ Works across paginated member list pages — v1.0

Active

(None — v1.0 complete, awaiting next milestone definition)

Out of Scope

  • Private/role-scoped notes — all notes are shared across admin roles
  • Note categories or tags — keep it simple, just text + time
  • Reminders or scheduled follow-ups — not needed for v1
  • 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

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

  • Tech stack: Must use existing Laravel 10 + Blade + Tailwind + Alpine.js stack
  • Database: SQLite (dev) / MySQL (prod) — standard Laravel migration
  • Access control: Reuse existing admin middleware — no new permission needed
  • UI pattern: Inline interaction via Alpine.js — no full-page reloads for note operations
  • Audit: Notes are append-only; use AuditLogger for tracking note creation

Key Decisions

Decision Rationale Outcome
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 v1.0 milestone