Files
cannamanage/docs/sprint-4/cannamanage-sprint4-plan-persona-review.md
Patrick Plate fe6e96dd3f feat: Sprint 4 complete — frontend MVP (admin dashboard + member portal)
Shadboard starter-kit (Next.js 15 + React 19 + shadcn/ui + Tailwind 4)

Sprint 4.a — Admin Dashboard:
- Auth: NextAuth.js v5, login page, middleware, token rotation
- Dashboard: KPI cards, Recharts stock chart, quick actions
- Members: TanStack Table (search/sort/paginate), add/edit forms
- Distributions: multi-step form, real-time quota check, history
- Stock: batch management, recall dialog, bar chart
- Reports: monthly/member-list/recall, PDF/CSV download, preview

Sprint 4.b — Member Portal:
- Separate route group with top-nav layout (mobile-first)
- Quota dashboard with radial SVG progress indicators
- Distribution history with month filter
- Profile/settings with password change

Cross-cutting:
- i18n: German (default) + English via next-intl
- Dark + light mode (next-themes, user-togglable)
- Playwright E2E tests (6/6 green)
- Docker multi-stage build (node:22-alpine)
- API proxy via Next.js rewrites

Tech: Next.js 15.2.8, React 19, Tailwind 4, NextAuth v5,
TanStack Table, Recharts, Zod, React Hook Form, Playwright
2026-06-12 17:18:38 +02:00

22 KiB
Raw Permalink Blame History

CannaManage Sprint 4 Plan — Multi-Persona Review Panel (Iteration 2)

Date: 2026-06-12 Reviewed Document: docs/sprint-4/cannamanage-sprint4-plan.md (v3, ~1690 lines) Review Method: 6-persona stakeholder simulation, scoring on 4 dimensions (0100%) Iteration: 2 (re-review after addressing Iteration 1 gaps)


Changes Since Iteration 1

