# 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 2–3 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 18–24 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 3–6 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 §§6–7 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 (€300–500) 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-001–010)
- [ ] Implement `MemberService` with age validation (TC-011–015)
- [ ] 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 (€300–500 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.
