# CannaManage — User Stories & Acceptance Criteria

**Author:** Patrick Plate  
**Date:** 2026-04-06  
**Version:** 1.0  
**Status:** Draft for Review

---

## MoSCoW Summary

| Priority | Count | Release Target | Description |
|----------|-------|----------------|-------------|
| 🔴 **Must Have** | 14 (US-001–014) | MVP v1 | Core compliance loop; legally required features |
| 🟡 **Should Have** | 4 (US-015–018) | v2 | Growth and retention features |
| 🟢 **Could Have** | 4 (US-019–022) | v3 | Scale and differentiation features |
| ⚫ **Won't Have (MVP)** | 3 (US-023–025) | Never / Post-legal-review | Explicitly excluded — legal or strategic |

---

## Must Have — MVP v1

### Club Admin Stories

---

### US-001: Register Club and Complete Setup Wizard

**As a** Club Admin, **I want to** register my Anbauvereinigung and complete a guided setup wizard, **so that** my club is correctly configured with all legally required attributes before any members are added.

**Priority:** Must Have  
**Acceptance Criteria:**
- [ ] AC1: Admin can register with email + password; email confirmation required before accessing the system
- [ ] AC2: Setup wizard collects: club name, registered address, founding date, Vereinsregisternummer (if available), maximum membership count
- [ ] AC3: Wizard requires designation of a Prevention Officer (name, contact) — field is mandatory, cannot be skipped
- [ ] AC4: Wizard requires acceptance of DSGVO data processing agreement (AVV) before any member data can be entered
- [ ] AC5: Completing the wizard provisions the club's isolated tenant environment (all subsequent data scoped to this club only)
- [ ] AC6: Admin receives a welcome email with login link after successful setup
- [ ] AC7: Incomplete wizard state is saved — admin can resume from last completed step

**Notes:** The AVV acceptance (AC4) is a legal prerequisite for handling member personal data under DSGVO. It must be timestamped and stored.

---

### US-002: Add and Remove Members with Age Verification

**As a** Club Admin, **I want to** add and remove club members with age verification, **so that** the member roster is accurate and the system can apply the correct distribution limits per member.

**Priority:** Must Have  
**Acceptance Criteria:**
- [ ] AC1: Admin can add a member with: full name, date of birth, email (optional), membership start date, member ID (auto-generated or manual)
- [ ] AC2: System rejects members with date of birth indicating age < 18
- [ ] AC3: Members aged 18–21 are automatically flagged as "Restricted (§23 CanG)" — this flag drives reduced quantity limits
- [ ] AC4: Admin can deactivate (soft-delete) a member; deactivated members cannot receive distributions but their historical records are preserved
- [ ] AC5: Admin can permanently delete a member record (DSGVO Art. 17 right to erasure); system warns if member has distribution history and requires explicit confirmation
- [ ] AC6: Member list is searchable by name and filterable by status (active / restricted / deactivated)
- [ ] AC7: Total active member count is visible on the dashboard and in the member list header

**Notes:** Hard deletion (AC5) must cascade correctly — distribution records referencing the member must be anonymised, not deleted, to preserve the compliance audit trail.

---

### US-003: Record a Distribution

**As a** Club Admin, **I want to** record each cannabis distribution to a member, **so that** every handout is documented as required by §26 CanG and the member's consumption is tracked.

**Priority:** Must Have  
**Acceptance Criteria:**
- [ ] AC1: Admin can log a distribution by selecting: member (search/autocomplete), strain, weight in grams (decimal, e.g. 3.5g), batch, date and time
- [ ] AC2: System pre-fills date/time with current timestamp; admin can override
- [ ] AC3: If the distribution would cause the member to exceed their daily limit (25g), the system displays a prominent warning and requires explicit override confirmation
- [ ] AC4: If the distribution would cause the member to exceed their monthly limit (50g adult / 30g restricted), the system **blocks** the entry and displays the reason
- [ ] AC5: For restricted members (§23), system additionally validates that the selected strain's THC percentage is ≤ 10% (if THC% is recorded on the batch)
- [ ] AC6: Successfully saved distributions appear immediately in the distribution log and update the member's monthly counter
- [ ] AC7: Distribution records are immutable after creation — admin can only add a correction note, not edit the original record

