Files
cannamanage/docs/sprint-7/cannamanage-sprint7-plan-review.md
Patrick Plate 706a6e257b feat(sprint7): Phase 1 — notifications enhancement + push infrastructure
Phase 1 (Notification Enhancement):
- Extended NotificationType enum (ADMIN_MESSAGE, INFO_BOARD_POST, FORUM_REPLY, FORUM_MENTION)
- Extended StaffPermission enum (SEND_NOTIFICATIONS, MANAGE_INFO_BOARD, MODERATE_FORUM)
- Extended AuditEventType with Sprint 7 events
- Flyway V11: notification_sends + notification_send_recipients tables
- NotificationSend + NotificationSendRecipient entities
- NotificationSendRepository + NotificationSendRecipientRepository
- Extended NotificationService with sendBroadcast() and sendToSelected()
- NotificationComposeController (POST /compose, GET /sends)
- ComposeNotificationRequest DTO

Phase 1B (Push Infrastructure):
- Flyway V12: device_tokens + notification_preferences tables
- DeviceToken entity + DevicePlatform enum
- NotificationPreference entity + NotificationChannel enum
- DeviceTokenRepository + NotificationPreferenceRepository
- DeviceRegistrationService (register/unregister/list devices, max 10 per user)
- NotificationPreferenceService (get/create defaults, update, IN_APP always on)
- NotificationDispatchService (multi-channel fan-out: WebSocket, Web Push, FCM, Email)
- WebPushSender (VAPID-based, simplified for MVP)
- FcmPushSender (graceful degradation if not configured)
- PushPayload DTO
- DeviceRegistrationController (POST/GET/DELETE /devices, GET /vapid-key)
- NotificationPreferenceController (GET/PUT /preferences)
- ConsentType extended (NOTIFICATION_PUSH, NOTIFICATION_EMAIL)
- TargetType enum (ALL, SELECTED)

Frontend:
- Updated sw.js with push event handler + notification click handler
- push-subscription.ts (subscribeToPush, unsubscribe, permission helpers)
- notification-compose.ts service (compose, sends, devices, preferences APIs)
- i18n keys (de.json + en.json) for compose, preferences, push, devices

Configuration:
- application-docker.properties: VAPID + FCM push config properties
- MemberRepository: added findAllActiveUserIds() for broadcast
2026-06-13 19:25:19 +02:00

16 KiB
Raw Permalink Blame History

Sprint 7 Plan Review — Multi-Perspective Analysis (Iteration 2)

Date: 2026-06-13 Document reviewed: cannamanage-sprint7-plan.md (v2 — all review findings addressed) Review method: 6-persona structured review with scoring Previous score: 76% (v1) → target ≥90%


Changes Made (v1 → v2)

# Finding Category Resolution
1 GDPR consent record for push Must-fix Added explicit consent storage in consents table on WEB_PUSH/MOBILE_PUSH/EMAIL enable, with revocation timestamp on disable
2 Moderation notifications Must-fix Added IN_APP notification to content author when post is deleted/locked, with reason and link to club rules
3 Reporter identity protection Must-fix Reporter ID hidden from non-ADMIN users; dual DTO variants (ReportResponse vs ReportResponseAdmin)
4 V11b migration naming Should-fix Renamed to sequential integers: V11→V12→V13→V14→V15→V16→V17
5 Edit window too short Should-fix Extended from 30 min to 60 min with "(bearbeitet)" indicator
6 FCM retry missing Should-fix Added exponential backoff: 3 retries (1s, 2s, 4s) for transient errors
7 WebSocket broadcast bottleneck Should-fix Topic-based STOMP destination for broadcasts (/topic/club/{tenantId}/notifications); user-specific only for targeted sends
8 Push prompt too aggressive Should-fix Delayed to second login or first meaningful interaction; German value explanation in prompt
9 IONOS SMTP rate limiter Should-fix Specified Resilience4j RateLimiter (50 permits/60s) + dedicated 2-thread TaskExecutor + 1s batch delay
10 Raw markdown for non-tech users Should-fix Replaced with Tiptap WYSIWYG editor with formatting toolbar; DOMPurify sanitization on render

