Patrick Plate a686957b09
CI — Build, Lint & Security Scan / backend (push) Failing after 1m4s
CI — Build, Lint & Security Scan / frontend (push) Failing after 1m24s
CI — Build, Lint & Security Scan / image-scan (push) Has been skipped
CI — Build, Lint & Security Scan / secrets-scan (push) Failing after 21s
Deploy to TrueNAS / deploy (push) Failing after 4m0s
feat(deploy): public hosting at cannamanage.plate-software.de + fix systemic auth-token bug
Auth fix (the real unblocker):
- Add server-side proxy Route Handler app/api/backend/[...path]/route.ts that
  reads the NextAuth session via auth() and injects Authorization: Bearer on
  every API call. Method-agnostic; streams raw request body (multipart uploads)
  and upstream response body (binary PDF/CSV downloads). Replaces the static
  next.config.mjs rewrite, which could not inject a header — the root cause of
  every authenticated browser fetch hitting the backend unauthenticated.
- Expose session.accessToken in the auth.ts session() callback (+ type aug).
  Uses auth() not getToken() so cookie handling is correct across the public
  HTTPS (Apache) -> internal HTTP (container) proxy boundary.
- No service files changed; all 24 services already call /api/backend/*.
  Verified live: NextAuth login -> GET /api/backend/members -> HTTP 200.

Public hosting (same proven chain as Gitea/InspectFlow):
- docker-compose.truenas.yml: NEXTAUTH_URL/AUTH_URL -> https public origin,
  rotate AUTH_SECRET + JWT_SECRET + DB_PASSWORD off the committed dev defaults.
- deploy.yml: inject AUTH_SECRET/JWT_SECRET/DB_PASSWORD from Gitea secrets;
  reconcile the live Postgres role password (volume keeps old pw on re-deploy).
- frpc on TrueNAS tunnels frontend :3000 -> VPS frps :30010; IONOS Apache
  terminates TLS for cannamanage.plate-software.de and proxies through frp.
2026-06-22 10:46:15 +02:00

CannaManage

Full-stack management platform for German cannabis cultivation associations (Anbauvereinigungen) under the CanG/KCanG regulatory framework.

Tech Stack

Layer Technology
Frontend Next.js 15, React 19, TypeScript, Tailwind CSS 4, shadcn/ui
Backend Spring Boot 3.5, Java 17, Spring Security (JWT + session)
Database PostgreSQL 16, Flyway migrations
Infrastructure Docker Compose, Gitea Actions CI/CD, TrueNAS deployment

Project Structure

cannamanage/
├── cannamanage-api/        # Spring Boot REST API (entry point)
├── cannamanage-service/    # Business logic layer
├── cannamanage-domain/     # JPA entities, enums, value objects
├── cannamanage-frontend/   # Next.js frontend (pnpm)
├── deploy/                 # Deployment scripts & nginx config
├── docker-compose.yml      # Local development stack
└── .gitea/workflows/       # CI/CD pipeline

Local Development

Prerequisites

  • Java 17+
  • Maven 3.9+
  • Node.js 22+ with pnpm 10+
  • Docker & Docker Compose

Backend

# Start PostgreSQL
docker compose up -d db

# Run Spring Boot
mvn spring-boot:run -f cannamanage-api/pom.xml -Dspring-boot.run.profiles=local

Frontend

cd cannamanage-frontend
pnpm install
pnpm dev

The frontend runs on http://localhost:3000, backend on http://localhost:8080.

Full Stack (Docker)

docker compose up --build

Deployment

Push to main triggers the Gitea Actions CI pipeline which:

  1. Runs backend tests (mvn test)
  2. Runs frontend lint (pnpm lint)
  3. Builds Docker images
  4. Deploys to TrueNAS via Docker Compose
  5. Verifies backend health + frontend availability

Manual deploy:

cd deploy && ./deploy.sh

Environment Variables

Variable Purpose Default
CANNAMANAGE_SECURITY_JWT_SECRET JWT signing key (base64, 256-bit) — (required)
CORS_ORIGINS Allowed CORS origins (comma-separated) http://localhost:3000
SMTP_HOST / SMTP_PORT Mail server for invites localhost:1025
SCHEDULERS_ENABLED Enable background jobs true

License

Proprietary — Patrick Plate

S
Description
CannaManage — B2B SaaS for German Cannabis Social Clubs (Anbauvereinigungen)
Readme 7.8 MiB
Languages
Java 61%
TypeScript 38.1%
JavaScript 0.4%
CSS 0.3%
Shell 0.2%