**Notes:** Immutability (AC7) is essential for audit integrity. Correction notes are the appropriate mechanism for errors.

---

### US-004: View and Enforce Distribution Limits

**As a** Club Admin, **I want to** view each member's current distribution totals and remaining quota, **so that** I can verify limits at a glance before and after recording distributions.

**Priority:** Must Have  
**Acceptance Criteria:**
- [ ] AC1: Each member's detail view shows: distributions this month (total grams), daily total for today, remaining monthly quota, and limit category (Adult 50g / Restricted 30g)
- [ ] AC2: Remaining quota is displayed as a progress bar (visual indicator of how close to the limit)
- [ ] AC3: Members who have reached or exceeded their monthly limit are visually flagged in the member list (e.g., red badge)
- [ ] AC4: Members who have consumed > 80% of their monthly limit show a warning indicator (e.g., amber badge)
- [ ] AC5: Monthly counters reset automatically on the first of each calendar month
- [ ] AC6: System applies §22 limits (50g/month, 25g/day) for adults and §23 limits (30g/month) for restricted members — these cannot be changed by the admin

**Notes:** The limits in AC6 are statutory and must be hardcoded, not configurable per club.

---

### US-005: Manage Stock (Strains, Quantities, Batches)

**As a** Club Admin, **I want to** manage my club's cannabis stock including strains, batch information, and quantities, **so that** I know what is available for distribution and can track batch provenance for contamination purposes.

**Priority:** Must Have  
**Acceptance Criteria:**
- [ ] AC1: Admin can create a strain with: name, THC% (optional), CBD% (optional), variety type (Indica/Sativa/Hybrid)
- [ ] AC2: Admin can create a batch linked to a strain with: batch ID (auto-generated), quantity in grams, harvest date (optional), grow cycle reference (optional)
- [ ] AC3: Each distribution recorded reduces the associated batch's available quantity
- [ ] AC4: Admin can manually adjust stock quantity with a reason note (e.g., "lab sample", "disposal")
- [ ] AC5: Admin is warned (but not blocked) when a batch's available quantity drops below a configurable threshold (default: 100g)
- [ ] AC6: Stock overview page shows all active batches with: strain name, batch ID, quantity available, quantity distributed to date
- [ ] AC7: Depleted batches (quantity = 0) are automatically moved to an "archived" view

**Notes:** Batch tracking is required for contamination recall (US-009). The batch ID must be immutable once created.

---

### US-006: View Admin Dashboard

**As a** Club Admin, **I want to** see a summary dashboard when I log in, **so that** I have an at-a-glance overview of club activity and can identify anything requiring attention.

**Priority:** Must Have  
**Acceptance Criteria:**
- [ ] AC1: Dashboard displays: total active members, members at/near their monthly limit (count), total distributions this calendar month (grams), active stock level (total grams across all batches)
- [ ] AC2: Dashboard shows a count of members in the "restricted §23" category separately
- [ ] AC3: Dashboard highlights any batches flagged as contaminated (contamination alert count)
- [ ] AC4: Dashboard includes a recent activity feed (last 10 distributions: member name, strain, weight, time)
- [ ] AC5: All dashboard data reflects the admin's own club only — never cross-tenant data
- [ ] AC6: Dashboard loads in < 3 seconds on Hetzner VPS hardware

**Notes:** Keep the dashboard simple for MVP — a single page with widgets. No charts required for v1.

---

### US-007: Export Monthly Compliance Report (PDF + CSV)

**As a** Club Admin, **I want to** export a monthly compliance report as PDF and CSV, **so that** I can fulfil my documentation and reporting obligations under §26 CanG.

**Priority:** Must Have  
**Acceptance Criteria:**
- [ ] AC1: Admin can select any calendar month/year and generate a compliance report
- [ ] AC2: PDF report contains: club name, reporting period, total distributions (count and weight), distribution detail table (member ID, strain, batch, weight, date/time), stock summary
- [ ] AC3: Member names in the PDF are replaced with member IDs to minimise PII exposure in the report document (actual name lookup available to the club separately)
- [ ] AC4: CSV export contains full distribution log for the selected period with headers: member_id, strain, batch_id, weight_g, distribution_date, distribution_time
- [ ] AC5: PDF is generated server-side using iText 7 (no client-side rendering dependency)
- [ ] AC6: Export completes in < 10 seconds for a month with up to 5,000 distribution records
- [ ] AC7: Generated reports are not stored on the server — they are streamed directly to the browser as a download