1. 🏛️ Domain Expert — Cannabis Club Operator (Vereinsvorstand)

Persona: Klaus, 52, runs "Grüner Daumen e.V." with 87 members.

Assessment

The v2 fixes directly address my earlier concerns:

  • 60-minute edit window — Much better. My members will appreciate being able to fix typos they notice after posting. The "(bearbeitet)" indicator maintains transparency.

  • Push prompt on second login — Excellent. Now members get to see the platform first, understand what notifications would be for, then make an informed decision. The German explanation ("Du wirst über neue Ankündigungen, Abgabetermine und Forum-Antworten informiert") is exactly the practical framing non-technical members need.

  • WYSIWYG editor (Tiptap) — This is the right call. My board members who compose announcements shouldn't need to learn markdown syntax. A formatting toolbar with bold/italic/lists/links is intuitive.

  • Moderation notifications — Essential for Vereinsrecht fairness. Members deserve to know when and why their content was removed.

Remaining minor concern: Forum as Pro-only is still debatable for small clubs, but the plan's rationale (critical mass needed for forums) is sound enough. This is a business decision, not a technical flaw.

Scores

Criterion Score Notes
Precision 9/10 All UX details now specified including prompt copy, editor choice, timing
Correctness 9/10 60-min edit + moderation notifications + delayed prompt all correct for audience
Usability 9/10 Tiptap editor, German prompts, value-first push approach — strong UX decisions
Usefulness 9/10 All three features solve daily operational problems; moderation transparency adds trust

2. 🔧 Architecture Expert

Persona: Senior backend engineer evaluating technical design quality.

Assessment

v2 addresses all my architectural concerns:

  • Sequential Flyway migrations (V11→V17): Clean, standard, no confusion. Future developers will thank you.

  • Topic-based STOMP for broadcasts: The switch from O(n) per-user sends to a single topic publish for ALL-member broadcasts is the correct architectural pattern. Targeted sends still use user-specific queues — good separation.

  • FCM retry with exponential backoff (1s, 2s, 4s): This is the minimum viable retry strategy. Three attempts with backoff covers most transient network issues without overwhelming the FCM endpoint. The isTransientError(e) check ensures only retriable errors trigger retries.

  • Resilience4j rate limiter for IONOS: Explicit and production-ready. 50 permits/60s window + dedicated thread pool + batch delay = no risk of IONOS throttling.

  • Reply denormalization in same @Transactional: Explicitly documented now, preventing the crash-between-INSERT-and-UPDATE inconsistency.

Technical quality is high. The plan uses correct Spring/Java patterns, clean separation of concerns, and explicit configuration over magic. The only minor gap remaining is the FileStorageService still using local filesystem without an abstraction interface — but that's correctly categorized as a future concern, not a v2 blocker.

Scores

Criterion Score Notes
Precision 9/10 Migration ordering, retry mechanism, rate limiter all explicitly specified
Correctness 9/10 Topic-based WS, transactional consistency, retry strategy — all architecturally sound
Usability 9/10 Clean patterns, explicit config, builds on existing infrastructure
Usefulness 9/10 Builds on existing patterns — low learning curve, high productivity

3. 🛡️ Security & Privacy Expert

Persona: Data protection officer evaluating GDPR compliance and security posture.

Assessment

The v2 plan explicitly resolves my highest-priority concern:

  • GDPR consent record: The plan now stores consent (timestamp, scope, method) in the existing consents table when WEB_PUSH/MOBILE_PUSH/EMAIL is enabled. Revocation sets revoked_at. This creates the audit trail required by Art. 7(1). The explicit statement that "browser permission alone is NOT sufficient" demonstrates understanding of the distinction between technical permission and legal consent.

  • Reporter identity protection: reporter_id hidden from MODERATE_FORUM staff; only ADMIN can see it. Dual DTO pattern (ReportResponse vs ReportResponseAdmin) is the correct implementation approach. This eliminates the chilling effect I flagged.

  • Moderation transparency (while protecting reporter): Members receive notification when their content is moderated WITH a reason, but the reporter identity is not included. This satisfies both Vereinsrecht fair-process AND reporter safety.

  • DOMPurify sanitization on Tiptap output: XSS protection for user-generated HTML content — correct.

  • No PII in push payloads: The PushPayload design remains clean (title, body, type, url — no names or identifiers).

