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:
20
.planning/MILESTONES.md
Normal file
20
.planning/MILESTONES.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Milestones
|
||||
|
||||
## v1.0 Member Notes System (Shipped: 2026-02-13)
|
||||
|
||||
**Phases completed:** 3 phases, 4 plans
|
||||
**Files modified:** 29 | **Lines:** +3,989 / -36
|
||||
**Timeline:** 2026-02-13 (single day)
|
||||
|
||||
**Key accomplishments:**
|
||||
- Polymorphic notes table with Member relationship and author tracking
|
||||
- JSON API endpoints for note creation/retrieval with validation and audit logging
|
||||
- Inline quick-add note UI on member list with AJAX submission and dark mode
|
||||
- Expandable note history panel with search filtering and cache sync
|
||||
- 11 feature tests with 86 assertions
|
||||
|
||||
**Bug found during UAT:**
|
||||
- `<template x-data>` inside `<tbody>` doesn't render children — fixed with per-member `<tbody x-data>`
|
||||
|
||||
---
|
||||
|
||||
@@ -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 system — existing
|
||||
- ✓ 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 supported — v1.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*
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
# Requirements: Member Notes System (會員備註系統)
|
||||
|
||||
**Defined:** 2026-02-13
|
||||
**Core Value:** The chairman can annotate any member with timestamped notes directly from the member list, without navigating away from the page.
|
||||
|
||||
## v1 Requirements
|
||||
|
||||
### Note Creation
|
||||
|
||||
- [ ] **NOTE-01**: Admin can add a text note to any member inline from the member list (no page navigation)
|
||||
- [ ] **NOTE-02**: Each note stores text content, author (current user), and creation datetime
|
||||
- [ ] **NOTE-03**: Note submission uses AJAX (Axios) with CSRF protection — no page reload
|
||||
|
||||
### Note Display
|
||||
|
||||
- [ ] **DISP-01**: Each member row shows a note count badge indicating number of notes
|
||||
- [ ] **DISP-02**: Clicking the badge expands an inline panel showing full note history (newest first)
|
||||
- [ ] **DISP-03**: Each note displays author name and formatted datetime
|
||||
- [ ] **DISP-04**: Notes can be filtered/searched by text content within a member's note history
|
||||
|
||||
### Data Layer
|
||||
|
||||
- [ ] **DATA-01**: Notes use polymorphic relationship (`notable_type`/`notable_id`) for future extensibility
|
||||
- [ ] **DATA-02**: Migration includes proper indexes for member lookups and chronological ordering
|
||||
- [ ] **DATA-03**: Member list uses eager loading (`withCount('notes')`) to prevent N+1 queries
|
||||
|
||||
### Access & Audit
|
||||
|
||||
- [ ] **ACCS-01**: All admin roles can view and write notes (reuses existing `admin` middleware)
|
||||
- [ ] **ACCS-02**: Note creation is logged via `AuditLogger::log()`
|
||||
- [ ] **ACCS-03**: Dark mode fully supported on all note UI elements
|
||||
|
||||
### UI/UX
|
||||
|
||||
- [ ] **UI-01**: All UI text in Traditional Chinese
|
||||
- [ ] **UI-02**: Note quick-add works correctly across paginated member list pages
|
||||
- [ ] **UI-03**: Alpine.js manages inline state (expand/collapse, form submission, loading states)
|
||||
|
||||
## v2 Requirements
|
||||
|
||||
### Enhanced Notes
|
||||
|
||||
- **NOTE-04**: Note editing with revision history
|
||||
- **NOTE-05**: Note deletion with soft delete and audit trail
|
||||
- **NOTE-06**: Rich text / markdown support in note content
|
||||
|
||||
### Advanced Display
|
||||
|
||||
- **DISP-05**: Export member notes to PDF
|
||||
- **DISP-06**: Full-text search across all members' notes (global search)
|
||||
|
||||
### Extended Data
|
||||
|
||||
- **DATA-04**: Attach notes to other entities (Issues, Payments) using polymorphic relationship
|
||||
- **DATA-05**: Note categories or tags for organization
|
||||
|
||||
### Permissions
|
||||
|
||||
- **ACCS-04**: Granular `manage_member_notes` permission via Spatie
|
||||
|
||||
## Out of Scope
|
||||
|
||||
| Feature | Reason |
|
||||
|---------|--------|
|
||||
| Private/role-scoped notes | All notes shared across admin roles per user decision |
|
||||
| Note reminders/follow-ups | Over-engineering for v1; revisit based on usage |
|
||||
| Note attachments (files/images) | Keep notes lightweight — text only |
|
||||
| API endpoint for notes | Admin-only feature, no public/headless API needed |
|
||||
| Dedicated notes management page | Notes integrated into existing member list |
|
||||
| Real-time updates (WebSocket) | Single-user note-taking doesn't need real-time sync |
|
||||
|
||||
## Traceability
|
||||
|
||||
| Requirement | Phase | Status |
|
||||
|-------------|-------|--------|
|
||||
| NOTE-01 | Phase 2 | Pending |
|
||||
| NOTE-02 | Phase 2 | Pending |
|
||||
| NOTE-03 | Phase 2 | Pending |
|
||||
| DISP-01 | Phase 2 | Pending |
|
||||
| DISP-02 | Phase 3 | Pending |
|
||||
| DISP-03 | Phase 3 | Pending |
|
||||
| DISP-04 | Phase 3 | Pending |
|
||||
| DATA-01 | Phase 1 | Pending |
|
||||
| DATA-02 | Phase 1 | Pending |
|
||||
| DATA-03 | Phase 1 | Pending |
|
||||
| ACCS-01 | Phase 1 | Pending |
|
||||
| ACCS-02 | Phase 1 | Pending |
|
||||
| ACCS-03 | Phase 2 | Pending |
|
||||
| UI-01 | Phase 2 | Pending |
|
||||
| UI-02 | Phase 2 | Pending |
|
||||
| UI-03 | Phase 2 | Pending |
|
||||
|
||||
**Coverage:**
|
||||
- v1 requirements: 16 total
|
||||
- Mapped to phases: 16 ✓
|
||||
- Unmapped: 0 ✓
|
||||
|
||||
---
|
||||
*Requirements defined: 2026-02-13*
|
||||
*Last updated: 2026-02-13 after roadmap creation*
|
||||
@@ -1,94 +1,30 @@
|
||||
# Roadmap: Member Notes System (會員備註系統)
|
||||
|
||||
## Overview
|
||||
## Milestones
|
||||
|
||||
This roadmap delivers inline note-taking capabilities for the Taiwan NPO admin member list, enabling quick annotation without page navigation. The implementation follows a foundation-first approach: database schema and backend API (Phase 1), followed by inline quick-add UI delivering core value (Phase 2), and concluding with full note history and display features (Phase 3). All work leverages the existing Laravel 10 + Alpine.js + Tailwind stack (Phase 3 adds @alpinejs/collapse, the official Alpine.js collapse plugin).
|
||||
- ✅ **v1.0 Member Notes System** — Phases 1-3 (shipped 2026-02-13)
|
||||
|
||||
## Phases
|
||||
|
||||
**Phase Numbering:**
|
||||
- Integer phases (1, 2, 3): Planned milestone work
|
||||
- Decimal phases (2.1, 2.2): Urgent insertions (marked with INSERTED)
|
||||
<details>
|
||||
<summary>✅ v1.0 Member Notes System (Phases 1-3) — SHIPPED 2026-02-13</summary>
|
||||
|
||||
Decimal phases appear between their surrounding integers in numeric order.
|
||||
- [x] Phase 1: Database Schema & Backend API (2/2 plans) — completed 2026-02-13
|
||||
- [x] Phase 2: Inline Quick-Add UI (1/1 plan) — completed 2026-02-13
|
||||
- [x] Phase 3: Note History & Display (1/1 plan) — completed 2026-02-13
|
||||
|
||||
- [x] **Phase 1: Database Schema & Backend API** - Foundation layer with polymorphic relationships
|
||||
- [x] **Phase 2: Inline Quick-Add UI** - Core value: quick annotation from member list
|
||||
- [x] **Phase 3: Note History & Display** - Full note viewing and search capabilities
|
||||
Full details: `.planning/milestones/v1.0-ROADMAP.md`
|
||||
|
||||
## Phase Details
|
||||
|
||||
### Phase 1: Database Schema & Backend API
|
||||
**Goal**: Establish database foundation and backend endpoints for note storage and retrieval
|
||||
|
||||
**Depends on**: Nothing (first phase)
|
||||
|
||||
**Requirements**: DATA-01, DATA-02, DATA-03, ACCS-01, ACCS-02
|
||||
|
||||
**Success Criteria** (what must be TRUE):
|
||||
1. Notes table exists with polymorphic columns (`notable_type`, `notable_id`) and proper indexes
|
||||
2. Admin can create a note via POST endpoint with text, member ID, and author auto-captured
|
||||
3. Admin can retrieve all notes for a member via GET endpoint with author name and timestamps
|
||||
4. Member list shows accurate note count for each member without N+1 queries
|
||||
5. Note creation events are logged in audit trail with action and metadata
|
||||
|
||||
**Plans:** 2 plans
|
||||
|
||||
Plans:
|
||||
- [x] 01-01-PLAN.md — Database schema, Note model, Member relationship, morph map, factory
|
||||
- [x] 01-02-PLAN.md — MemberNoteController, routes, member list withCount, feature tests
|
||||
|
||||
### Phase 2: Inline Quick-Add UI
|
||||
**Goal**: Deliver core value — admins can annotate members inline without page navigation
|
||||
|
||||
**Depends on**: Phase 1
|
||||
|
||||
**Requirements**: NOTE-01, NOTE-02, NOTE-03, DISP-01, UI-01, UI-02, UI-03, ACCS-03
|
||||
|
||||
**Success Criteria** (what must be TRUE):
|
||||
1. Each member row displays a note count badge showing number of notes
|
||||
2. Admin can click an inline form to add a note without leaving the member list page
|
||||
3. After submitting a note, the badge updates immediately and the form clears
|
||||
4. Note submission shows loading state during AJAX request (disabled button)
|
||||
5. Validation errors display in Traditional Chinese below the form field
|
||||
6. All note UI elements work correctly in both light and dark mode
|
||||
7. Quick-add functionality works across paginated member list pages (pages 1, 2, 3+)
|
||||
|
||||
**Plans:** 1 plan
|
||||
|
||||
Plans:
|
||||
- [x] 02-01-PLAN.md — Inline note form with Alpine.js, note count badge, AJAX submission, dark mode, and feature tests
|
||||
|
||||
### Phase 3: Note History & Display
|
||||
**Goal**: Complete the note feature with full history viewing and search
|
||||
|
||||
**Depends on**: Phase 2
|
||||
|
||||
**Requirements**: DISP-02, DISP-03, DISP-04
|
||||
|
||||
**Success Criteria** (what must be TRUE):
|
||||
1. Admin can click the note count badge to expand an inline panel showing all notes for that member
|
||||
2. Notes display in chronological order (newest first) with author name and formatted datetime
|
||||
3. Panel shows empty state message ("尚無備註") when member has no notes
|
||||
4. Admin can filter/search notes by text content within a member's note history
|
||||
5. Expanded panel collapses cleanly without affecting other member rows
|
||||
|
||||
**Plans:** 1 plan
|
||||
|
||||
Plans:
|
||||
- [x] 03-01-PLAN.md — Expandable note history panel with search, collapse plugin, controller ordering fix, and feature tests
|
||||
</details>
|
||||
|
||||
## Progress
|
||||
|
||||
**Execution Order:**
|
||||
Phases execute in numeric order: 1 → 2 → 3
|
||||
|
||||
| Phase | Plans Complete | Status | Completed |
|
||||
|-------|----------------|--------|-----------|
|
||||
| 1. Database Schema & Backend API | 2/2 | ✓ Complete | 2026-02-13 |
|
||||
| 2. Inline Quick-Add UI | 1/1 | ✓ Complete | 2026-02-13 |
|
||||
| 3. Note History & Display | 1/1 | ✓ Complete | 2026-02-13 |
|
||||
| Phase | Milestone | Plans Complete | Status | Completed |
|
||||
|-------|-----------|----------------|--------|-----------|
|
||||
| 1. Database Schema & Backend API | v1.0 | 2/2 | ✓ Complete | 2026-02-13 |
|
||||
| 2. Inline Quick-Add UI | v1.0 | 1/1 | ✓ Complete | 2026-02-13 |
|
||||
| 3. Note History & Display | v1.0 | 1/1 | ✓ Complete | 2026-02-13 |
|
||||
|
||||
---
|
||||
*Roadmap created: 2026-02-13*
|
||||
*Last updated: 2026-02-13 (Phase 3 complete — all phases done)*
|
||||
*Last updated: 2026-02-13 (v1.0 milestone shipped)*
|
||||
|
||||
@@ -6,14 +6,13 @@ See: .planning/PROJECT.md (updated 2026-02-13)
|
||||
|
||||
**Core value:** The chairman can annotate any member with timestamped notes directly from the member list, without navigating away from the page.
|
||||
|
||||
**Current focus:** Phase 3 - Note History Display
|
||||
**Current focus:** v1.0 shipped — planning next milestone
|
||||
|
||||
## Current Position
|
||||
|
||||
Phase: 3 of 3 (Note History Display)
|
||||
Plan: 1 of 1 in current phase
|
||||
Status: Phase Complete
|
||||
Last activity: 2026-02-13 — Completed 03-01-PLAN.md (Expandable note history panel with search)
|
||||
Milestone: v1.0 Member Notes System — SHIPPED
|
||||
Status: Complete
|
||||
Last activity: 2026-02-13 — Milestone archived
|
||||
|
||||
Progress: [██████████] 100%
|
||||
|
||||
@@ -32,45 +31,24 @@ Progress: [██████████] 100%
|
||||
| 02 | 1 | 2.3 min | 2.3 min |
|
||||
| 03 | 1 | 2.2 min | 2.2 min |
|
||||
|
||||
**Recent Trend:**
|
||||
- Last 5 plans: 3 min, 2 min, 2.3 min, 2.2 min
|
||||
- Trend: Consistently fast (sub-3 min average)
|
||||
|
||||
*Updated after each plan completion*
|
||||
|
||||
## Accumulated Context
|
||||
|
||||
### Decisions
|
||||
|
||||
Decisions are logged in PROJECT.md Key Decisions table.
|
||||
Recent decisions affecting current work:
|
||||
|
||||
- Use Alpine.js collapse plugin for panel animation: Provides smooth, accessible expand/collapse with minimal code (completed in 03-01)
|
||||
- Wrap main row + expansion row in template x-data: Allows sibling tr elements to share Alpine.js state while maintaining table structure (completed in 03-01)
|
||||
- Client-side search via computed property: Notes dataset is small, no need for server-side filtering (completed in 03-01)
|
||||
- Fix controller ordering from implicit to explicit latest(): Prevents future bugs if database changes affect insertion order (completed in 03-01)
|
||||
- Eager load only author id+name: Reduces payload size, only needed fields for display (completed in 03-01)
|
||||
- Per-row Alpine.js scope for independent inline forms: Each row renders fresh x-data, pagination works correctly (completed in 02-01)
|
||||
- Submit button disabled when isSubmitting OR noteContent empty: Prevents blank note submissions (completed in 02-01)
|
||||
- Error display via optional chaining (errors.content?.[0]): Handles missing error keys gracefully (completed in 02-01)
|
||||
- Cancel button resets all state (content, form open, errors): Clean slate on re-open (completed in 02-01)
|
||||
- JSON responses for admin endpoints: Phase 2 consumes via AJAX from Alpine.js (completed in 01-02)
|
||||
- Authorization via admin middleware: StoreNoteRequest returns true, route middleware handles auth (completed in 01-02)
|
||||
- withCount in member list: Prevents N+1 queries for note count badges (completed in 01-02)
|
||||
- Use morphMap instead of enforceMorphMap: Avoids breaking Spatie Laravel Permission while providing namespace protection (completed in 01-01)
|
||||
All decisions logged in PROJECT.md Key Decisions table.
|
||||
|
||||
### Pending Todos
|
||||
|
||||
None yet.
|
||||
None.
|
||||
|
||||
### Blockers/Concerns
|
||||
|
||||
None yet.
|
||||
None.
|
||||
|
||||
## Session Continuity
|
||||
|
||||
Last session: 2026-02-13
|
||||
Stopped at: Completed Phase 3 (03-01-PLAN.md) - Expandable note history panel with search
|
||||
Stopped at: v1.0 milestone complete and archived
|
||||
Resume file: None
|
||||
|
||||
**Phase 3 Complete** - Note history display feature complete. Admins can now view all member notes inline with search filtering. The member notes feature is fully functional: inline quick-add (Phase 2) + expandable history panel (Phase 3). All 3 phases complete.
|
||||
**Milestone v1.0 shipped.** Next: `/gsd:new-milestone` when ready for new work.
|
||||
|
||||
65
.planning/milestones/v1.0-REQUIREMENTS.md
Normal file
65
.planning/milestones/v1.0-REQUIREMENTS.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# Requirements Archive: v1.0 Member Notes System
|
||||
|
||||
**Archived:** 2026-02-13
|
||||
**Status:** SHIPPED
|
||||
|
||||
---
|
||||
|
||||
## v1 Requirements — All Shipped
|
||||
|
||||
### Note Creation
|
||||
|
||||
- [x] **NOTE-01**: Admin can add a text note to any member inline from the member list — Phase 2
|
||||
- [x] **NOTE-02**: Each note stores text content, author (current user), and creation datetime — Phase 1
|
||||
- [x] **NOTE-03**: Note submission uses AJAX (Axios) with CSRF protection — no page reload — Phase 2
|
||||
|
||||
### Note Display
|
||||
|
||||
- [x] **DISP-01**: Each member row shows a note count badge indicating number of notes — Phase 2
|
||||
- [x] **DISP-02**: Clicking the badge expands an inline panel showing full note history (newest first) — Phase 3
|
||||
- [x] **DISP-03**: Each note displays author name and formatted datetime — Phase 3
|
||||
- [x] **DISP-04**: Notes can be filtered/searched by text content within a member's note history — Phase 3
|
||||
|
||||
### Data Layer
|
||||
|
||||
- [x] **DATA-01**: Notes use polymorphic relationship (`notable_type`/`notable_id`) — Phase 1
|
||||
- [x] **DATA-02**: Migration includes proper indexes for member lookups and chronological ordering — Phase 1
|
||||
- [x] **DATA-03**: Member list uses eager loading (`withCount('notes')`) to prevent N+1 queries — Phase 1
|
||||
|
||||
### Access & Audit
|
||||
|
||||
- [x] **ACCS-01**: All admin roles can view and write notes (reuses existing `admin` middleware) — Phase 1
|
||||
- [x] **ACCS-02**: Note creation is logged via `AuditLogger::log()` — Phase 1
|
||||
- [x] **ACCS-03**: Dark mode fully supported on all note UI elements — Phase 2
|
||||
|
||||
### UI/UX
|
||||
|
||||
- [x] **UI-01**: All UI text in Traditional Chinese — Phase 2
|
||||
- [x] **UI-02**: Note quick-add works correctly across paginated member list pages — Phase 2
|
||||
- [x] **UI-03**: Alpine.js manages inline state (expand/collapse, form submission, loading states) — Phase 3
|
||||
|
||||
## Traceability
|
||||
|
||||
| Requirement | Phase | Status |
|
||||
|-------------|-------|--------|
|
||||
| NOTE-01 | Phase 2 | ✓ Shipped |
|
||||
| NOTE-02 | Phase 1 | ✓ Shipped |
|
||||
| NOTE-03 | Phase 2 | ✓ Shipped |
|
||||
| DISP-01 | Phase 2 | ✓ Shipped |
|
||||
| DISP-02 | Phase 3 | ✓ Shipped |
|
||||
| DISP-03 | Phase 3 | ✓ Shipped |
|
||||
| DISP-04 | Phase 3 | ✓ Shipped |
|
||||
| DATA-01 | Phase 1 | ✓ Shipped |
|
||||
| DATA-02 | Phase 1 | ✓ Shipped |
|
||||
| DATA-03 | Phase 1 | ✓ Shipped |
|
||||
| ACCS-01 | Phase 1 | ✓ Shipped |
|
||||
| ACCS-02 | Phase 1 | ✓ Shipped |
|
||||
| ACCS-03 | Phase 2 | ✓ Shipped |
|
||||
| UI-01 | Phase 2 | ✓ Shipped |
|
||||
| UI-02 | Phase 2 | ✓ Shipped |
|
||||
| UI-03 | Phase 3 | ✓ Shipped |
|
||||
|
||||
**Coverage:** 16/16 requirements shipped (100%)
|
||||
|
||||
---
|
||||
*Archived: 2026-02-13*
|
||||
94
.planning/milestones/v1.0-ROADMAP.md
Normal file
94
.planning/milestones/v1.0-ROADMAP.md
Normal file
@@ -0,0 +1,94 @@
|
||||
# Roadmap: Member Notes System (會員備註系統)
|
||||
|
||||
## Overview
|
||||
|
||||
This roadmap delivers inline note-taking capabilities for the Taiwan NPO admin member list, enabling quick annotation without page navigation. The implementation follows a foundation-first approach: database schema and backend API (Phase 1), followed by inline quick-add UI delivering core value (Phase 2), and concluding with full note history and display features (Phase 3). All work leverages the existing Laravel 10 + Alpine.js + Tailwind stack (Phase 3 adds @alpinejs/collapse, the official Alpine.js collapse plugin).
|
||||
|
||||
## Phases
|
||||
|
||||
**Phase Numbering:**
|
||||
- Integer phases (1, 2, 3): Planned milestone work
|
||||
- Decimal phases (2.1, 2.2): Urgent insertions (marked with INSERTED)
|
||||
|
||||
Decimal phases appear between their surrounding integers in numeric order.
|
||||
|
||||
- [x] **Phase 1: Database Schema & Backend API** - Foundation layer with polymorphic relationships
|
||||
- [x] **Phase 2: Inline Quick-Add UI** - Core value: quick annotation from member list
|
||||
- [x] **Phase 3: Note History & Display** - Full note viewing and search capabilities
|
||||
|
||||
## Phase Details
|
||||
|
||||
### Phase 1: Database Schema & Backend API
|
||||
**Goal**: Establish database foundation and backend endpoints for note storage and retrieval
|
||||
|
||||
**Depends on**: Nothing (first phase)
|
||||
|
||||
**Requirements**: DATA-01, DATA-02, DATA-03, ACCS-01, ACCS-02
|
||||
|
||||
**Success Criteria** (what must be TRUE):
|
||||
1. Notes table exists with polymorphic columns (`notable_type`, `notable_id`) and proper indexes
|
||||
2. Admin can create a note via POST endpoint with text, member ID, and author auto-captured
|
||||
3. Admin can retrieve all notes for a member via GET endpoint with author name and timestamps
|
||||
4. Member list shows accurate note count for each member without N+1 queries
|
||||
5. Note creation events are logged in audit trail with action and metadata
|
||||
|
||||
**Plans:** 2 plans
|
||||
|
||||
Plans:
|
||||
- [x] 01-01-PLAN.md — Database schema, Note model, Member relationship, morph map, factory
|
||||
- [x] 01-02-PLAN.md — MemberNoteController, routes, member list withCount, feature tests
|
||||
|
||||
### Phase 2: Inline Quick-Add UI
|
||||
**Goal**: Deliver core value — admins can annotate members inline without page navigation
|
||||
|
||||
**Depends on**: Phase 1
|
||||
|
||||
**Requirements**: NOTE-01, NOTE-02, NOTE-03, DISP-01, UI-01, UI-02, UI-03, ACCS-03
|
||||
|
||||
**Success Criteria** (what must be TRUE):
|
||||
1. Each member row displays a note count badge showing number of notes
|
||||
2. Admin can click an inline form to add a note without leaving the member list page
|
||||
3. After submitting a note, the badge updates immediately and the form clears
|
||||
4. Note submission shows loading state during AJAX request (disabled button)
|
||||
5. Validation errors display in Traditional Chinese below the form field
|
||||
6. All note UI elements work correctly in both light and dark mode
|
||||
7. Quick-add functionality works across paginated member list pages (pages 1, 2, 3+)
|
||||
|
||||
**Plans:** 1 plan
|
||||
|
||||
Plans:
|
||||
- [x] 02-01-PLAN.md — Inline note form with Alpine.js, note count badge, AJAX submission, dark mode, and feature tests
|
||||
|
||||
### Phase 3: Note History & Display
|
||||
**Goal**: Complete the note feature with full history viewing and search
|
||||
|
||||
**Depends on**: Phase 2
|
||||
|
||||
**Requirements**: DISP-02, DISP-03, DISP-04
|
||||
|
||||
**Success Criteria** (what must be TRUE):
|
||||
1. Admin can click the note count badge to expand an inline panel showing all notes for that member
|
||||
2. Notes display in chronological order (newest first) with author name and formatted datetime
|
||||
3. Panel shows empty state message ("尚無備註") when member has no notes
|
||||
4. Admin can filter/search notes by text content within a member's note history
|
||||
5. Expanded panel collapses cleanly without affecting other member rows
|
||||
|
||||
**Plans:** 1 plan
|
||||
|
||||
Plans:
|
||||
- [x] 03-01-PLAN.md — Expandable note history panel with search, collapse plugin, controller ordering fix, and feature tests
|
||||
|
||||
## Progress
|
||||
|
||||
**Execution Order:**
|
||||
Phases execute in numeric order: 1 → 2 → 3
|
||||
|
||||
| Phase | Plans Complete | Status | Completed |
|
||||
|-------|----------------|--------|-----------|
|
||||
| 1. Database Schema & Backend API | 2/2 | ✓ Complete | 2026-02-13 |
|
||||
| 2. Inline Quick-Add UI | 1/1 | ✓ Complete | 2026-02-13 |
|
||||
| 3. Note History & Display | 1/1 | ✓ Complete | 2026-02-13 |
|
||||
|
||||
---
|
||||
*Roadmap created: 2026-02-13*
|
||||
*Last updated: 2026-02-13 (Phase 3 complete — all phases done)*
|
||||
Reference in New Issue
Block a user