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
14 KiB
CannaManage — User Stories
Version: 1.0 Date: 2026-06-13 Status: Complete
Persona: Admin/Staff (Vereinsverwaltung)
US-A01: Admin Login
As an admin, I want to log in with my email and password, So that I can access the management dashboard securely.
Acceptance Criteria:
- Login page displays email and password fields
- Form validates email format (Zod schema)
- Empty fields trigger validation errors with
aria-invalid - Invalid credentials show localized error message
- Successful login redirects to
/dashboard - Password field is masked (type="password")
- Form is keyboard-navigable (Tab + Enter)
US-A02: Dashboard Overview
As an admin, I want to see KPI cards on my dashboard, So that I can monitor club status at a glance.
Acceptance Criteria:
- Dashboard shows 4 KPI cards: Active Members, Distributions Today, Stock Level, Monthly Quota Used
- Quick actions section provides shortcuts to common tasks
- Recent distributions list shows latest activity
- Stock by strain visualization is present
- Page is responsive (cards stack on mobile)
- Dark/light mode renders correctly
US-A03: Member List Management
As an admin, I want to view, search, and paginate through members, So that I can quickly find and manage club members.
Acceptance Criteria:
- Member table displays: name, email, status, joined date, member number
- Status badges show Active/Inactive/Suspended with color coding
- Search input filters members by name or email
- Pagination controls navigate between pages
- "Add Member" button navigates to creation form
- Clicking a member navigates to their detail page
US-A04: Add New Member
As an admin, I want to register a new member with their details, So that they can start receiving distributions.
Acceptance Criteria:
- Form includes: first name, last name, email, date of birth, phone, notes
- All required fields show validation errors when empty
- Date of birth calculates age for KCanG compliance checks
- Email must be unique (backend validation)
- Success redirects to member detail page
- Cancel returns to member list without saving
US-A05: Edit Member Details
As an admin, I want to edit an existing member's information, So that I can keep records current.
Acceptance Criteria:
- Form pre-fills with existing member data
- All editable fields can be updated
- Status can be changed (Active/Inactive/Suspended)
- Changes are saved with confirmation
- Audit event is logged on status change
US-A06: Distribution List
As an admin, I want to view all cannabis distributions with filters, So that I can track dispensing history.
Acceptance Criteria:
- Table shows: date, member name, strain, amount (grams), recorded by
- Filter by time period: today, this week, this month, all
- Sort by date (newest first by default)
- "New Distribution" button starts the wizard
- Total distributed amount shown in header
US-A07: Distribution Wizard (4-Step)
As an admin, I want to record a distribution through a guided wizard, So that quota limits are enforced before dispensing.
Acceptance Criteria:
- Step 1: Select member (search by name/number)
- Step 2: Quota check shows daily/monthly remaining (25g daily, 50g monthly)
- Under-21 shows 30g monthly limit and 10% THC restriction
- Blocks progression if limits exceeded
- Step 3: Select strain + enter amount (grams)
- THC% shown per strain for under-21 verification
- Amount cannot exceed available batch stock
- Step 4: Confirmation summary → submit
- Success creates distribution record + audit event
- Back navigation between steps preserves data
US-A08: Stock/Batch Management
As an admin, I want to manage cannabis batches in inventory, So that I can track available stock.
Acceptance Criteria:
- Batch list shows: strain, THC%, CBD%, available grams, status
- Overview cards: total stock, active batches, low stock alerts
- Filter by strain or batch status
- "Add Batch" button opens creation form
- Stock levels update after distributions
US-A09: Add New Batch
As an admin, I want to register a new cannabis batch, So that it becomes available for distribution.
Acceptance Criteria:
- Form includes: strain name, THC%, CBD%, total grams, harvest date, notes
- THC% and CBD% are numeric with validation (0-100)
- Total grams must be positive
- Batch gets unique ID and "Available" status
- Can link to a grow entry (traceability)
US-A10: Grow Calendar
As an admin, I want to track plant grows through their lifecycle stages, So that I can manage cultivation from seed to harvest.
Acceptance Criteria:
- Calendar/list shows all active grows with current stage
- 7 stages: Seedling → Vegetative → Flowering → Harvest → Drying → Curing → Complete
- Stage progression is sequential (can't skip)
- Each grow shows: strain, start date, current stage, days in stage
- Color-coded stage indicators
US-A11: Grow Detail
As an admin, I want to manage a specific grow entry in detail, So that I can record sensors, photos, and feeding.
Acceptance Criteria:
- Sensor readings displayed: temperature, humidity, CO2, pH, EC
- Photo gallery with upload capability
- Feeding log with date, nutrients, amount
- Timeline showing stage transitions
- "Advance Stage" button with confirmation
- Harvest → links to batch creation (traceability)
US-A12: Reports
As an admin, I want to generate compliance reports, So that I can satisfy regulatory requirements.
Acceptance Criteria:
- Three report types: Monthly Report, Member List, Recall Report
- Preview mode shows report content in-page
- PDF download generates branded document
- CSV export for data analysis
- Monthly report includes: distributions count, total grams, member activity
- Recall report traces a batch to all distribution recipients
US-A13: Audit Log
As an admin, I want to view an immutable audit trail, So that all actions are traceable for compliance.
Acceptance Criteria:
- Shows 18+ event types (MEMBER_CREATED, DISTRIBUTION_RECORDED, BATCH_ADDED, etc.)
- Filter by event type, date range, actor
- Each entry shows: timestamp, event type, actor, details
- Tamper-proof indicator (hash chain)
- PDF export of filtered results
- 10-year retention policy displayed
- Log entries cannot be deleted (REVOKE DELETE)
US-A14: Staff Management
As an admin, I want to invite and manage staff accounts, So that I can control who has access.
Acceptance Criteria:
- Staff list shows: name, email, role, permissions, last active
- "Invite Staff" button opens invitation form (email + role)
- Permission checkboxes for granular access control
- "Revoke Access" button with confirmation dialog
- Prevention officer role limit enforced (max per KCanG)
- Invite sends email with token link
US-A15: Billing & Subscription
As an admin, I want to manage my club's subscription plan, So that I can access features appropriate to our size.
Acceptance Criteria:
- Current plan displayed with usage stats
- Three tiers: Starter (€19/≤30 members), Pro (€49/≤100 members), Enterprise
- Upgrade/downgrade available
- Payment methods: SEPA, PayPal, Card (via Stripe)
- Billing history with invoices
- 3-month free trial for new clubs
US-A16: Privacy/DSGVO Settings
As an admin, I want to handle data privacy requests, So that my club complies with GDPR.
Acceptance Criteria:
- Data Export (Art. 15): Generate JSON export of all member data
- Account Deletion (Art. 17): Delete member with confirmation
- Consent management overview
- Data processing agreement reference
- Last export/deletion timestamp shown
US-A17: Protected Route Access Control
As a system, I want to redirect unauthenticated users to login, So that admin pages are secured.
Acceptance Criteria:
- All admin routes redirect to
/loginwhen not authenticated - Redirect preserves
callbackUrlparameter - After login, user returns to originally requested page
- Session expiry triggers redirect
Persona: Member (Portal-Nutzer)
US-M01: Member Portal Login
As a member, I want to log in to my personal portal, So that I can view my quota and history.
Acceptance Criteria:
- Portal login page at
/portal-loginwith email + password - Separate from admin login (different auth flow)
- Link to admin login ("Staff login")
- Successful login redirects to
/portal/dashboard - Invalid credentials show error
US-M02: Portal Dashboard / Quota View
As a member, I want to see my daily and monthly quota usage, So that I know how much I can still receive.
Acceptance Criteria:
- Daily quota ring: X.Xg / 25g used (visual circle)
- Monthly quota ring: X.Xg / 50g used (visual circle)
- Under-21 shows 30g monthly limit
- Last distribution info: strain, amount, date
- Quick info section with member number and club name
- Navigation links to history and profile
US-M03: Distribution History
As a member, I want to view my past distributions, So that I can track what I received.
Acceptance Criteria:
- Table showing: date, strain, amount (grams), recorded by
- Sorted by date (newest first)
- Pagination for many entries
- Tamper-proof indicator per entry
- Navbar with portal navigation
- Total received this month displayed
US-M04: Member Profile
As a member, I want to view and update my personal information, So that my records stay current.
Acceptance Criteria:
- Personal info displayed: name, email, member number, date of birth
- Password change section (current + new + confirm)
- Language preference toggle (DE/EN)
- Theme preference (dark/light/system)
- Save button for changes
- Read-only fields clearly distinguished
US-M05: Portal Navigation
As a member, I want to navigate between portal pages easily, So that I can access all self-service features.
Acceptance Criteria:
- Top navbar with links: Dashboard, History, Profile
- Active page indicator in navigation
- Footer with legal links
- No sidebar (cleaner portal layout)
- Responsive at all breakpoints
Persona: Visitor (Öffentlicher Zugang)
US-V01: Pricing Page
As a visitor, I want to compare subscription plans, So that I can decide which tier to purchase.
Acceptance Criteria:
- Three plan cards: Starter, Pro, Enterprise
- Feature comparison matrix
- Price displayed per plan (€19/€49/Custom)
- FAQ section for common questions
- CTA button per plan ("Get Started" / "Contact Us")
- Responsive layout (cards stack on mobile)
US-V02: Legal Pages (Impressum, Datenschutz, AGB)
As a visitor, I want to read legal information, So that I understand the terms.
Acceptance Criteria:
/impressum— Legal notice with company info/datenschutz— Privacy policy (DSGVO-compliant)/agb— Terms of service- All pages render text content without authentication
- Proper heading hierarchy
- Footer links accessible from all public pages
US-V03: 404 Not Found
As a visitor, I want to see a helpful error page for invalid URLs, So that I can navigate back to valid content.
Acceptance Criteria:
- Custom 404 page with branded design
- "Go Home" or navigation links
- Displays on any non-existent route
- Consistent with app theme (dark/light)
Cross-Cutting: Non-Functional User Stories
US-X01: Responsive Design
As any user, I want the app to work on all device sizes, So that I can use it on mobile, tablet, or desktop.
Acceptance Criteria:
- Mobile (375px): Single column, hamburger menu, stacked cards
- Tablet (768px): Sidebar collapses, 2-column where appropriate
- Desktop (1280px): Full sidebar, multi-column layouts
- No horizontal scrollbar at any breakpoint
- Touch-friendly tap targets (≥44px)
US-X02: Dark/Light Theme
As any user, I want to switch between dark and light themes, So that I can use the app in my preferred color scheme.
Acceptance Criteria:
- Theme toggle accessible from settings/header
- Dark mode: dark backgrounds, light text, green accents
- Light mode: white backgrounds, dark text, green accents
- Preference persisted in localStorage
- System preference detection (prefers-color-scheme)
- All pages render correctly in both modes
US-X03: Internationalization (i18n)
As any user, I want the app in German or English, So that I can use it in my preferred language.
Acceptance Criteria:
- German (de) as default language
- English (en) as alternative
- All UI labels, buttons, messages translated
- Language switcher in settings
- Date/number formatting adapts to locale
- next-intl integration working
US-X04: PWA & Offline Support
As any user, I want the app to be installable and work offline, So that I can access it without constant connectivity.
Acceptance Criteria:
- Web app manifest with icons (192px, 512px)
- Service worker registered
- Offline page shows when no connectivity
- Install prompt available on supported browsers
- App icon on home screen after install
US-X05: Accessibility (a11y)
As a user with disabilities, I want the app to be accessible, So that I can use it with assistive technology.
Acceptance Criteria:
- All form inputs have associated labels
- Proper heading hierarchy (h1 → h2 → h3)
- Keyboard navigation works on all interactive elements
- ARIA attributes on dynamic content
- Color contrast meets WCAG 2.1 AA
- Focus visible on interactive elements
- Autocomplete attributes on login fields
US-X06: Notifications
As an admin, I want to receive real-time notifications, So that I'm alerted to important events.
Acceptance Criteria:
- Bell icon with unread count badge
- Notification dropdown/panel
- WebSocket (STOMP) real-time delivery
- Notification types: low stock, quota warning, new member, system alert
- Mark as read / mark all as read
- Persistent across page navigation