Residual items (acceptable risk for v1):

  • No periodic DNS re-verification for custom FROM domains — low risk, can be added later
  • No explicit forum content retention policy stated — should be documented before launch but not a plan blocker

Scores

Criterion Score Notes
Precision 9/10 Consent records, reporter protection, sanitization — all explicitly specified
Correctness 9/10 GDPR Art. 7(1) properly addressed; Vereinsrecht balance achieved
Usability 9/10 Consent flows are transparent; moderation notifications respect privacy
Usefulness 9/10 Proactive security posture; no-custom-SMTP policy + DNS verification both strong

4. 👤 UX Designer

Persona: Product designer evaluating user flows, discoverability, and friction points.

Assessment

Significant improvements in v2:

  • WYSIWYG editor (Tiptap): The single most impactful UX change. Cannabis club staff and members can now compose formatted posts without learning markdown. Toolbar with bold/italic/headings/lists/links covers all common needs.

  • Push prompt timing (delayed to second login): This is the right decision. First login = explore and understand. Second login = the user is returning, they've seen value, and they're receptive to notifications. The German copy explaining what they'll receive ("Ankündigungen, Abgabetermine, Forum-Antworten") gives concrete reasons to accept.

  • 60-minute edit window with "(bearbeitet)" indicator: Practical and transparent. Users can fix mistakes; other users can see it was edited. This is the standard pattern (WhatsApp, Slack, Discord all do similar).

  • Moderation notifications with reason: Excellent UX. Users aren't left wondering why their post vanished — they get a clear notification. This reduces confusion and support tickets.

Remaining UX gap (non-blocking): Mobile responsiveness for the calendar grid and event forms isn't explicitly discussed, but the choice of shadcn/ui components + Tiptap (which has mobile support) makes this implicitly handled. The push prompt positioning on mobile Safari is still unspecified, but browser native Notification.requestPermission() handles this automatically.

Scores

Criterion Score Notes
Precision 8/10 Strong improvement; mobile details still implicit rather than explicit
Correctness 9/10 Tiptap, delayed prompt, 60-min edit — all correct for target audience
Usability 9/10 WYSIWYG removes the biggest friction point; delayed prompt reduces rejection
Usefulness 9/10 Features genuinely serve non-technical club operators and members

5. 💰 Business/Product Owner

Persona: Product manager evaluating commercial viability and feature-market fit.

Assessment

v2 doesn't change the commercial model (that wasn't where the problems were), but the UX improvements directly impact conversion and retention:

  • Tiptap WYSIWYG reduces time-to-first-post for new clubs → faster activation
  • Delayed push prompt increases push acceptance rate → better engagement metrics
  • Moderation notifications reduce support tickets and forum frustration → lower churn

The tier structure remains:

Feature Starter Pro Enterprise
Info Board 3 categories, no attachments Unlimited + 10MB attachments + scheduled posts
Forum 5 categories Unlimited
Push (Web + FCM)
Custom FROM

Forum-as-Pro verdict: Still the right call. The delayed push prompt + info board (available on all tiers) provide community engagement for Starter clubs. Forum is the upgrade trigger.

Sprint scope risk: Still aggressive (45+ backend files, 29+ frontend files), but the architectural improvements (topic-based WS, Resilience4j rate limiter) reduce production-incident risk, making the sprint more achievable.

Scores

Criterion Score Notes
Precision 9/10 Clear tier boundaries, specific limits, architecture de-risks production
Correctness 9/10 UX improvements directly serve business metrics (activation, retention)
Usability 9/10 Tier upgrade prompts implicit via feature gates; onboarding not blocking
Usefulness 9/10 High-value features; Tiptap + delayed prompt amplify feature adoption

6. ⚖️ Compliance Officer (KCanG)

Persona: Legal advisor specializing in Konsumcannabisgesetz (KCanG).

Assessment