**Notes:** Not storing reports (AC7) reduces data exposure risk. The club is responsible for retaining their own copies.

---

### US-008: Export Member List for Inspections

**As a** Club Admin, **I want to** export the current member list, **so that** I can present it to authorities during an inspection as required by law.

**Priority:** Must Have  
**Acceptance Criteria:**
- [ ] AC1: Admin can export the active member list as PDF and CSV at any time
- [ ] AC2: Export includes: member ID, full name, date of birth, age category (Adult/Restricted §23), membership start date, current membership status
- [ ] AC3: Export is timestamped with the generation date/time in the document
- [ ] AC4: Admin is shown a DSGVO reminder before downloading (this document contains personal data — handle per your privacy obligations)
- [ ] AC5: Export includes the club name and address in the header
- [ ] AC6: Only active members are included by default; admin can optionally include deactivated members

**Notes:** This document contains significant PII. The DSGVO reminder (AC4) is important to keep admins legally aware.

---

### US-009: Trigger Contamination Alert for a Batch

**As a** Club Admin, **I want to** flag a batch as contaminated and immediately see all members who received from it, **so that** I can notify affected members and fulfil my contamination traceability obligations under CanG.

**Priority:** Must Have  
**Acceptance Criteria:**
- [ ] AC1: Admin can mark any batch as "contaminated" with a reason note and timestamp
- [ ] AC2: Immediately upon flagging, system displays a list of all members who received distributions from the contaminated batch (name, member ID, total grams received, dates received)
- [ ] AC3: Contaminated batches are removed from the active distribution interface — admin cannot select them for new distributions
- [ ] AC4: The dashboard shows a contamination alert badge whenever any active batch is flagged
- [ ] AC5: Admin can export the affected member list as PDF and CSV (for authority notification)
- [ ] AC6: Contamination status is immutable — once flagged, only a senior action (with confirmation) can reverse it; reversal is logged with reason

**Notes:** Contamination traceability is explicitly required by CanG. Response speed matters — the affected member list (AC2) must display without delay.

---

### US-010: Manage Prevention Officer Information

**As a** Club Admin, **I want to** record and update Prevention Officer (Präventionsbeauftragter) information, **so that** my club meets the mandatory requirement of §27 CanG.

**Priority:** Must Have  
**Acceptance Criteria:**
- [ ] AC1: Club profile includes a Prevention Officer section with fields: full name, contact email, contact phone, designation date
- [ ] AC2: All four fields are required — the system warns if any is empty and marks the section as incomplete
- [ ] AC3: Admin can update the Prevention Officer at any time; previous officer entries are retained in a change log (name, designation period)
- [ ] AC4: The compliance report export (US-007) includes the current Prevention Officer name and contact in its header
- [ ] AC5: Setup wizard (US-001) cannot be completed without entering Prevention Officer information

**Notes:** This is a statutory requirement, not optional. AC5 enforces that clubs cannot operate on the platform without this data.

---

### Member Portal Stories

---

### US-011: Login with Club-Issued Credentials

**As a** Club Member, **I want to** log in to the member portal using credentials issued by my club, **so that** I can access my personal information without the club admin needing to be present.

**Priority:** Must Have  
**Acceptance Criteria:**
- [ ] AC1: Admin can generate login credentials (username + temporary password) for a member from the member management screen
- [ ] AC2: Member receives credentials via a secure channel (displayed to admin for manual handoff in MVP; email in v2)
- [ ] AC3: Member is required to change their temporary password on first login
- [ ] AC4: Member login is scoped to their club only — they cannot access any other club's data or member list
- [ ] AC5: Failed login attempts are rate-limited (5 attempts, then 15-minute lockout)
- [ ] AC6: Member sessions expire after 24 hours of inactivity
- [ ] AC7: Members cannot register themselves — accounts are always created by the Club Admin

**Notes:** AC7 is critical for CanG compliance — only verified, age-checked members should have portal access.

---

### US-012: View Personal Distribution History

**As a** Club Member, **I want to** view my personal distribution history, **so that** I can track what I have received from the club.

