4.2 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Marktvogt is a platform for medieval markets (Mittelaltermärkte) in the DACH region. It connects visitors, merchants, artists, camp groups, and organizers — replacing fragmented Facebook groups, phone calls, and scattered websites.
All planning documents are in planning/. Read 17-roadmap.md for the phased feature plan and 15-mvp.md for current MVP scope.
Architecture
Monorepo at somegit.dev/vikingowl/marktvogt.de. Components are regular directories (not git submodules):
backend/— Go REST API + WebSocket (chat). PostgreSQL (+ PostGIS), Redis, S3 (self-hosted on itsh.dev).web/— SvelteKit + Tailwind 4. SSR for SEO. Consumes the Go API.app/— Flutter mobile app (Android + iOS). Consumes the Go API.admin/— Separate admin dashboard (own repo, added later).
Tech Stack
| Layer | Technology |
|---|---|
| Backend | Go, PostgreSQL, PostGIS, Redis, S3 |
| Web Frontend | SvelteKit, Tailwind 4 |
| Mobile | Flutter |
| Auth | Custom (Go libs), E-Mail+PW / Magic Link / OAuth / 2FA |
| Payments | Stripe Connect |
| LLM | Google Gemini |
| CI/CD | Woodpecker (ci.somegit.dev) — .gitlab-ci.yml retained as fallback |
| Hosting | Kubernetes (itsh.dev), Helm chart at helm/marktvogt/ |
| Monitoring | Prometheus, Loki, Grafana, Sentry |
Key Domain Concepts
- 6 roles: Gast (anonymous), User (registered), Händler (merchant), Künstler (artist), Lager (reenactment camp group), Veranstalter (organizer)
- Groups: All applicants (Händler/Künstler/Lager) operate as groups. A solo merchant is a one-person group. Applications always go through groups.
- Veranstalter is the central role — creates markets, manages plots, reviews applications, configures tickets.
- Mitarbeiter (staff) is a sub-role under Veranstalter with granular permissions.
Git Workflow
When asked to "commit to a new branch, merge to main, and push":
git checkout -b <branch-name>
git add <files>
git commit -m "<message>"
git checkout main && git merge --ff-only <branch-name> && git push origin main && git branch -d <branch-name>
No MR/PR needed for this pattern — merge locally, push main directly.
Development Conventions
- All planning docs use ASCII (no umlauts) for cross-platform compatibility.
- API design: REST for CRUD, WebSocket for real-time chat.
- Auth is custom-built using Go libraries (no external auth provider).
- Offline capability required for QR ticket validation and venue maps.
Current Status
Project is in active development as of 2026-04-18. backend/, web/, and app/ contain working code (Go API scaffolding + auth, SvelteKit pages, Flutter iOS/Android skeleton). Refer to planning/17-roadmap.md for feature sequencing and planning/15-mvp.md for current MVP scope.
Container registry is registry.itsh.dev/vikingowl/marktvogt.de/{backend,web} — a hosted Zot-backed registry that requires attestations on every pushed image. CI builds via woodpeckerci/plugin-docker-buildx (handles attestations by default); see .woodpecker/{backend,web}.yaml.
Deployment
Single Helm release marktvogt in namespace tenant-2, deployed from helm/marktvogt/ (monolithic chart for both backend + web + Postgres + Dragonfly). CI deploys via helm upgrade marktvogt --reuse-values --set-string <service>.image.tag=... (must use --set-string to avoid float coercion of all-digit SHAs).
K8s Secrets are pre-created out-of-band by scripts/k8s-secrets-sync.sh reading from .env.helm (gitignored). CI no longer touches secret values. Web runs on the Bun runtime (oven/bun:1-alpine), backend on a CGO-disabled Go static binary.
kubectl exec into pods is blocked by the cluster's block-exec-non-gvisor kyverno policy — use kubectl port-forward svc/marktvogt-pg-rw 5432:5432 + psql for ad-hoc DB access. Tenant subdomains (e.g. api.marktvogt.de) must be explicitly added via the panel's "Eigene Domains" tab; subdomains aren't auto-allowed by itsh.dev/allowed-hostnames.