diff --git a/docs/ROO-HANDOVER.md b/docs/ROO-HANDOVER.md index d145672..a29410c 100644 --- a/docs/ROO-HANDOVER.md +++ b/docs/ROO-HANDOVER.md @@ -6,6 +6,56 @@ --- +## ✅ "OOPS" CRASH FIXED — 2026-06-13 (update 3) — verified in a real browser + +The previous "RESOLVED" was wrong: login was verified with **curl only**, which cannot +execute client-side JS. In a real browser **every page (including `/login`) crashed on +hydration** with the "Oops! Something went wrong" boundary. Diagnosed by installing a +**Playwright browser probe** (`scripts/debug/dashboard-probe.mjs`) that logs in and +captures real console/network errors + a screenshot. Three root causes, all fixed in +commit **`4be9c4c`** (frontend rebuilt + redeployed): + +8. **App-wide intl hydration crash ("Oops" on every page).** Root `app/layout.tsx` + renders global client components (`PwaInstallPrompt` → `useTranslations`, `Toaster`, + `Sonner`) as siblings of `{children}` inside ``, but only each route-group + layout wrapped *its own* children in `NextIntlClientProvider`. Those global components + mounted with **no intl context** → "No intl context found" → hydration crash. + **Fix:** root layout is now `async` and wraps the body in `NextIntlClientProvider` + via `getMessages()`. Nested route-group providers remain valid (next-intl nests). + +9. **PWA assets intercepted by auth middleware** (manifest.json syntax error + stale cache). + The middleware `matcher` did not exclude `/manifest.json` or `/sw.js`, so unauthenticated + browsers got **307 → /login (HTML)** for both → browser parsed HTML as JSON + (`manifest.json:1 Syntax error`) and an HTML/old service worker kept serving **stale + bundles** ("website hasn't changed after redeploy"). **Fix:** matcher now excludes + `manifest.json`, `sw.js`, `icons`, `offline`. Verified: `manifest.json` → 200 + `application/json`, `sw.js` → 200 `application/javascript`. + +10. **Service-worker stale cache.** Bumped `CACHE_NAME` `v1`→`v2` in `public/sw.js` so the + `activate` handler purges old cached bundles from clients that loaded the broken build. + +**Browser verification (Playwright):** login `admin@test.de`/`test123` → lands on +`/dashboard`, **no `pageerror`**, dashboard renders. The "Oops" is gone. + +### ⚠️ Known follow-up (non-fatal — dashboard renders via mock fallback) +Dashboard API endpoints are **mis-wired**: frontend calls `/api/backend/dashboard/stats`, +`/distributions/recent`, `/consent/check` → proxy rewrites to `/api/v1/dashboard/stats` +etc., but the backend has **no such routes** (real stats route is `/api/v1/clubs/me/stats` +in `ClubController`; `/dashboard` only exists in `PortalController`) → HTTP 500/404. +The dashboard falls back to `mockClubStats`/`mockRecentDistributions` so it still renders. +Frontend `ClubStats` type also differs from backend `ClubStatsResponse`. Fix = align +service paths + DTO shape, or add `/api/v1/dashboard/*` endpoints to the backend. + +### 🔧 New tooling installed on the Fedora 44 workstation +- **Node.js 22.22.2 + npm 10.9.7** via `sudo dnf install -y nodejs npm` (was MISSING). +- **`@playwright/mcp` v0.0.76** (run via `npx @playwright/mcp@latest`) + Chromium + headless-shell (`npx playwright install chromium`). Wired into Roo `mcp_settings.json` + (server name `playwright`). Chromium launches fine on Fedora 44 despite the + "OS not officially supported" warning. +- **Probe:** `scripts/debug/dashboard-probe.mjs` — reusable client-side debugger. + +--- + ## ✅ LOGIN WORKING — 2026-06-13 (update 2) — full auth flow verified After deploy, login showed a client-side "Oops! Something went wrong" error boundary. diff --git a/docs/TOURGUIDE.md b/docs/TOURGUIDE.md new file mode 100644 index 0000000..108195e --- /dev/null +++ b/docs/TOURGUIDE.md @@ -0,0 +1,160 @@ +# 🌿 CannaManage — Local Test Tour Guide + +**URL:** http://192.168.188.119:3000 +**Stack:** Next.js frontend → Spring Boot backend → PostgreSQL +**Deployed on:** TrueNAS.local (`/mnt/VM_SSD_Pool/cannamanage/`) + +--- + +## 🔐 Login Credentials + +| Field | Value | +|-------|-------| +| Email | `admin@test.de` | +| Password | `test123` | +| Role | `ROLE_ADMIN` | +| Club | Grüner Daumen e.V. (Berlin) | + +Go to **http://192.168.188.119:3000** → you'll land on the login page → enter the credentials above. + +--- + +## 🗺️ What's Been Built — Where to Look + +### 1. Marketing / Public Pages (no login required) + +These are the public-facing pages Sprint 6 just shipped: + +| URL | What you'll see | +|-----|-----------------| +| `/pricing` | 3-tier pricing: Starter €19, Pro €49, Enterprise | +| `/impressum` | Legal imprint placeholder | +| `/datenschutz` | Privacy policy placeholder | +| `/agb` | Terms of service placeholder | + +> These pages use a separate layout (no sidebar, no auth). The footer links to them from login page and portal. + +--- + +### 2. The Portal (after login) + +Once you log in as `admin@test.de`, you're in the **club management portal** for *Grüner Daumen e.V.* + +#### 📊 Dashboard +The main overview. Should show club stats, recent activity, quick links. + +#### 👥 Members +5 test members pre-loaded: + +| Name | Email | Age | Membership # | Notes | +|------|-------|-----|--------------|-------| +| Max Mustermann | max@test.de | Adult | M-001 | Regular member | +| Anna Schmidt | anna@test.de | Adult | M-002 | Regular member | +| Jonas Weber | jonas@test.de | **Under 21** | M-003 | ⚠️ THC restricted | +| Lisa Meyer | lisa@test.de | Adult | M-004 | Regular member | +| Tom Fischer | tom@test.de | Adult | M-005 | Regular member | + +> **Try:** Click on Jonas Weber — his under-21 flag means he can only receive CBD strains and has a lower monthly limit (30g vs 50g). + +#### 🌱 Strains / Batches +3 test strains and 3 available batches: + +| Strain | THC | CBD | Batch Code | Stock | +|--------|-----|-----|------------|-------| +| Northern Lights | 18.5% | 0.8% | BATCH-2024-001 | 500g | +| Amnesia Haze | 22.0% | 1.2% | BATCH-2024-002 | 300g | +| CBD Critical Mass | 5.0% | 12.0% | BATCH-2024-003 | 200g | + +> **Try:** Attempt to distribute Amnesia Haze (22% THC) to Jonas Weber — the compliance engine should **block it** (under-21 THC limit enforcement). + +#### 📦 Distributions / POS +Try recording a distribution: +1. Select a member (e.g., Max Mustermann) +2. Select a batch (e.g., Northern Lights) +3. Enter quantity in grams (e.g., 5g) +4. Submit + +The backend compliance check runs: member active? batch available? THC ok? daily limit (25g)? monthly limit (50g)? + +> **Stress test:** Try distributing 30g in one go to Max — it should be blocked (daily limit is 25g per CanG). + +#### 👔 Staff Management (Sprint 3) +Staff invite flow. You can invite staff members via email and assign roles. Check the staff list page. + +#### ⚙️ Club Settings +Club details: name, address, license number, max members cap (500). Edit fields and save. + +--- + +## 🧪 Compliance Engine — What to Test + +These are the core legal compliance rules from CanG (Cannabis Act): + +| Test | How | Expected result | +|------|-----|-----------------| +| Under-21 + high THC strain | Distribute Amnesia Haze to Jonas Weber | ❌ Blocked | +| Under-21 + CBD strain | Distribute CBD Critical Mass to Jonas | ✅ Allowed (≤10% THC) | +| Over daily limit | Try 26g for Max in one distribution | ❌ Blocked (max 25g/day) | +| Over monthly limit | Try distributing 50g total to one member | ❌ Blocked (max 50g/month, 30g for under-21) | +| Valid distribution | 5g Northern Lights to Anna Schmidt | ✅ Approved | + +--- + +## 📑 API (for nerds) + +The Spring Boot API is exposed at **http://192.168.188.119:8080** + +Swagger UI (if enabled): http://192.168.188.119:8080/swagger-ui/index.html +Health check: http://192.168.188.119:8080/actuator/health + +### Get a JWT token: +```bash +curl -X POST http://192.168.188.119:8080/api/v1/auth/login \ + -H "Content-Type: application/json" \ + -d '{"email":"admin@test.de","password":"test123"}' +``` + +--- + +## 🐳 Container Management + +All running on TrueNAS at `/mnt/VM_SSD_Pool/cannamanage/`: + +```bash +# Check status +ssh truenas.local "docker ps --filter name=cannamanage" + +# View backend logs +ssh truenas.local "docker logs cannamanage-backend -f --tail=50" + +# View frontend logs +ssh truenas.local "docker logs cannamanage-frontend -f --tail=50" + +# Restart everything +ssh truenas.local "cd /mnt/VM_SSD_Pool/cannamanage && docker compose -f docker-compose.yml -f docker-compose.truenas.yml restart" + +# Stop everything +ssh truenas.local "cd /mnt/VM_SSD_Pool/cannamanage && docker compose -f docker-compose.yml -f docker-compose.truenas.yml down" + +# Pull latest + rebuild +ssh truenas.local "cd /mnt/VM_SSD_Pool/cannamanage && git pull && docker compose -f docker-compose.yml -f docker-compose.truenas.yml up -d --build" +``` + +--- + +## 🌍 i18n — Language Toggle + +The app has German and English translations. Look for a language switcher in the UI — should be visible on login page and in the portal header. Marketing pages (`/pricing` etc.) are also bilingual. + +--- + +## ⚠️ Known Limits of the Test Environment + +- Legal page texts (`/impressum`, `/datenschutz`, `/agb`) are **placeholder templates** — not real legal text +- Pricing page is a **mockup** — Stripe is not integrated yet +- Email sending (staff invites) is not wired to a real mail server in dev +- The "seed data" dates are from 2024 — the compliance quota engine uses current month/year, so the pre-seeded distributions won't count against current monthly limits + +--- + +*Generated by Lumen — Homelab Mode — 2026-06-13*