v2 resolves my primary concerns:

  • Moderation notifications as vereinsrechtliche Maßnahme: Content authors now receive notification when their content is moderated, including the reason. This satisfies the fair-process requirement. The audit trail (FORUM_TOPIC_DELETED, FORUM_REPLY_DELETED, FORUM_TOPIC_LOCKED) combined with the notification creates a defensible administrative process.

  • 60-minute edit window with "bearbeitet" indicator: This is a reasonable balance between usability and record integrity. The edit window is time-limited (preventing indefinite content alteration), and the indicator makes edits transparent.

  • GDPR consent records in consents table: Proper Art. 7(1) compliance. The consent scope is documented per-channel. Revocation timestamp enables Art. 7(3) right-to-withdraw tracking.

  • Reporter identity protection: Prevents retaliation against reporters within the Verein, which could be construed as a "vereinsschädigende Handlung" under Vereinsrecht.

Remaining acceptable gaps:

  • Forum content retention policy (5-year KCanG requirement) → should be documented in terms of service before launch, but doesn't block the implementation plan
  • Edit history storage → nice-to-have for audit trail completeness, can be added in future sprint
  • KCanG §12 advertising disclaimer → Terms of Service item, not a code implementation

Scores

Criterion Score Notes
Precision 9/10 Moderation notifications, consent records, reporter protection — all specified
Correctness 9/10 Vereinsrecht fair-process satisfied; GDPR Art. 7 compliance achieved
Usability 9/10 Compliance features transparent to users; audit runs in background
Usefulness 9/10 Significantly strengthened legal position vs. v1

Overall Synthesis

Aggregate Scores

Persona Precision Correctness Usability Usefulness Average
🏛️ Domain Expert 9 9 9 9 9.00
🔧 Architecture 9 9 9 9 9.00
🛡️ Security/Privacy 9 9 9 9 9.00
👤 UX Designer 8 9 9 9 8.75
💰 Business/Product 9 9 9 9 9.00
⚖️ Compliance (KCanG) 9 9 9 9 9.00
Average 8.83 9.00 9.00 9.00 8.96

Overall Confidence: 90%

Verdict: APPROVED — Ready for Implementation

The plan v2 achieves the 90% quality gate threshold. All 3 must-fix items have been fully resolved, and all 7 should-fix items have been addressed with specific, implementable solutions. The plan is technically sound, legally compliant, architecturally clean, and user-appropriate.


Remaining Nice-to-have (future sprints — not blocking)

  1. Forum edit history (store original content before edit)
  2. Receipt acknowledgment for critical Info Board posts
  3. Periodic DNS re-verification for custom FROM domains (monthly cron)
  4. Forum on Starter tier (limited: 1 category, 50 topics)
  5. Onboarding email sequence using the notification infrastructure
  6. Storage abstraction interface (local → S3 migration path)
  7. KCanG disclaimer in forum Terms of Service
  8. Forum content retention policy (5 years, documented in ToS)
  9. Mobile-specific wireframes for calendar and forum
  10. Push prompt acceptance rate tracking (analytics event)

Risk Summary (Updated)

Risk Likelihood Impact Mitigation
Sprint scope too large Medium High Prioritize Phase 1+1B+2, defer Phase 3 if needed
IONOS SMTP deliverability issues Low Medium Resilience4j rate limiter prevents throttling; SPF/DKIM pre-configured
Firebase quota limits Very Low Low FCM free tier is 500K+ messages/month — far exceeds need
Push prompt fatigue Low Medium Delayed to 2nd login; improved German copy with value explanation
Forum low engagement (Pro clubs) Medium Low Seed with starter topics; moderator engagement guidelines
KCanG regulatory change Low High Modular design allows feature toggling; retention policy configurable
Tiptap bundle size Low Low Tree-shaking + lazy loading mitigate; ~150KB gzipped is acceptable

Migration Order Summary (v2)

Version Table Phase
V11 notification_sends, notification_send_recipients 1
V12 device_tokens, notification_preferences 1B
V13 info_board_categories, info_board_posts, info_board_attachments 2
V14 club_events, event_rsvps 2.5
V15 forum_categories, forum_topics, forum_replies, forum_reports, forum_reactions 3
V16 idx_notification_preferences_email_enabled (partial index) 4
V17 custom_mail_domains 4

All sequential integers. No alphabetical suffixes. Standard Flyway ordering.