docs: update wiki for Sprint 4 completion + add retrospective
+66
-24
@@ -5,9 +5,74 @@
|
||||
|
||||
---
|
||||
|
||||
## Sprint 4 Retrospective — Frontend MVP (Admin Dashboard + Member Portal)
|
||||
|
||||
**Sprint:** 4 — Frontend MVP with Shadboard, Next.js 15, React 19, shadcn/ui, Tailwind 4
|
||||
**Period:** 2026-06-12 (single-day intensive sprint, AI-assisted)
|
||||
**Mode:** Solo development, AI-assisted (Claude Opus via Roo Orchestrator)
|
||||
**Outcome:** ✅ Complete — 143 files, ~23,568 LoC, 14 routes, 6 Playwright E2E tests passing
|
||||
**Commit:** `fe6e96d`
|
||||
|
||||
### What Went Well ✅
|
||||
|
||||
**Shadboard starter kit saved weeks of boilerplate.** Using the MIT-licensed Shadboard template (Next.js 15 + shadcn/ui + Tailwind 4) as a foundation meant sidebar layout, theme system, command palette, and responsive behavior came pre-built. Estimated 2-3 weeks of work avoided. The structure was clean enough to extend without fighting it.
|
||||
|
||||
**Persona review caught compliance gaps early.** Before coding the distribution form, reviewing the user stories against CanG §19 requirements identified the need for under-21 reduced limits (30g/month), suspension/expulsion blocking, and immutable audit trail indicators in the UI — all of which were built into the form from the start rather than retrofitted.
|
||||
|
||||
**Playwright E2E caught the NextAuth deadlock immediately.** The very first E2E run revealed that NextAuth v5's middleware was blocking indefinitely when the backend wasn't reachable. Without E2E tests, this would have been a production-discovery bug. The fix (AbortController with 3-second timeout in the auth fetch) took 10 minutes once diagnosed.
|
||||
|
||||
**Dark + light mode from Day 1 was low-effort, high-value.** Since Shadboard already had next-themes integrated and Tailwind 4's `dark:` variant is zero-config, supporting both themes required only choosing color variables — no structural changes. The radial quota visualization in the portal looks excellent in both modes.
|
||||
|
||||
**i18n architecture (next-intl) scales cleanly.** All 200+ UI strings live in `messages/de.json` and `messages/en.json`. No hardcoded text in components. Adding a language is just a JSON file. The translation structure mirrors the route structure (dashboard.*, members.*, portal.*) making keys predictable.
|
||||
|
||||
**Separate route groups for admin vs. portal.** Using Next.js route groups `(dashboard-layout)` and `(portal)` with independent layouts means the admin sidebar never leaks into the member portal (which uses a top nav). Clean separation without code duplication.
|
||||
|
||||
### What Was Challenging ⚠️
|
||||
|
||||
**NextAuth v5 middleware deadlocked without backend.** The default NextAuth behavior waits indefinitely for the backend auth endpoint. During frontend-only development (backend not running), this caused all protected routes to hang. Fix: AbortController timeout wrapper around the fetch in the `authorize` callback + graceful error handling in middleware.
|
||||
|
||||
**Tailwind 4 breaking changes from v3 documentation.** Most online examples and Stack Overflow answers reference Tailwind v3 syntax. Tailwind 4 changes include: new CSS-first configuration (`@theme` in CSS instead of `tailwind.config.js`), `@apply` deprecated in favor of direct utility classes, and some color utilities renamed. Required reading the v4 migration guide carefully.
|
||||
|
||||
**Mock data architecture decisions.** Without the real backend running, all pages use mock data from `src/data/mock/`. The interface contracts needed to be designed carefully so the migration to real API calls (Sprint 5) is a drop-in replacement. TypeScript interfaces in `src/types/api.ts` define the shared contract.
|
||||
|
||||
**Multi-step distribution form state management.** The 4-step distribution form (member selection → quota check → batch+amount → confirmation) required careful state threading across steps without a state management library. Solved with React `useState` + prop drilling since the form is a single page component. This is fine for 4 steps but wouldn't scale to 10+.
|
||||
|
||||
### Key Decisions Made 📋
|
||||
|
||||
| Decision | Rationale | Alternatives Rejected |
|
||||
|----------|-----------|----------------------|
|
||||
| Shadboard (MIT) as starter kit | Pre-built layout, theme, sidebar, command palette. Saves 2-3 weeks. MIT license = no restrictions. | Custom scaffold (slow), Vercel templates (too generic), paid templates (license restrictions) |
|
||||
| Node 22 LTS | Long-term support, stable for production. Required by some Next.js 15 features. | Node 20 (older LTS), Node 24 (too new, not LTS yet) |
|
||||
| i18n from Day 1 (next-intl) | Cheaper to add from start than retrofit. German clubs may have English-speaking members. EU expansion possible. | Hardcoded German (faster short-term, expensive later), react-i18next (heavier, server components don't play well) |
|
||||
| Dark mode default + light toggle | Cannabis club aesthetic suits dark mode. Outdoor mobile use needs light mode. Both supported via next-themes. | Dark-only (excludes bright-environment use), Light-only (boring, doesn't match brand) |
|
||||
| Separate portal route group | Members get a simplified top-nav layout. Admins get a full sidebar. No layout collision. | Single layout with conditional rendering (messy), separate Next.js app (overkill) |
|
||||
| pnpm over npm/yarn | Faster installs, strict dependency resolution, disk-efficient via hard links. Shadboard already configured for it. | npm (slower, phantom deps), yarn (Berry complexity) |
|
||||
| Mock data in typed files | TypeScript interfaces enforce API contract. Easy to swap with real fetch calls. No backend dependency for UI work. | MSW (Mock Service Worker — adds complexity), json-server (external process) |
|
||||
|
||||
### Risks Going Forward ⚠️
|
||||
|
||||
| Risk | Likelihood | Impact | Mitigation |
|
||||
|------|-----------|--------|------------|
|
||||
| Mock-to-real API migration breaks assumptions | Medium | Medium — pages may need refactoring | TypeScript interfaces as contract; API response types match backend DTOs |
|
||||
| NextAuth session expiry UX | Low | Low — users see login page | Implement token refresh in `jwt` callback; show toast before expiry |
|
||||
| Tailwind 4 ecosystem immaturity | Low | Low — workarounds exist | Pin Tailwind version; avoid bleeding-edge plugins |
|
||||
| No loading/error states in UI | Medium | Medium — poor UX on slow connections | Sprint 5: add React Suspense boundaries + error.tsx per route |
|
||||
| Frontend tests don't cover real auth flow | High | Medium — false confidence | Sprint 5: E2E tests with real backend running in Docker Compose |
|
||||
|
||||
### Sprint 5 Goals (Planned)
|
||||
|
||||
- [ ] Wire frontend to real backend API (replace mock data with fetch/SWR calls)
|
||||
- [ ] Staff management UI (invite, permissions editor)
|
||||
- [ ] DSGVO consent management flow
|
||||
- [ ] WebSocket notifications (real-time quota updates)
|
||||
- [ ] Full E2E test suite with backend running in Docker
|
||||
- [ ] Loading states, error boundaries, toast notifications
|
||||
|
||||
---
|
||||
|
||||
## Sprint 3 Retrospective — Staff, Portal & Compliance Reports
|
||||
|
||||
**Sprint:** 3 — Staff Permissions, Token Revocation, Member Portal, Reports, Prevention Officer, Integration Tests
|
||||
**Sprint:** 3 — Staff Permissions, Token Revocation, Member Portal, Reports, Prevention Officer
|
||||
**Period:** 2026-05-15 to 2026-06-12
|
||||
**Mode:** Solo development, AI-assisted (Claude Opus via Roo Orchestrator)
|
||||
**Outcome:** ✅ Complete — 7 phases delivered, ~80 files, ~8,500 LoC, 67+ tests passing
|
||||
@@ -56,15 +121,6 @@
|
||||
| Token revocation cache grows unbounded if no cleanup | Low | Low — scheduler runs daily | `TokenCleanupScheduler` + Caffeine TTL eviction |
|
||||
| 45-second integration test suite slows CI | Medium | Low — annoying but not blocking | Parallel test execution (`maven-surefire-plugin` forks); test categorization |
|
||||
|
||||
### Sprint 4 Goals (Planned)
|
||||
|
||||
- [ ] React/Vite admin dashboard (SPA)
|
||||
- [ ] Admin login page, club dashboard widget
|
||||
- [ ] Member list view with search/filter
|
||||
- [ ] Distribution recording form
|
||||
- [ ] API integration with JWT auth from frontend
|
||||
- [ ] Deployment: Nginx serves SPA static files + proxies API
|
||||
|
||||
---
|
||||
|
||||
## Sprint 0 Planning Retrospective
|
||||
@@ -132,20 +188,6 @@
|
||||
|
||||
---
|
||||
|
||||
## 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 |
|
||||
|
||||
+66
-24
@@ -5,9 +5,74 @@
|
||||
|
||||
---
|
||||
|
||||
## Sprint 4 Retrospective — Frontend MVP (Admin Dashboard + Member Portal)
|
||||
|
||||
**Sprint:** 4 — Frontend MVP with Shadboard, Next.js 15, React 19, shadcn/ui, Tailwind 4
|
||||
**Period:** 2026-06-12 (single-day intensive sprint, AI-assisted)
|
||||
**Mode:** Solo development, AI-assisted (Claude Opus via Roo Orchestrator)
|
||||
**Outcome:** ✅ Complete — 143 files, ~23,568 LoC, 14 routes, 6 Playwright E2E tests passing
|
||||
**Commit:** `fe6e96d`
|
||||
|
||||
### What Went Well ✅
|
||||
|
||||
**Shadboard starter kit saved weeks of boilerplate.** Using the MIT-licensed Shadboard template (Next.js 15 + shadcn/ui + Tailwind 4) as a foundation meant sidebar layout, theme system, command palette, and responsive behavior came pre-built. Estimated 2-3 weeks of work avoided. The structure was clean enough to extend without fighting it.
|
||||
|
||||
**Persona review caught compliance gaps early.** Before coding the distribution form, reviewing the user stories against CanG §19 requirements identified the need for under-21 reduced limits (30g/month), suspension/expulsion blocking, and immutable audit trail indicators in the UI — all of which were built into the form from the start rather than retrofitted.
|
||||
|
||||
**Playwright E2E caught the NextAuth deadlock immediately.** The very first E2E run revealed that NextAuth v5's middleware was blocking indefinitely when the backend wasn't reachable. Without E2E tests, this would have been a production-discovery bug. The fix (AbortController with 3-second timeout in the auth fetch) took 10 minutes once diagnosed.
|
||||
|
||||
**Dark + light mode from Day 1 was low-effort, high-value.** Since Shadboard already had next-themes integrated and Tailwind 4's `dark:` variant is zero-config, supporting both themes required only choosing color variables — no structural changes. The radial quota visualization in the portal looks excellent in both modes.
|
||||
|
||||
**i18n architecture (next-intl) scales cleanly.** All 200+ UI strings live in `messages/de.json` and `messages/en.json`. No hardcoded text in components. Adding a language is just a JSON file. The translation structure mirrors the route structure (dashboard.*, members.*, portal.*) making keys predictable.
|
||||
|
||||
**Separate route groups for admin vs. portal.** Using Next.js route groups `(dashboard-layout)` and `(portal)` with independent layouts means the admin sidebar never leaks into the member portal (which uses a top nav). Clean separation without code duplication.
|
||||
|
||||
### What Was Challenging ⚠️
|
||||
|
||||
**NextAuth v5 middleware deadlocked without backend.** The default NextAuth behavior waits indefinitely for the backend auth endpoint. During frontend-only development (backend not running), this caused all protected routes to hang. Fix: AbortController timeout wrapper around the fetch in the `authorize` callback + graceful error handling in middleware.
|
||||
|
||||
**Tailwind 4 breaking changes from v3 documentation.** Most online examples and Stack Overflow answers reference Tailwind v3 syntax. Tailwind 4 changes include: new CSS-first configuration (`@theme` in CSS instead of `tailwind.config.js`), `@apply` deprecated in favor of direct utility classes, and some color utilities renamed. Required reading the v4 migration guide carefully.
|
||||
|
||||
**Mock data architecture decisions.** Without the real backend running, all pages use mock data from `src/data/mock/`. The interface contracts needed to be designed carefully so the migration to real API calls (Sprint 5) is a drop-in replacement. TypeScript interfaces in `src/types/api.ts` define the shared contract.
|
||||
|
||||
**Multi-step distribution form state management.** The 4-step distribution form (member selection → quota check → batch+amount → confirmation) required careful state threading across steps without a state management library. Solved with React `useState` + prop drilling since the form is a single page component. This is fine for 4 steps but wouldn't scale to 10+.
|
||||
|
||||
### Key Decisions Made 📋
|
||||
|
||||
| Decision | Rationale | Alternatives Rejected |
|
||||
|----------|-----------|----------------------|
|
||||
| Shadboard (MIT) as starter kit | Pre-built layout, theme, sidebar, command palette. Saves 2-3 weeks. MIT license = no restrictions. | Custom scaffold (slow), Vercel templates (too generic), paid templates (license restrictions) |
|
||||
| Node 22 LTS | Long-term support, stable for production. Required by some Next.js 15 features. | Node 20 (older LTS), Node 24 (too new, not LTS yet) |
|
||||
| i18n from Day 1 (next-intl) | Cheaper to add from start than retrofit. German clubs may have English-speaking members. EU expansion possible. | Hardcoded German (faster short-term, expensive later), react-i18next (heavier, server components don't play well) |
|
||||
| Dark mode default + light toggle | Cannabis club aesthetic suits dark mode. Outdoor mobile use needs light mode. Both supported via next-themes. | Dark-only (excludes bright-environment use), Light-only (boring, doesn't match brand) |
|
||||
| Separate portal route group | Members get a simplified top-nav layout. Admins get a full sidebar. No layout collision. | Single layout with conditional rendering (messy), separate Next.js app (overkill) |
|
||||
| pnpm over npm/yarn | Faster installs, strict dependency resolution, disk-efficient via hard links. Shadboard already configured for it. | npm (slower, phantom deps), yarn (Berry complexity) |
|
||||
| Mock data in typed files | TypeScript interfaces enforce API contract. Easy to swap with real fetch calls. No backend dependency for UI work. | MSW (Mock Service Worker — adds complexity), json-server (external process) |
|
||||
|
||||
### Risks Going Forward ⚠️
|
||||
|
||||
| Risk | Likelihood | Impact | Mitigation |
|
||||
|------|-----------|--------|------------|
|
||||
| Mock-to-real API migration breaks assumptions | Medium | Medium — pages may need refactoring | TypeScript interfaces as contract; API response types match backend DTOs |
|
||||
| NextAuth session expiry UX | Low | Low — users see login page | Implement token refresh in `jwt` callback; show toast before expiry |
|
||||
| Tailwind 4 ecosystem immaturity | Low | Low — workarounds exist | Pin Tailwind version; avoid bleeding-edge plugins |
|
||||
| No loading/error states in UI | Medium | Medium — poor UX on slow connections | Sprint 5: add React Suspense boundaries + error.tsx per route |
|
||||
| Frontend tests don't cover real auth flow | High | Medium — false confidence | Sprint 5: E2E tests with real backend running in Docker Compose |
|
||||
|
||||
### Sprint 5 Goals (Planned)
|
||||
|
||||
- [ ] Wire frontend to real backend API (replace mock data with fetch/SWR calls)
|
||||
- [ ] Staff management UI (invite, permissions editor)
|
||||
- [ ] DSGVO consent management flow
|
||||
- [ ] WebSocket notifications (real-time quota updates)
|
||||
- [ ] Full E2E test suite with backend running in Docker
|
||||
- [ ] Loading states, error boundaries, toast notifications
|
||||
|
||||
---
|
||||
|
||||
## Sprint 3 Retrospective — Staff, Portal & Compliance Reports
|
||||
|
||||
**Sprint:** 3 — Staff Permissions, Token Revocation, Member Portal, Reports, Prevention Officer, Integration Tests
|
||||
**Sprint:** 3 — Staff Permissions, Token Revocation, Member Portal, Reports, Prevention Officer
|
||||
**Period:** 2026-05-15 to 2026-06-12
|
||||
**Mode:** Solo development, AI-assisted (Claude Opus via Roo Orchestrator)
|
||||
**Outcome:** ✅ Complete — 7 phases delivered, ~80 files, ~8,500 LoC, 67+ tests passing
|
||||
@@ -56,15 +121,6 @@
|
||||
| Token revocation cache grows unbounded if no cleanup | Low | Low — scheduler runs daily | `TokenCleanupScheduler` + Caffeine TTL eviction |
|
||||
| 45-second integration test suite slows CI | Medium | Low — annoying but not blocking | Parallel test execution (`maven-surefire-plugin` forks); test categorization |
|
||||
|
||||
### Sprint 4 Goals (Planned)
|
||||
|
||||
- [ ] React/Vite admin dashboard (SPA)
|
||||
- [ ] Admin login page, club dashboard widget
|
||||
- [ ] Member list view with search/filter
|
||||
- [ ] Distribution recording form
|
||||
- [ ] API integration with JWT auth from frontend
|
||||
- [ ] Deployment: Nginx serves SPA static files + proxies API
|
||||
|
||||
---
|
||||
|
||||
## Sprint 0 Planning Retrospective
|
||||
@@ -132,20 +188,6 @@
|
||||
|
||||
---
|
||||
|
||||
## 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 |
|
||||
|
||||
+92
-21
@@ -1,31 +1,102 @@
|
||||
# 🌿 CannaManage
|
||||
|
||||
**B2B SaaS for German Cannabis Social Clubs (Anbauvereinigungen)**
|
||||
**Multi-tenant compliance platform for German Cannabis Social Clubs (Anbauvereinigungen)**
|
||||
|
||||
> Status: Sprint 3 ✅ Complete | Stack: Java 21 + Spring Boot 4.0.6 + React/Vite (Sprint 4) | Legal: ✅ CanG-Compliant
|
||||
> **Status:** Sprint 4 ✅ Complete | **Stack:** Java 21 + Spring Boot 4.0.6 + Next.js 15 | **Tests:** 67+ backend + 6 E2E frontend | **Legal:** CanG §19 compliant
|
||||
|
||||
## Documentation Index
|
||||
---
|
||||
|
||||
| Document | Description |
|
||||
|----------|-------------|
|
||||
| [Project Charter](CannaManage-01-Charter) | Vision, scope, risk register, timeline Gantt chart |
|
||||
| [User Stories](CannaManage-02-UserStories) | 25+ stories with MoSCoW priorities + acceptance criteria |
|
||||
| [Architecture](CannaManage-03-Architecture) | System diagram, 11-entity ERD, multi-tenancy, dual SecurityFilterChain |
|
||||
| [Flow Charts](CannaManage-04-Flowcharts) | 5 business logic flows (distribution, recall, compliance) |
|
||||
| [API Spec](CannaManage-05-API) | REST API: 9 controllers, 25+ endpoints, JWT + session auth |
|
||||
| [Wireframes & Mockups](CannaManage-06-Wireframes) | 6 screen wireframes with AI-generated UI mockups |
|
||||
| [Coding Standards](CannaManage-07-CodingStandards) | Java 21 standards, compliance code rules, Git strategy |
|
||||
| [Test Plan](CannaManage-08-TestPlan) | 67+ test cases, Testcontainers integration, JaCoCo 100% gate on ComplianceService |
|
||||
| [Deployment Guide](CannaManage-09-Deployment) | Hetzner VPS, Docker Compose, SMTP config, Gitea CI/CD |
|
||||
| [Retrospective](CannaManage-10-Retrospective) | Sprint 0–3 retros: decisions, challenges, next steps |
|
||||
## 🚀 Current State
|
||||
|
||||
## Quick Stats
|
||||
| Milestone | What's Done | Tests |
|
||||
|-----------|-------------|-------|
|
||||
| **Sprint 1** — Foundation | 8 JPA entities, ComplianceService (CanG §19 enforcement), Flyway V1 | 25 unit tests |
|
||||
| **Sprint 2** — REST API | 5 controllers, JWT auth, Spring Security 7, OpenAPI, TenantFilterAspect | 12 integration tests |
|
||||
| **Sprint 3** — Staff, Portal & Compliance | Staff permissions (JSONB), token revocation, invite flow, PDF/CSV reports, member portal (session auth), prevention officer, 30+ integration tests | 30+ integration tests |
|
||||
| **Sprint 4** — Frontend MVP | Admin Dashboard + Member Portal (Shadboard, Next.js 15, React 19, 143 files, 23K lines). Login, KPI dashboard, member management (TanStack Table), multi-step distribution form with quota check, batch/stock management with charts, compliance reports. Member portal with radial quota visualization, distribution history, profile. i18n (de/en), dark+light mode, Playwright E2E, Docker multi-stage. | 6 E2E tests |
|
||||
| **Sprint 5** — Staff UI & API Wiring | _Planned:_ Wire frontend to real backend API, staff management UI, DSGVO consent, WebSocket notifications | — |
|
||||
|
||||
## 📋 Documentation
|
||||
|
||||
| # | Document | Description |
|
||||
|---|----------|-------------|
|
||||
| 01 | [Project Charter](CannaManage-01-Charter) | Vision, scope, legal framework, risk register, Gantt timeline |
|
||||
| 02 | [User Stories](CannaManage-02-UserStories) | 25+ stories with MoSCoW priorities + acceptance criteria |
|
||||
| 03 | [Architecture](CannaManage-03-Architecture) | System diagram, ERD, multi-tenancy design, dual SecurityFilterChain |
|
||||
| 04 | [Flow Charts](CannaManage-04-Flowcharts) | Business logic flows: distribution, recall, compliance check |
|
||||
| 05 | [API Spec](CannaManage-05-API) | REST API: 9 controllers, JWT + session auth, role-based access |
|
||||
| 06 | [Wireframes & Mockups](CannaManage-06-Wireframes) | UI mockups for admin dashboard, distribution, quota views |
|
||||
| 07 | [Coding Standards](CannaManage-07-CodingStandards) | Java 21 standards, compliance patterns, Git strategy |
|
||||
| 08 | [Test Plan](CannaManage-08-TestPlan) | Test strategy, 67+ automated tests, Testcontainers integration |
|
||||
| 09 | [Deployment Guide](CannaManage-09-Deployment) | Hetzner VPS, Docker Compose, PostgreSQL, SMTP, Gitea CI/CD |
|
||||
| 10 | [Retrospective](CannaManage-10-Retrospective) | Sprint retrospectives and decisions log |
|
||||
|
||||
## 🏗️ Tech Stack
|
||||
|
||||
| Layer | Technology |
|
||||
|-------|-----------|
|
||||
| Language | Java 21 (Temurin) |
|
||||
| Framework | Spring Boot 4.0.6 |
|
||||
| Security | Spring Security 7.0 + JWT (stateless) + Session (portal) · JJWT 0.12.6 |
|
||||
| ORM | Hibernate 7 / JPA |
|
||||
| Database | PostgreSQL 16 (prod) · Testcontainers (integration tests) |
|
||||
| Migrations | Flyway 10 (V1–V5) |
|
||||
| Multi-tenancy | Hibernate `@Filter` + `TenantFilterAspect` (AOP) |
|
||||
| PDF Generation | OpenPDF (iText fork — LGPL, no license cost) |
|
||||
| Caching | Caffeine (in-memory token revocation cache) |
|
||||
| Email | Spring Mail (SMTP — staff invite flow) |
|
||||
| Testing (Backend) | JUnit 5 + Mockito + Testcontainers (PostgreSQL 16) |
|
||||
| Frontend | Next.js 15 + React 19 + TypeScript |
|
||||
| UI Components | shadcn/ui (Radix primitives) + Tailwind CSS 4 |
|
||||
| Charts | Recharts |
|
||||
| Tables | TanStack Table v8 |
|
||||
| Frontend Auth | NextAuth v5 (Auth.js) |
|
||||
| Frontend i18n | next-intl |
|
||||
| Frontend Testing | Playwright (E2E) |
|
||||
| API Docs | SpringDoc OpenAPI 2.8.6 · Swagger UI |
|
||||
| Build | Maven multi-module (backend) · pnpm (frontend) |
|
||||
| Hosting | Hetzner VPS (German DC) · Docker Compose |
|
||||
|
||||
## 📦 Module Layout
|
||||
|
||||
```
|
||||
cannamanage/
|
||||
├── cannamanage-domain/ → 11 JPA entities, enums, TenantContext
|
||||
├── cannamanage-service/ → Business logic, repositories, ComplianceService, ReportService, TokenRevocationService
|
||||
├── cannamanage-api/ → Spring Boot app, 9 controllers, dual security config, DTOs
|
||||
├── cannamanage-frontend/ → Next.js 15 app, admin dashboard + member portal, 143 files
|
||||
└── docs/ → Sprint plans, security reviews, design docs
|
||||
```
|
||||
|
||||
## 🔒 Security Model
|
||||
|
||||
- **Dual SecurityFilterChain** — JWT chain for admin/staff API + session-based chain for member portal
|
||||
- **Roles:** ADMIN (full access) · STAFF (configurable permissions) · MEMBER (self-service portal) · PREVENTION_OFFICER (under-21 reports)
|
||||
- **Staff permissions:** 8 granular permissions stored as JSONB, enforced via `@StaffPermissionChecker`
|
||||
- **Token revocation:** Caffeine in-memory cache with DB backing (`revoked_tokens` table), automatic cleanup scheduler
|
||||
- **Multi-tenant isolation:** Hibernate @Filter activated per-request via AOP
|
||||
- **Token rotation:** refresh tokens SHA-256 hashed, rotated on each use
|
||||
- **Invite flow:** Admin creates invite → email sent via SMTP → staff sets password via 72-hour token
|
||||
- **Frontend auth:** NextAuth v5 with CredentialsProvider → backend JWT (server-side only, no token exposure to client)
|
||||
|
||||
## 📊 Quick Facts
|
||||
|
||||
| Metric | Value |
|
||||
|--------|-------|
|
||||
| Entities | 11 JPA entities |
|
||||
| Target Market | 500–3,000 German Anbauvereinigungen |
|
||||
| Legal Basis | Konsumcannabisgesetz (CanG) §§2, 15–26 |
|
||||
| Revenue Model | B2B SaaS subscription |
|
||||
| Entities | 11 (Member, Distribution, MonthlyQuota, Batch, Strain, StockMovement, Club, User, StaffAccount, RevokedToken, InviteToken) |
|
||||
| API Endpoints | 25+ across 9 controllers |
|
||||
| Automated Tests | 67+ (unit + Testcontainers integration) |
|
||||
| Security Roles | 4 (ADMIN, STAFF, MEMBER, PREVENTION_OFFICER) |
|
||||
| Flyway Migrations | V1–V5 |
|
||||
| Security Scan | SAST + SCA clean |
|
||||
| Total Files | 200+ (backend + frontend) |
|
||||
| Test Coverage | 67+ backend tests (unit + integration) + 6 Playwright E2E |
|
||||
| Flyway Migrations | V1–V5 (initial schema → staff/portal → club settings → invite tokens) |
|
||||
| Frontend Pages | 14 routes (10 admin + 4 portal) |
|
||||
| Security Scan | SAST + SCA clean (Snyk Code, SonarQube) |
|
||||
|
||||
## 🔗 Links
|
||||
|
||||
- **Repository:** [git.plate-software.de/pplate/cannamanage](https://git.plate-software.de/pplate/cannamanage)
|
||||
- **Swagger UI:** `http://localhost:8080/swagger-ui.html` (local dev)
|
||||
- **Frontend Dev:** `http://localhost:3000` (Next.js dev server)
|
||||
- **Branch:** `main` (current release)
|
||||
|
||||
+22
-9
@@ -2,7 +2,7 @@
|
||||
|
||||
**Multi-tenant compliance platform for German Cannabis Social Clubs (Anbauvereinigungen)**
|
||||
|
||||
> **Status:** Sprint 3 ✅ Complete | **Stack:** Java 21 + Spring Boot 4.0.6 | **Tests:** 67+ green | **Legal:** CanG §19 compliant
|
||||
> **Status:** Sprint 4 ✅ Complete | **Stack:** Java 21 + Spring Boot 4.0.6 + Next.js 15 | **Tests:** 67+ backend + 6 E2E frontend | **Legal:** CanG §19 compliant
|
||||
|
||||
---
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
| **Sprint 1** — Foundation | 8 JPA entities, ComplianceService (CanG §19 enforcement), Flyway V1 | 25 unit tests |
|
||||
| **Sprint 2** — REST API | 5 controllers, JWT auth, Spring Security 7, OpenAPI, TenantFilterAspect | 12 integration tests |
|
||||
| **Sprint 3** — Staff, Portal & Compliance | Staff permissions (JSONB), token revocation, invite flow, PDF/CSV reports, member portal (session auth), prevention officer, 30+ integration tests | 30+ integration tests |
|
||||
| **Sprint 4** — Frontend MVP | _Planned:_ React/Vite admin dashboard, real-time notifications | — |
|
||||
| **Sprint 4** — Frontend MVP | Admin Dashboard + Member Portal (Shadboard, Next.js 15, React 19, 143 files, 23K lines). Login, KPI dashboard, member management (TanStack Table), multi-step distribution form with quota check, batch/stock management with charts, compliance reports. Member portal with radial quota visualization, distribution history, profile. i18n (de/en), dark+light mode, Playwright E2E, Docker multi-stage. | 6 E2E tests |
|
||||
| **Sprint 5** — Staff UI & API Wiring | _Planned:_ Wire frontend to real backend API, staff management UI, DSGVO consent, WebSocket notifications | — |
|
||||
|
||||
## 📋 Documentation
|
||||
|
||||
@@ -44,19 +45,27 @@
|
||||
| PDF Generation | OpenPDF (iText fork — LGPL, no license cost) |
|
||||
| Caching | Caffeine (in-memory token revocation cache) |
|
||||
| Email | Spring Mail (SMTP — staff invite flow) |
|
||||
| Testing | JUnit 5 + Mockito + Testcontainers (PostgreSQL 16) |
|
||||
| Testing (Backend) | JUnit 5 + Mockito + Testcontainers (PostgreSQL 16) |
|
||||
| Frontend | Next.js 15 + React 19 + TypeScript |
|
||||
| UI Components | shadcn/ui (Radix primitives) + Tailwind CSS 4 |
|
||||
| Charts | Recharts |
|
||||
| Tables | TanStack Table v8 |
|
||||
| Frontend Auth | NextAuth v5 (Auth.js) |
|
||||
| Frontend i18n | next-intl |
|
||||
| Frontend Testing | Playwright (E2E) |
|
||||
| API Docs | SpringDoc OpenAPI 2.8.6 · Swagger UI |
|
||||
| Build | Maven multi-module |
|
||||
| Build | Maven multi-module (backend) · pnpm (frontend) |
|
||||
| Hosting | Hetzner VPS (German DC) · Docker Compose |
|
||||
|
||||
## 📦 Module Layout
|
||||
|
||||
```
|
||||
cannamanage/
|
||||
├── cannamanage-domain/ → 11 JPA entities, enums, TenantContext
|
||||
├── cannamanage-service/ → Business logic, repositories, ComplianceService, ReportService, TokenRevocationService
|
||||
├── cannamanage-api/ → Spring Boot app, 9 controllers, dual security config, DTOs
|
||||
└── docs/ → Sprint plans, security reviews, design docs
|
||||
├── cannamanage-domain/ → 11 JPA entities, enums, TenantContext
|
||||
├── cannamanage-service/ → Business logic, repositories, ComplianceService, ReportService, TokenRevocationService
|
||||
├── cannamanage-api/ → Spring Boot app, 9 controllers, dual security config, DTOs
|
||||
├── cannamanage-frontend/ → Next.js 15 app, admin dashboard + member portal, 143 files
|
||||
└── docs/ → Sprint plans, security reviews, design docs
|
||||
```
|
||||
|
||||
## 🔒 Security Model
|
||||
@@ -68,6 +77,7 @@ cannamanage/
|
||||
- **Multi-tenant isolation:** Hibernate @Filter activated per-request via AOP
|
||||
- **Token rotation:** refresh tokens SHA-256 hashed, rotated on each use
|
||||
- **Invite flow:** Admin creates invite → email sent via SMTP → staff sets password via 72-hour token
|
||||
- **Frontend auth:** NextAuth v5 with CredentialsProvider → backend JWT (server-side only, no token exposure to client)
|
||||
|
||||
## 📊 Quick Facts
|
||||
|
||||
@@ -78,12 +88,15 @@ cannamanage/
|
||||
| Revenue Model | B2B SaaS subscription |
|
||||
| Entities | 11 (Member, Distribution, MonthlyQuota, Batch, Strain, StockMovement, Club, User, StaffAccount, RevokedToken, InviteToken) |
|
||||
| API Endpoints | 25+ across 9 controllers |
|
||||
| Test Coverage | 67+ automated tests (unit + integration via Testcontainers) |
|
||||
| Total Files | 200+ (backend + frontend) |
|
||||
| Test Coverage | 67+ backend tests (unit + integration) + 6 Playwright E2E |
|
||||
| Flyway Migrations | V1–V5 (initial schema → staff/portal → club settings → invite tokens) |
|
||||
| Frontend Pages | 14 routes (10 admin + 4 portal) |
|
||||
| Security Scan | SAST + SCA clean (Snyk Code, SonarQube) |
|
||||
|
||||
## 🔗 Links
|
||||
|
||||
- **Repository:** [git.plate-software.de/pplate/cannamanage](https://git.plate-software.de/pplate/cannamanage)
|
||||
- **Swagger UI:** `http://localhost:8080/swagger-ui.html` (local dev)
|
||||
- **Frontend Dev:** `http://localhost:3000` (Next.js dev server)
|
||||
- **Branch:** `main` (current release)
|
||||
|
||||
+2
-1
@@ -29,4 +29,5 @@
|
||||
| 1 — Domain | ✅ |
|
||||
| 2 — API | ✅ |
|
||||
| 3 — Staff & Portal | ✅ |
|
||||
| 4 — Frontend | 📋 |
|
||||
| 4 — Frontend MVP | ✅ |
|
||||
| 5 — Staff UI & Wiring | 📋 |
|
||||
|
||||
Reference in New Issue
Block a user