1
CannaManage 10 Retrospective
Patrick Plate edited this page 2026-04-06 11:21:47 +02:00
This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

10 — Sprint 0 Planning Retrospective

Project: CannaManage — B2B SaaS for German Cannabis Social Clubs
Sprint: 0 — Planning & Documentation
Period: 2026-04-04 to 2026-04-06
Mode: Solo planning, AI-assisted documentation (Claude Sonnet 4.6 via Roo Orchestrator + Doc Writer modes)
Outcome: Complete — 10-document suite written, architecture locked


What Went Well

AI-assisted documentation at scale. The complete documentation suite (10 documents, ~25,000 words total) was created in a single focused session using the Roo Orchestrator mode to coordinate multi-document generation. This would have taken 23 days manually. The quality is high enough to serve as actual implementation guidance — not placeholder text.

Legal analysis confirmed viability early. The CanG compliance review (Phase 1) identified the key constraints (no public directory, no consumer-facing advertising, B2B-only) before any code was written. These became hard architectural constraints rather than late surprises. No "oh wait, we can't do that" moments during technical design.

Architecture decisions locked before code. The shared-schema multi-tenancy decision, immutable distribution records design, and ComplianceConstants pattern were all decided and documented before a single line of production code was written. This is the correct order. Rework from late architectural pivots is far more expensive than planning time.

Compliance constants centralized from day zero. Designing ComplianceConstants.java as the single source of truth for all CanG quota values (25g/day, 50g/month, etc.) prevents the most dangerous class of compliance bug: magic numbers scattered across the codebase that diverge when the law changes.

ComfyUI mockup images in minutes. Generating 5 realistic UI mockup images with FLUX.1-schnell took approximately 8 minutes of wall-clock time. This provides a visual reference for the UI that would otherwise require a designer or Figma skills. The images are good enough for stakeholder presentations and early user research.

Test plan written before code. TC-001 through TC-026 were defined against specifications, not against existing implementation. This forces clarity on what the code must do before writing it — the test cases are essentially executable requirements.


What Was Challenging ⚠️

ComfyUI manual startup friction. The ComfyUI image generation server does not auto-start with the system. This required manual service start and a retry cycle before image generation could proceed. The fix (systemd user service + auto-start lifespan check in mcp-image-gen) was implemented during this planning sprint but added unexpected overhead.

Solo developer timeline is ambitious. The 1824 month estimate for a production-ready SaaS while employed full-time at ADP Germany is tight. Sprint 1 goals are achievable; the risk accumulates in Sprints 36 when frontend work, billing integration, and PDF generation converge. The PrimeFaces JSF choice for MVP was deliberate to reduce this risk — existing Java frontend skills transfer directly.

Spring Boot 3 is not yet a "home" stack. ADP work uses Jakarta EE (JBoss, CDI, JAX-RS). Spring Boot 3 shares the JPA/Hibernate mental model but diverges on dependency injection, auto-configuration, and application packaging. The learning curve is real but bounded — the mss-failsafe and wellmann-shop projects in pi_mcps demonstrate that the transition is manageable.

Next.js/React remains a significant gap. The v2 frontend pivot to Next.js 15 + React 19 is the highest-skill-gap risk in the project. PrimeFaces buys time, but the clock starts ticking on React learning from Sprint 1. Deferring is correct; ignoring it is not.

No real user validation yet. The entire architecture and pricing model is based on market research and regulatory reading, not on conversations with actual club administrators. The product may be solving the right problem in the wrong way. This is the most important open risk.


Key Decisions Made 📋

Decision Rationale Alternatives rejected
Shared-schema multi-tenancy (single DB, tenant_id columns) Lowest ops overhead for MVP; one DB to backup/restore; simpler Flyway migrations Schema-per-tenant (complex provisioning), DB-per-tenant (expensive at scale)
Immutable distribution records (@Column(updatable = false)) Legal integrity — audit logs must be tamper-proof; corrections via RecallEvent, not UPDATE Mutable records (simpler but legally risky under CanG §26 record-keeping)
PrimeFaces JSF for MVP frontend Leverages existing Jakarta EE skills; fastest path to working product; no JS build tooling required React/Next.js (faster modern dev, but higher skill gap), Thymeleaf (less interactive)
No public club discovery — permanent architectural exclusion CanG §§67 prohibit advertising cannabis to the general public; club lookup tool would likely constitute advertising N/A — this is a legal constraint, not a design choice
ComplianceConstants.java single source of truth Prevents magic number scatter; single change point when law evolves Constants in each service (fragile), DB-configurable limits (dangerous — allows disabling compliance)
Hetzner VPS over AWS/GCP Cost (€5.88/month vs €20+); EU data residency (GDPR); simpler ops for solo developer AWS (expensive, complex), Fly.io (less EU clarity), Railway (vendor lock-in)

Risks Going Forward ⚠️

Risk Likelihood Impact Mitigation
New German government tightens CanG (e.g. lower quota limits) Medium High — requires rapid compliance updates ComplianceConstants.java centralizes all limits; update is a 1-file change + test re-run
Stripe flags account as cannabis-adjacent Medium Critical — billing becomes unusable Use category "Vereinsverwaltung" (club management) in Stripe onboarding; prepare Mollie as fallback
Solo dev burnout / timeline slip High Medium — delayed launch, not cancellation Strict MVP scope; PrimeFaces reduces frontend effort; no scope creep before first paying customer
Market timing risk — clubs adopt ad-hoc Excel/WhatsApp solutions Medium High — low willingness to pay for formal software User research with 3+ clubs in Sprint 1 is mandatory before writing production code
Legal risk: CanG compliance interpretation Low High — criminal liability for club officers Specialist cannabis law opinion (€300500) before launch; not optional
Under-21 age calculation edge cases Low Medium — compliance bug Birthday-based age calculation uses Period.between(), not year subtraction; tested in TC-013/014

Next Steps — Sprint 1 Goals

  • Initialize Spring Boot 3.x Maven multi-module project (cannamanage-parent, cannamanage-domain, cannamanage-service, cannamanage-api, cannamanage-web)
  • Implement AbstractTenantEntity base class with @MappedSuperclass
  • Write V1__initial_schema.sql Flyway migration covering all 8 entities
  • Implement ComplianceService with full quota logic and 100% test coverage (TC-001010)
  • Implement MemberService with age validation (TC-011015)
  • Set up JaCoCo with ComplianceService 100% coverage gate
  • Gitea repository created and CI pipeline (unit tests on feature/*) functional
  • Talk to 3 real club administrators — validate pain points, willingness to pay, and current workarounds
  • Get specialist legal opinion from a cannabis law attorney (€300500 budget)

Metrics

Metric Value
Planning duration 3 days (2026-04-04 to 2026-04-06)
Documents created 10 (01-PROJECT-CHARTER through 10-RETROSPECTIVE)
Estimated total words ~25,000
Test cases defined 26
API endpoints specified 30+
JPA entities designed 8
UI screens wireframed 6
UI mockup images generated 5
Lines of production code written 0
Architecture decisions logged 6 major
Open risks identified 6

The ratio of planning output to production code written is intentional. Phase 0 exists to eliminate avoidable rework — the most expensive kind.