**Priority:** Must Have  
**Acceptance Criteria:**
- [ ] AC1: Member can view all their distributions in reverse chronological order: date/time, strain, weight (grams), batch ID
- [ ] AC2: Current calendar month distributions are shown first, with a clear monthly subtotal
- [ ] AC3: Member can filter history by month/year
- [ ] AC4: Member sees only their own distribution history — no other member's data is accessible
- [ ] AC5: History is read-only — members cannot edit or delete distribution records

---

### US-013: View Current Stock Availability

**As a** Club Member, **I want to** see what strains are currently available at the club, **so that** I know what I can request on my next visit.

**Priority:** Must Have  
**Acceptance Criteria:**
- [ ] AC1: Member portal shows a stock list with: strain name, variety type (Indica/Sativa/Hybrid), THC% (if recorded), availability status (Available / Low Stock / Unavailable)
- [ ] AC2: Exact batch quantities are NOT shown to members — only availability status
- [ ] AC3: Only strains with available stock (quantity > 0) are shown as "Available"
- [ ] AC4: Strains with stock below the admin-configured low-stock threshold are shown as "Low Stock"
- [ ] AC5: For restricted members (§23 CanG), strains with THC > 10% are shown with a "Not available to you" indicator rather than hidden (transparency about why)
- [ ] AC6: Stock view is refreshed in real time — no stale cache longer than 5 minutes

**Notes:** AC2 is important — showing exact quantities could constitute advertising for the club's stock. Only availability status is shown.

---

### US-014: View Remaining Monthly Quota

**As a** Club Member, **I want to** see my remaining monthly quota, **so that** I can plan my distributions and stay within my legal limits.

**Priority:** Must Have  
**Acceptance Criteria:**
- [ ] AC1: Member portal homepage prominently displays: consumed this month (grams), remaining quota (grams), monthly limit (grams), days remaining in current month
- [ ] AC2: Quota is displayed as a progress bar with colour coding: green (< 50% used), amber (50–80% used), red (> 80% used)
- [ ] AC3: Members in the restricted §23 category see their 30g/month limit (not the 50g adult limit)
- [ ] AC4: Daily limit status is also visible: consumed today (grams) vs. 25g daily cap
- [ ] AC5: Quota resets display on the first of each calendar month — confirmed visually (e.g., "Resets in X days")

---

## Should Have — v2

---

### US-015: Process Membership Fee Payments via Stripe

**As a** Club Admin, **I want to** collect membership fees from members via Stripe, **so that** fee collection is automated and documented without manual bank transfers.

**Priority:** Should Have  
**Acceptance Criteria:**
- [ ] AC1: Admin can configure an annual membership fee amount for their club
- [ ] AC2: Members can pay via Stripe-hosted checkout (card payment)
- [ ] AC3: Stripe subscription or one-time payment for annual fee — admin configures which model
- [ ] AC4: Payment confirmation is logged against the member record with date and amount
- [ ] AC5: Admin can view payment status per member (paid / pending / overdue)
- [ ] AC6: No cannabis product payments are ever processed through this system — fee is for club membership only

**Notes:** Stripe position: membership fees for registered non-profit clubs (Vereinsbeiträge) are standard use case. AC6 must be enforced at system design level.

---

### US-016: Manage Automated Waiting List

**As a** Club Admin, **I want to** manage a waiting list for new membership applicants, **so that** I can process applications in order while respecting the club's maximum membership count.

**Priority:** Should Have  
**Acceptance Criteria:**
- [ ] AC1: Admin can set a maximum member count for the club (from setup wizard or settings)
- [ ] AC2: When member count reaches maximum, new applicants are added to a waiting list with timestamp
- [ ] AC3: Waiting list is FIFO — applicants are offered membership in order of application
- [ ] AC4: Admin can notify the next waiting list applicant (email notification — v2 dependency)
- [ ] AC5: Admin can remove applicants from the waiting list
- [ ] AC6: Waiting list count is visible on the admin dashboard

---

### US-017: Receive Email and SMS Notifications

**As a** Club Member, **I want to** receive email (and optionally SMS) notifications for key events, **so that** I am informed without needing to log in to the portal.

