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
|
## 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
|
## Core Value
|
||||||
|
|
||||||
@@ -12,26 +12,20 @@ The chairman can annotate any member with timestamped notes directly from the me
|
|||||||
|
|
||||||
### Validated
|
### Validated
|
||||||
|
|
||||||
<!-- Existing capabilities inferred from codebase -->
|
- ✓ 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
|
||||||
- ✓ Member lifecycle management (pending → active → expired/suspended) — existing
|
- ✓ Note count badge displayed on each member row in the list — v1.0
|
||||||
- ✓ Admin member list with search, filter, CRUD — existing
|
- ✓ Click badge to expand/view full note history for that member — v1.0
|
||||||
- ✓ Role-based access control via Spatie permissions — existing
|
- ✓ All admin roles can view and write notes (shared visibility) — v1.0
|
||||||
- ✓ Multi-tier financial approval workflows — existing
|
- ✓ Notes display author name and creation datetime — v1.0
|
||||||
- ✓ CMS (articles, pages, documents) with headless API — existing
|
- ✓ Notes management (view history, search, chronological order) — v1.0
|
||||||
- ✓ Issue tracking system — existing
|
- ✓ Dark mode fully supported — v1.0
|
||||||
- ✓ Audit logging on business-critical actions — existing
|
- ✓ All UI text in Traditional Chinese — v1.0
|
||||||
- ✓ Member profile with LINE ID — existing
|
- ✓ Works across paginated member list pages — v1.0
|
||||||
|
|
||||||
### Active
|
### Active
|
||||||
|
|
||||||
- [ ] Per-member notes with text + timestamp, stored in DB
|
(None — v1.0 complete, awaiting next milestone definition)
|
||||||
- [ ] 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)
|
|
||||||
|
|
||||||
### Out of Scope
|
### 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
|
- Note editing or deletion — append-only for audit integrity
|
||||||
- Dashboard/summary statistics — just the annotated member list
|
- Dashboard/summary statistics — just the annotated member list
|
||||||
- API endpoint for notes — admin-only, no public/headless API needed
|
- API endpoint for notes — admin-only, no public/headless API needed
|
||||||
|
- Real-time updates (WebSocket) — single-user note-taking doesn't need sync
|
||||||
|
|
||||||
## Context
|
## Context
|
||||||
|
|
||||||
- The existing admin member list is at `/admin/members` with full CRUD, search, and filtering
|
Shipped v1.0 with 3,989 lines added across 29 files.
|
||||||
- The chairman (理事長) role maps to `finance_chair` in the RBAC system
|
Tech stack: Laravel 10, Blade, Tailwind CSS, Alpine.js 3.4 + @alpinejs/collapse.
|
||||||
- The `admin` middleware allows access to anyone with the `admin` role or any permissions
|
11 feature tests with 86 assertions covering API, UI rendering, and data contracts.
|
||||||
- UI is Blade + Tailwind CSS + Alpine.js — inline interactions fit naturally with Alpine.js
|
|
||||||
- All UI text is hardcoded Traditional Chinese
|
Key files:
|
||||||
- The member list uses standard Laravel pagination
|
- `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
|
## Constraints
|
||||||
|
|
||||||
@@ -63,10 +62,16 @@ The chairman can annotate any member with timestamped notes directly from the me
|
|||||||
|
|
||||||
| Decision | Rationale | Outcome |
|
| Decision | Rationale | Outcome |
|
||||||
|----------|-----------|---------|
|
|----------|-----------|---------|
|
||||||
| Enhance existing member list vs new page | User wants notes integrated into existing workflow, not a separate tool | — 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 | — Pending |
|
| 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 | — Pending |
|
| 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 | — Pending |
|
| 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 (會員備註系統)
|
# 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
|
## Phases
|
||||||
|
|
||||||
**Phase Numbering:**
|
<details>
|
||||||
- Integer phases (1, 2, 3): Planned milestone work
|
<summary>✅ v1.0 Member Notes System (Phases 1-3) — SHIPPED 2026-02-13</summary>
|
||||||
- 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 (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
|
Full details: `.planning/milestones/v1.0-ROADMAP.md`
|
||||||
- [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
|
</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
|
## Progress
|
||||||
|
|
||||||
**Execution Order:**
|
| Phase | Milestone | Plans Complete | Status | Completed |
|
||||||
Phases execute in numeric order: 1 → 2 → 3
|
|-------|-----------|----------------|--------|-----------|
|
||||||
|
| 1. Database Schema & Backend API | v1.0 | 2/2 | ✓ Complete | 2026-02-13 |
|
||||||
| Phase | Plans Complete | Status | Completed |
|
| 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 |
|
||||||
| 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*
|
*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.
|
**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
|
## Current Position
|
||||||
|
|
||||||
Phase: 3 of 3 (Note History Display)
|
Milestone: v1.0 Member Notes System — SHIPPED
|
||||||
Plan: 1 of 1 in current phase
|
Status: Complete
|
||||||
Status: Phase Complete
|
Last activity: 2026-02-13 — Milestone archived
|
||||||
Last activity: 2026-02-13 — Completed 03-01-PLAN.md (Expandable note history panel with search)
|
|
||||||
|
|
||||||
Progress: [██████████] 100%
|
Progress: [██████████] 100%
|
||||||
|
|
||||||
@@ -32,45 +31,24 @@ Progress: [██████████] 100%
|
|||||||
| 02 | 1 | 2.3 min | 2.3 min |
|
| 02 | 1 | 2.3 min | 2.3 min |
|
||||||
| 03 | 1 | 2.2 min | 2.2 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
|
## Accumulated Context
|
||||||
|
|
||||||
### Decisions
|
### Decisions
|
||||||
|
|
||||||
Decisions are logged in PROJECT.md Key Decisions table.
|
All decisions 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)
|
|
||||||
|
|
||||||
### Pending Todos
|
### Pending Todos
|
||||||
|
|
||||||
None yet.
|
None.
|
||||||
|
|
||||||
### Blockers/Concerns
|
### Blockers/Concerns
|
||||||
|
|
||||||
None yet.
|
None.
|
||||||
|
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-02-13
|
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
|
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