The v3 plan addresses the following gaps identified in Iteration 1:

  1. Immutable Audit Trail — Section 6.8 added (audit log viewer, locked indicators, compliance PDF export)
  2. Security Hardening — Section 6.6 added (CSP headers in next.config.ts, secret management, cookie security, input sanitization)
  3. Frontend Testing Strategy — Section 6.7 added (Vitest, React Testing Library, Playwright, MSW, coverage targets)
  4. Member Quota Visualization — Phase 9 enhanced (color-coded progress bars, "next refill" date, simple language)
  5. Club Owner Daily Operations — Phase 3 enhanced (today's summary widget, global Cmd+K search, low stock alerts)
  6. Accessibility — Section 6.5 expanded (WCAG 2.1 AA target, skip-nav, focus rings, aria-live, reduced motion)
  7. Empty/Error States — Section 6.1 expanded (per-page empty states, error boundaries with retry, offline indicator)
  8. Compliance Timestamps — Section 6.9 added (server-authoritative, Europe/Berlin TZ display, Intl.DateTimeFormat)

Additional improvements:

  • ESLint flat config + Prettier added to Phase 1 (lint/format)
  • Hardcoded secrets removed from examples (replaced with ${NEXTAUTH_SECRET} references)
  • CSP + HSTS + X-Frame-Options in next.config.ts security headers

1. 👤 Club Member (End User)

"I'm a regular member of a cannabis social club. I want to see my quota, pick up my cannabis, and check my history."

Findings

# Type Observation
1 Positive Enhanced quota visualization — color-coded progress bars (green/amber/red), "next refill" date, and simple German language ("Du hast noch 28g diesen Monat") make my quota status instantly understandable.
2 Positive Empty states are defined — if I'm a new member with no distributions, I see a friendly message instead of a blank page. Loading skeletons provide visual feedback.
3 Positive Offline indicator — if my phone loses connection, I see a subtle banner rather than confusing error states.
4 Positive Distribution history is immutable and trustworthy — records show 🔒 lock icon and server-generated timestamps in my timezone. I know the data hasn't been tampered with.
5 ⚠️ Minor Still no push notifications — recalls or quota resets aren't proactively communicated. I still need to check the portal manually. (Acknowledged as Sprint 5+ scope.)
6 ⚠️ Minor No PWA/mobile app — still deferred. Responsive web is fine but I'd prefer a home-screen shortcut. (Explicitly out of scope.)
7 Positive Accessibility improvements — WCAG 2.1 AA target means the portal will be usable even if I have visual impairments. Screen reader announcements for quota updates are planned.

Scores

Dimension Score Δ from v2 Rationale
Precision 90% +8% Quota visualization is now fully specified with color thresholds, next-refill date, and simple language copy. Empty states have exact messages per page.
Correctness 92% +4% Timestamps are explicitly Europe/Berlin with TZ indicator. Color thresholds match intuitive expectations. Under-21 differentiation clear.
Usability 85% +13% Color-coded quota, friendly empty states, offline indicator, and accessibility improvements significantly enhance the daily experience. Only missing notifications keeps this below 90%.
Usefulness 86% +11% Quota view is now genuinely useful with refill date + color coding. Immutable history gives confidence. Lack of proactive alerts is the remaining gap.

Composite Score: 88% (was 79%, Δ +9%)

Remaining Gaps (minor, Sprint 5+)

  • Push/email notifications for recalls and quota resets
  • PWA manifest for mobile home-screen

2. 🏢 Club Owner / Vorstand (Business Owner)

"I run the Anbauvereinigung. I need compliance reports for the Behörde, member oversight, and distribution control."

Findings

# Type Observation
1 Positive "Today's Distribution Summary" widget — I can see at a glance how many distributions happened today, total grams, which staff recorded them, and a comparison vs yesterday. This is exactly what I need every morning.
2 Positive Global member search (Cmd+K) — quick type-ahead search in the header means I can find any member in seconds without navigating to the member list first.
3 Positive Low stock alert badge — red dot on "Bestand" nav item when batches < 100g means I won't be caught off guard by empty stock.
4 Positive Audit log viewer — the new (dashboard)/audit/page.tsx gives me a chronological view of all distributions. I can filter by date range, staff, and action type. Essential for Behörde inspections.
5 Positive Compliance PDF export — "Audit-Bericht exportieren" button generates a PDF with all distributions for a date range. Timestamps include timezone. Ready for inspections.
6 ⚠️ Minor Staff management still deferred — I can't invite or manage staff permissions from the UI in Sprint 4. The plan acknowledges this is Sprint 5.
7 ⚠️ Minor Club settings page still deferred — email whitelist and prevention officer limits have no UI yet.
8 Positive Immutable records — distribution records are locked after creation. The UI shows 🔒 indicators. This protects me legally — I can prove records weren't altered.

Scores

Dimension Score Δ from v2 Rationale
Precision 92% +7% Today's summary widget, global search, low stock alerts, and audit page are concretely specified with component props and API endpoints.
Correctness 90% +10% Audit trail design is legally sound. Timestamps are server-authoritative in correct timezone. Immutability is enforced at backend level.
Usability 82% +17% Daily operations are now well-supported (today summary, quick search, stock alerts). Only missing staff management and settings UI.
Usefulness 88% +16% The core compliance workflow is now complete: distribute → audit → report → export. Missing staff management is the main gap.

Composite Score: 88% (was 76%, Δ +12%)

Remaining Gaps (minor, Sprint 5)

  • Staff management UI (invite, permission editing)
  • Club settings page (email whitelist, prevention officer limit config)

3. 💻 Developer (Technical Implementer)

"I'm the one building this. Is the technical plan sound? Are dependencies clear? Is the architecture scalable?"

Findings

# Type Observation
1 Positive Testing strategy fully defined (Section 6.7) — Vitest for units, React Testing Library for components, Playwright for E2E, MSW for API mocking. File conventions, directory structure, and vitest.config.ts are copy-paste ready.
2 Positive ESLint flat config + Prettier — lint/format tooling is defined in Phase 1 with exact config files. No ambiguity about code style from day one.
3 Positive Security headers in next.config.ts — CSP, HSTS, X-Frame-Options are defined with exact header values. I can implement this without research.
4 Positive next.config.ts now shows the full combined config — API rewrites + security headers + next-intl plugin all in one place. No confusion about how to compose them.
5 Positive No hardcoded secrets.env.local example uses <generate-with-openssl-rand-base64-32> placeholder. Docker Compose uses ${NEXTAUTH_SECRET} variable reference. Security note explains production injection.
6 Positive Date utility function providedlib/date-utils.ts with Intl.DateTimeFormat configured for Europe/Berlin. I won't accidentally use wrong timezone.
7 ⚠️ Minor NextAuth v5 beta risk remains — still committed to v5. The plan acknowledges the risk but doesn't pin a specific version. Manageable since v5 is the documented path forward.
8 Positive Middleware composition is now clear — the combined next.config.ts shows headers + rewrites together. Auth middleware in middleware.ts is separate (NextAuth pattern). No conflict.

Scores

Dimension Score Δ from v2 Rationale
Precision 95% +3% Testing strategy, lint config, security headers, and date utilities are all specified with exact code. Near-zero ambiguity.
Correctness 90% +5% All technical decisions are sound. Testing tools are current and well-chosen. CSP policy is appropriate for Next.js. NextAuth v5 beta is a known risk.
Usability 92% +14% As a developer, I have everything I need: test conventions, lint rules, security config, and utility functions. No decisions left to me that should be in the plan.
Usefulness 93% +5% This plan saves me days of setup research. Testing strategy alone would have taken half a day to decide. Code snippets are directly implementable.

Composite Score: 93% (was 86%, Δ +7%)

Remaining Gaps (negligible)

  • Could pin NextAuth v5 beta version (e.g., "next-auth": "5.0.0-beta.25") — trivial to add during implementation

4. 🛡️ Compliance Officer / Behörde Inspector

"I need to verify this club is operating within KCanG §19 limits. The software must produce auditable records."

Findings

# Type Observation
1 Positive Immutable audit trail is explicitly designed (Section 6.8) — distributions are append-only, no UPDATE/DELETE allowed. Backend enforces DISTRIBUTION_IMMUTABLE error code. Frontend shows lock icons.
2 Positive Server-authoritative timestamps (Section 6.9) — distributedAt is set by backend, not client. All times displayed in Europe/Berlin with explicit timezone indicator. Monthly reports include timezone-aware date ranges.
3 Positive Audit log viewer — admin dashboard includes a paginated event log with date range filters. I can see who distributed what, when, and to whom in chronological order.
4 Positive Compliance PDF export — "Audit-Bericht exportieren" generates a report suitable for Behörde inspections. Includes all legally required fields: timestamp (TZ-aware), member ID, quantity, batch code, staff name.
5 Positive Batch traceability intact — recall reports trace contaminated batches to affected members. Combined with immutable distribution records, this creates a complete chain of custody.
6 ⚠️ Minor No cryptographic hash chain — while records are immutable (no UPDATE/DELETE), there's no SHA-256 hash linking each record to the previous one. This means a database admin could theoretically insert backdated records. For KCanG compliance this is acceptable (not required by law), but would strengthen auditability.
7 ⚠️ Minor No inspector read-only mode — there's still no separate login for Behörde officials. They must trust the admin to show them the audit log. The compliance PDF export partially mitigates this.
8 Positive Under-21 differentiation clear — quota visualization explicitly distinguishes 25g (under-21) vs 50g (adult) with visual warnings. Compliance with §19 age-based limits is verifiable.

Scores

Dimension Score Δ from v2 Rationale
Precision 88% +18% Audit trail design, timestamp handling, and compliance export are precisely specified. Immutability enforcement is clear (backend error code + frontend lock icons).
Correctness 90% +15% Timestamps are correctly server-authoritative in Europe/Berlin. Append-only records meet KCanG audit requirements. Quota limits match §19 specifications.
Usability 78% +23% Audit log viewer and PDF export make inspections feasible. No separate inspector login is a gap but the PDF export provides a sealed artifact.
Usefulness 85% +17% The system can now demonstrate compliance during inspections: immutable records + timestamped audit trail + exportable PDF reports. Core compliance needs are met.

Composite Score: 85% (was 67%, Δ +18%)

Remaining Gaps (future enhancement)

  • Cryptographic hash chain (SHA-256 linking records) — nice-to-have, not legally required
  • Inspector read-only mode — could be a time-limited token generating feature (Sprint 6+)
  • Monthly report auto-sealing at month-end — would prevent retroactive modification concerns

5. 🔒 Security Auditor

"I'm reviewing the app for security vulnerabilities before production deployment."

Findings

# Type Observation
1 Positive CSP headers fully definedContent-Security-Policy with default-src 'self', frame-ancestors 'none', form-action 'self'. Also includes HSTS (63072000s), X-Frame-Options, X-Content-Type-Options, Permissions-Policy. Comprehensive header set.
2 Positive No hardcoded secrets anywhere.env.local uses placeholder with generation command. Docker Compose uses ${NEXTAUTH_SECRET} and ${DB_PASSWORD:-dev_password}. Security note explains production injection.
3 Positive Cookie security verified — HttpOnly, Secure (prod), SameSite=Lax. JWT never exposed to client JavaScript. This is NextAuth's default but explicitly confirmed.
4 Positive Rate limiting acknowledged — backend enforces 5 attempts/15min. Frontend shows "Zu viele Anmeldeversuche" on 429. The backend enforcement is the correct layer for this.
5 Positive CSRF protection via NextAuth — built-in csrfToken verification in credential forms. Explicitly mentioned in section 6.6.
6 Positive Input sanitization strategy — all inputs validated with Zod schemas. No dangerouslySetInnerHTML. Server-side validation remains authoritative. Defense in depth.
7 ⚠️ Minor CSP allows unsafe-inline and unsafe-eval for scripts — necessary for Next.js in development mode. In production, could tighten with nonce-based CSP. Plan notes this with comment "Next.js requires unsafe-inline/eval in dev".
8 Positive API proxy pattern (rewrites) means backend URL never exposed to browser. Combined with CSP connect-src 'self', external data exfiltration is blocked.
9 Positive Immutable distribution records — append-only design prevents data tampering through the application layer. Good defense against insider threats.

Scores

Dimension Score Δ from v2 Rationale
Precision 90% +15% CSP header values are exact. Cookie attributes are specified. Rate limiting parameters defined. Secret management guidance is clear.
Correctness 92% +14% Security architecture is sound: server-side tokens, CSP, HSTS, SameSite cookies, input validation, no secret exposure. The unsafe-inline/eval is a known Next.js trade-off.
Implementability 90% +10% All security measures are implementable within the sprint. CSP headers are copy-paste. Secret management guidance prevents common mistakes.
Usefulness 88% +18% The plan now provides a production-ready security posture. Only nonce-based CSP (removing unsafe-inline) would improve it, and that's a post-MVP optimization.

Composite Score: 90% (was 76%, Δ +14%)

Remaining Gaps (post-MVP optimization)

  • Nonce-based CSP to eliminate unsafe-inline/unsafe-eval — requires Next.js middleware integration
  • Subresource Integrity (SRI) for third-party scripts — no third-party scripts planned, so N/A

6. 🎨 UX Designer

"I'm evaluating the user experience and accessibility of the planned UI."

Findings

# Type Observation
1 Positive Empty states are comprehensively defined — each list page has a specific message and CTA. "Noch keine Mitglieder vorhanden" + "Erstes Mitglied anlegen" button. No blank pages anywhere.
2 Positive WCAG 2.1 AA compliance target with specific implementations — focus rings (ring-2 ring-ring ring-offset-2), skip-nav link, aria-live regions for toasts, reduced motion support. Not just a checklist but actual CSS and implementation guidance.
3 Positive Color contrast verified#E6EDF3 on #0D1117 = 13.5:1 , #2ECC71 on #0D1117 = 7.5:1 . Numbers given, not just "meets AA".
4 Positive Quota visualization with color coding — green/amber/red progress bars with exact thresholds (50%/80%). This provides instant visual feedback about quota status.
5 Positive Loading skeletons expanded — specific skeleton patterns for stat cards, tables, quota rings, and charts. Users always see a structured placeholder during load.
6 Positive Offline indicator — subtle banner "Keine Internetverbindung" shows without interrupting flow. Good progressive enhancement.
7 Positive Screen reader announcements — toasts use role="alert" with appropriate aria-live politeness levels. Quota updates and form results are announced.
8 ⚠️ Minor No micro-interactions/transitions still — page transitions, form animations remain unspecified. The plan is functional but won't feel "polished". Acceptable for MVP.
9 ⚠️ Minor Distribution form still lacks visual progress stepper — 3-step flow doesn't have a step indicator component specified. Users may not know they're on step 2 of 3.

Scores

Dimension Score Δ from v2 Rationale
Precision 88% +16% Empty states have exact messages per page. Accessibility has CSS values. Color coding has numeric thresholds. Significant improvement in UX specification.
Correctness 90% +8% Color contrast ratios are verified. WCAG 2.1 AA implementations are technically correct. Loading patterns follow best practices.
Usability 86% +16% Empty states, offline indicator, color-coded quota, and accessibility improvements make the app usable by a wider audience. Missing animations keep it from "delightful".
Usefulness 88% +10% The plan now delivers a usable, accessible, and informative MVP. Users can understand their status at a glance. Accessibility means no users are excluded.

Composite Score: 88% (was 76%, Δ +12%)

Remaining Gaps (polish, Sprint 5)

  • Page transition animations (Framer Motion or next-view-transitions)
  • Distribution form progress stepper (3-dot visual indicator)
  • Portal visual differentiation from admin (subtle color shift)

Summary Matrix

Persona Precision Correctness Usability Usefulness Composite Δ from v2
👤 Club Member 90% 92% 85% 86% 88% +9%
🏢 Club Owner 92% 90% 82% 88% 88% +12%
💻 Developer 95% 90% 92% 93% 93% +7%
🛡️ Compliance Officer 88% 90% 78% 85% 85% +18%
🔒 Security Auditor 90% 92% 90%¹ 88% 90% +14%
🎨 UX Designer 88% 90% 86% 88% 88% +12%

¹ Security Auditor "Usability" replaced with "Implementability"

Overall Plan Score: 89% (was 77%, Δ +12%)

Dimension Averages (across all personas)

Dimension Average Δ from v2 Weakest Persona
Precision 91% +12% Compliance Officer (88%)
Correctness 91% +10% Developer / Compliance / UX (90%)
Usability 86% +16% Compliance Officer (78%)
Usefulness 88% +13% Compliance Officer (85%)

Iteration Comparison

Persona Iteration 1 (v2) Iteration 2 (v3) Delta Target Met (≥90%)
👤 Club Member 79% 88% +9% ⚠️ Close (88%)
🏢 Club Owner 76% 88% +12% ⚠️ Close (88%)
💻 Developer 86% 93% +7% Yes
🛡️ Compliance Officer 67% 85% +18% ⚠️ No (85%)
🔒 Security Auditor 76% 90% +14% Yes
🎨 UX Designer 76% 88% +12% ⚠️ Close (88%)

Personas at or above 90%: 2 of 6 (Developer, Security Auditor) Personas at 85-89%: 4 of 6 (all close but below target)


Verdict

The v3 plan represents a significant improvement across all dimensions (+12% overall). The largest lift was for the Compliance Officer persona (+18%), which went from the weakest performer (67%) to a solid 85% thanks to the audit trail, timestamp verification, and compliance export additions.

Key remaining gaps preventing all personas from reaching 90%:

  1. Compliance Officer (85%) — lacks cryptographic hash chain and inspector read-only mode. These are enhancements beyond KCanG requirements but would provide stronger audit guarantees. The 85% score reflects a system that meets legal compliance needs but doesn't exceed them.

  2. Club Member (88%) — lacks proactive notifications (recall alerts, quota reset reminders) and PWA support. Both are explicitly deferred to Sprint 5+. The core portal experience is excellent.

  3. Club Owner (88%) — lacks staff management and club settings UI. These are Sprint 5 scope. Daily operations (today summary, search, alerts) are well-covered.

  4. UX Designer (88%) — lacks micro-interactions/transitions and distribution form progress stepper. These are polish items that don't affect functionality.

Assessment: The plan is implementation-ready for a frontend MVP sprint. All critical gaps from Iteration 1 have been addressed. The remaining gaps are explicitly deferred scope (Sprint 5+) or post-MVP polish — they do not represent missing requirements for Sprint 4.

Recommendation: GO — proceed to implementation. The 4 personas at 85-89% have gaps that are intentionally out of Sprint 4 scope. No blocking issues remain.