**Priority:** Should Have  
**Acceptance Criteria:**
- [ ] AC1: Member receives email notification when their distribution is recorded by the admin
- [ ] AC2: Member receives email when their monthly quota reaches 80% consumed
- [ ] AC3: Member receives email when a batch they received from is flagged as contaminated
- [ ] AC4: Admin receives email when any member's quota is exceeded (should not happen, but safety net)
- [ ] AC5: SMS notifications are optional and require member opt-in; email is default
- [ ] AC6: All notification emails are sent in German (language is not configurable in v2)
- [ ] AC7: Members can manage notification preferences (opt out of non-mandatory notifications)

---

### US-018: Track Multi-Strain Grow Cycles

**As a** Club Admin, **I want to** track grow cycles linked to batches, **so that** I have full provenance from grow start to distribution.

**Priority:** Should Have  
**Acceptance Criteria:**
- [ ] AC1: Admin can create a grow cycle with: cycle ID, strain, start date, expected harvest date, grow area (optional), notes
- [ ] AC2: Batches can be linked to a grow cycle
- [ ] AC3: Grow cycle view shows: all batches produced, total yield, grow duration
- [ ] AC4: Closed grow cycles (harvest complete) are archived but remain searchable
- [ ] AC5: Grow cycle data is included in the monthly compliance report (batch provenance section)

---

## Could Have — v3

---

### US-019: Access Mobile PWA

**As a** Club Member, **I want to** use CannaManage on my smartphone without installing an app, **so that** I can check my quota and stock on the go.

**Priority:** Could Have  
**Acceptance Criteria:**
- [ ] AC1: The member portal is fully responsive and usable on mobile viewport sizes (320px and up)
- [ ] AC2: The app can be added to the home screen (PWA manifest, service worker, offline cache for quota display)
- [ ] AC3: Core member portal features (quota, distribution history, stock view) work in offline mode with cached data
- [ ] AC4: Admin portal is also responsive (admin-on-the-go distribution logging)
- [ ] AC5: No app store submission required — pure PWA

---

### US-020: Support Multi-Location Club

**As a** Club Admin, **I want to** manage a club with multiple distribution locations, **so that** members can pick up from different sites and all distributions are consolidated.

**Priority:** Could Have  
**Acceptance Criteria:**
- [ ] AC1: Admin can define multiple locations (name, address) for one club
- [ ] AC2: Distributions are recorded with a location tag
- [ ] AC3: Stock is managed per location or shared — admin configures which model
- [ ] AC4: Compliance reports can be generated per location or consolidated for the whole club
- [ ] AC5: Members are assigned a primary location but can receive from any location within quota limits

---

### US-021: Download Legal Document Templates

**As a** Club Admin, **I want to** download standardised legal document templates (Satzung, Jugendschutzkonzept), **so that** I can fulfil my legal obligations without hiring a lawyer for every document.

**Priority:** Could Have  
**Acceptance Criteria:**
- [ ] AC1: Template library is accessible from the admin portal (separate from compliance exports)
- [ ] AC2: Available templates include: Vereinssatzung (club charter), Jugendschutzkonzept (youth protection concept), DSGVO Datenschutzerklärung
- [ ] AC3: Templates are pre-filled with club-specific data (name, address, Prevention Officer) where applicable
- [ ] AC4: Templates are available as DOCX (editable) and PDF (final version)
- [ ] AC5: Template library is a paid add-on (€49 one-time or included in Professional/Enterprise plan)

---

### US-022: Integrate with Authority Reporting Portals

**As a** Club Admin, **I want to** submit compliance reports directly to authority portals via CannaManage, **so that** I save time and avoid transcription errors in authority submissions.

**Priority:** Could Have  
**Acceptance Criteria:**
- [ ] AC1: System can detect available authority portals by Bundesland (state)
- [ ] AC2: Admin can initiate a report submission from within CannaManage
- [ ] AC3: Submission status is tracked (submitted, acknowledged, rejected) per report
- [ ] AC4: System retries failed submissions automatically (up to 3 times)
- [ ] AC5: This feature is only activated once at least one Bundesland has a machine-readable submission portal

**Notes:** Authority portals may not exist in v3 timeline — this is aspirational and depends on government digitalisation progress.

---

## Won't Have — MVP (Explicitly Excluded)

---

### US-023: Public Club Discovery — "Find Clubs Near You"

