KommuneFlow AI is a working portfolio implementation of municipal case management. A citizen submits a request, a provider prepares a structured suggestion, and an employee reviews that suggestion before official case values change.
Problem: municipal requests often arrive through fragmented channels and need careful routing, traceability, and handling of sensitive information. This repository demonstrates one coherent citizen-to-employee workflow. It is not an approved SaaS product or a system for real citizen data.
The public demo uses shared synthetic data, deterministic mock AI, and a short-lived restricted guest session. Public uploads are disabled. Changes may be reset or affected by another visitor. No account is required for the public portfolio path; normal staff login remains a separate controlled path.
- Demo script
- API reference
- Security and privacy
- AI governance
- Home-server deployment
- Screenshots
- Verification log
- A citizen chooses a municipality and submits synthetic text through the Norwegian or English intake.
- The API returns a case reference and a private status access code. The code is used in the JSON body of the status lookup and is not placed in a URL.
- The citizen can continue to the same municipality's employee demo.
- The server creates an allowlisted, short-lived
portfolio_guestsession. - The guest reviews cases, opens a case, runs deterministic mock AI, and accepts or corrects the suggestion.
- The employee workflow changes only after explicit human review. The current deployed guest Analytics page is the compact live portfolio view with synthetic counts, review totals, denominator-aware failure rate, waiting citizen status, and median triage time with sample size.
The guest role cannot access administration, privacy, audit, operations, document upload/delete, or analytics aggregation. These boundaries are enforced by server-side permissions and are documented in the security and verification documents.
flowchart LR
Internet --> GlobalCaddy[Global Caddy TLS :80/:443]
GlobalCaddy --> Gateway[Project gateway HTTP :8080]
Gateway --> Web[Next.js web]
Gateway --> API[NestJS API]
API --> Auth[JWT and RBAC guards]
API --> Cases[Cases and documents]
API --> AI[AIProvider]
API --> Analytics[Analytics]
API --> DB[(PostgreSQL)]
AI --> Mock[Deterministic mock provider]
AI -. optional .-> OpenAI[OpenAI provider]
The current public deployment is the home-server topology: global Caddy terminates TLS, while the project gateway runs on the shared proxy network and applies routing, security headers, and request-size limits. PostgreSQL, API, and web remain on the private project network. See the deployment runbook and verification evidence.
Hetzner files are retained as alternative deployment assets, not as evidence of the current live deployment. Azure/Fabric material is architecture exploration and is not implemented.
The implementation includes password hashing, HttpOnly authentication cookies, JWT validation, rate limiting, security headers, CORS and origin validation, request-size limits, server-side permission guards, tenant-scoped queries, upload validation, private upload storage, safe error responses, audit events, privacy export/anonymization controls, retention cleanup, and negative auth, RBAC, tenant, upload, and guest-perimeter tests.
These are implemented portfolio controls, not a certification or a claim of regulatory compliance. Privacy documentation describes the intended controls and remaining limitations.
- Security and privacy
- Production security hardening
- Privacy notice
- Data processing inventory
- DPIA-lite
AI suggestions are separate from official case fields, validated with Zod, and
record human review decisions. The provider is selected behind the
AIProvider abstraction. Local tests and the public deployment use the
deterministic mock provider. OpenAI is an optional provider for a protected
manual workflow; this repository does not claim that real OpenAI has been
verified unless a dated successful run is recorded in the verification log.
Current AI execution is synchronous in the request path. Background workers, stronger PII redaction, cost monitoring, retries, and production operational controls remain future work.
See AI governance and the provider ADR.
- Bilingual citizen and internal portfolio workflows support Norwegian and English.
- The public path uses synthetic data and disables public uploads.
- Guest Analytics is a compact live portfolio reference view, not a live SSB or municipal performance report. It shows synthetic counts and sample-size-limited metrics rather than real municipal reporting.
- SSB integration code exists, but this README does not claim a completed live import without dated evidence.
- Background jobs, scheduled backup/restore testing, real OpenAI verification, and a full tenant/user/feature-management product surface are not claimed as implemented portfolio behavior.
- The application is not approved for production municipal use.
The selected implementation uses TypeScript, Next.js, NestJS, PostgreSQL,
Prisma, Zod, Python ELT tests, Docker Compose, Caddy, and Vitest/Jest/
Playwright. OpenAI is optional behind AIProvider; the public mode is mock AI.
Requirements: Node.js 24+, pnpm 10+, and Docker Desktop.
pnpm install
cp .env.example .env
docker compose up -d postgres
pnpm --filter @kommuneflow/api prisma:generate
pnpm --filter @kommuneflow/api prisma:migrate
pnpm --filter @kommuneflow/api prisma:seed
pnpm run devLocal URLs:
- Web:
http://localhost:3000 - API:
http://localhost:3101/api/v1 - Citizen intake:
http://localhost:3000/nbor/en - Internal login:
http://localhost:3000/internal/login - Internal cases:
http://localhost:3000/internal/cases - Internal analytics:
http://localhost:3000/internal/analytics
Use ignored local environment values for seeded passwords. Do not publish passwords, access codes, cookies, or private operational values.
pnpm lint
pnpm typecheck
pnpm test:all
pnpm build
pnpm audit:deps
git diff --checkThe exact local, CI, and live results are recorded in the verification log. A dependency audit finding is reported as a finding; it is not relabeled as clean.
The API groups are auth, public tenant cases, cases, documents,
ai-triage, analytics, Kartverket and SSB integrations, operations,
privacy, health, and readiness. See the
API reference for the current method, path, body,
permission, and response conventions.
The current public deployment is the home server at
https://kommune.norvix.no. The deployment runbook documents the project
Compose file, global Caddy boundary, shared proxy network, health checks,
release procedure, backups, rollback notes, and evidence links. It uses mock AI
and synthetic data.
Use the documented home release procedure instead of a direct Compose command.
Run ./scripts/home-release.sh on the home server and follow
Home-server deployment.
Alternative deployment material is explicitly separated from the current deployment:
apps/api: NestJS API, Prisma schema, migrations, seed, and tests.apps/web: Next.js citizen and internal portfolio workflows.packages/shared: shared public documentation-safe types and capability data.apps/etl: Python integration helpers and tests.docs: current product, security, deployment, demo, and evidence documents.deploy: container gateway and reverse-proxy configuration..github/workflows: CI and protected manual verification workflows.