**As a** Public User, I want to find cannabis clubs near my location.

**Priority:** Won't Have (MVP)  
**Reason:** **Explicitly illegal under CanG §§6–7.** The advertising and sponsoring ban covers any feature that functions as advertising for Anbauvereinigungen to the general public. A public club directory constitutes advertising for clubs. This feature will never be built in any form on this platform.

**Acceptance Criteria:** *None — this feature is permanently excluded.*

**Notes:** This is not a commercial decision. It is a **legal constraint** hardcoded into the product architecture. No public-facing club listing, no map, no search, no "register your club publicly."

---

### US-024: Cannabis E-Commerce or Payment for Cannabis Products

**As a** Club Member, I want to purchase cannabis through the CannaManage platform.

**Priority:** Won't Have (MVP)  
**Reason:** **Illegal.** Cannabis sales are not the legal model for Anbauvereinigungen under CanG. Payment for cannabis products would violate German law and immediately trigger Stripe account termination. CannaManage processes membership fee payments only — not cannabis product payments, ever.

**Acceptance Criteria:** *None — permanently excluded.*

---

### US-025: Non-EU Data Storage

**As a** Club Admin, I want my club's data stored on the cheapest/fastest infrastructure, including non-EU servers.

**Priority:** Won't Have (MVP)  
**Reason:** **DSGVO violation.** Club member data includes personal data (name, date of birth, consumption records). Storing this outside the EU without a valid adequacy decision or standard contractual clauses violates Art. 44–49 DSGVO. All data remains on Hetzner DE datacenters.

**Acceptance Criteria:** *None — permanently excluded.*

---

## Acceptance Criteria Traceability Matrix

| Story | Role | Phase | Legal Basis | Key Risk |
|-------|------|-------|-------------|----------|
| US-001 | Club Admin | MVP | DSGVO (AVV) | Clubs operating without AVV |
| US-002 | Club Admin | MVP | §22–23 CanG | Under-21 age verification gaps |
| US-003 | Club Admin | MVP | §26 CanG | Distribution limit bypass |
| US-004 | Club Admin | MVP | §22–23 CanG | Incorrect limit category applied |
| US-005 | Club Admin | MVP | §26 CanG (batch traceability) | Inaccurate stock → wrong quota available |
| US-006 | Club Admin | MVP | — | Cross-tenant data leak |
| US-007 | Club Admin | MVP | §26 CanG | Incomplete report → authority rejection |
| US-008 | Club Admin | MVP | §26 CanG | Outdated member list at inspection |
| US-009 | Club Admin | MVP | CanG (contamination traceability) | Delayed recall notification |
| US-010 | Club Admin | MVP | §27 CanG | Missing officer → club licence risk |
| US-011 | Club Member | MVP | DSGVO | Unauthorised member account creation |
| US-012 | Club Member | MVP | DSGVO (Art. 15 access) | Cross-member data exposure |
| US-013 | Club Member | MVP | §§6–7 CanG (no advertising) | Over-disclosure of stock data |
| US-014 | Club Member | MVP | §22–23 CanG | Member unaware of impending limit breach |
| US-015 | Club Admin | v2 | — | Stripe cannabis-adjacent policy |
| US-016 | Club Admin | v2 | — | Waiting list ordering errors |
| US-017 | Club Member | v2 | DSGVO (email marketing consent) | Spam / opt-out compliance |
| US-018 | Club Admin | v2 | §26 CanG (provenance) | Batch-grow linkage gaps |
| US-019 | Club Member | v3 | — | Offline cache staleness |
| US-020 | Club Admin | v3 | — | Stock isolation complexity |
| US-021 | Club Admin | v3 | — | Template legal accuracy |
| US-022 | Club Admin | v3 | §26 CanG | Portal API non-existence |
| US-023 | *(none)* | Never | **Illegal §§6–7 CanG** | Platform shutdown risk |
| US-024 | *(none)* | Never | **Illegal** | Stripe termination + criminal liability |
| US-025 | *(none)* | Never | **DSGVO Art. 44–49** | Regulatory fine + club data breach |

---

*Source: [STRATEGY.md](../STRATEGY.md) | Related: [01-PROJECT-CHARTER.md](./01-PROJECT-CHARTER.md)*
