docs: add top-level README
This commit is contained in:
164
README.md
Normal file
164
README.md
Normal file
@@ -0,0 +1,164 @@
|
||||
# Marktvogt
|
||||
|
||||
**The central portal for medieval markets ("Mittelaltermaerkte") in the DACH region.**
|
||||
|
||||
Marktvogt connects visitors, merchants, artists, camp groups, and organizers on
|
||||
one platform — replacing the patchwork of Facebook groups, phone calls, mailing
|
||||
lists, and scattered websites that the scene currently runs on.
|
||||
|
||||
The name comes from the historical *Marktvogt* — the keeper of order at medieval
|
||||
markets. Same job, different century.
|
||||
|
||||
---
|
||||
|
||||
## The Problem
|
||||
|
||||
The medieval-market scene in the DACH region is large (hundreds of markets per
|
||||
year) but digitally fragmented:
|
||||
|
||||
- **Finding markets**: Facebook groups, `mittelalterkalender.info`, private sites
|
||||
- **Bookings** (merchants, artists, camps): phone, e-mail, Facebook Messenger
|
||||
- **Camp groups**: organize almost exclusively on Facebook
|
||||
- **Tickets**: usually box-office-only or one-off organizer sites
|
||||
|
||||
There is no single portal that brings all participants together. Marktvogt is
|
||||
that portal.
|
||||
|
||||
## The Solution
|
||||
|
||||
A two-sided marketplace:
|
||||
|
||||
- **Supply side** — organizers list markets, open plots, programs, tickets
|
||||
- **Demand side** — visitors discover markets and buy tickets; merchants,
|
||||
artists, and camp groups apply for spots
|
||||
|
||||
Network effects: organizers attract applicants, applicants make the platform
|
||||
indispensable for organizers, and visitors follow the content.
|
||||
|
||||
## Roles
|
||||
|
||||
Six roles, with the *Veranstalter* (organizer) as the central actor:
|
||||
|
||||
| Role | Description |
|
||||
|---------------|----------------------------------------------------------|
|
||||
| Gast | Anonymous visitor — browse markets, no account |
|
||||
| User | Registered visitor — tickets, favorites, profile |
|
||||
| Haendler | Merchant group applying for plots |
|
||||
| Kuenstler | Artist group applying for performance slots |
|
||||
| Lager | Reenactment camp group applying for camp space |
|
||||
| Veranstalter | Organizer — creates markets, reviews applications, sells tickets |
|
||||
|
||||
All applicants (Haendler / Kuenstler / Lager) operate as **groups**. A solo
|
||||
merchant is just a one-person group. *Mitarbeiter* (staff) is a sub-role under
|
||||
Veranstalter with granular permissions.
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
Monorepo. Components are plain directories, not git submodules.
|
||||
|
||||
| Layer | Stack |
|
||||
|--------------|--------------------------------------------------------------------|
|
||||
| Backend | Go REST API + WebSocket; PostgreSQL (PostGIS), Redis, S3 |
|
||||
| Web | SvelteKit + Tailwind 4, SSR for SEO, runs on Bun |
|
||||
| Mobile | Flutter (Android + iOS) |
|
||||
| Auth | Custom (Go), e-mail+password / magic link / OAuth / 2FA |
|
||||
| Payments | Stripe Connect |
|
||||
| LLM | Google Gemini (`gemini-2.5-flash-lite`) for enrichment |
|
||||
| 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 |
|
||||
|
||||
### Repo Layout
|
||||
|
||||
```
|
||||
backend/ Go REST API + WebSocket chat
|
||||
web/ SvelteKit frontend (SSR, Bun runtime)
|
||||
app/ Flutter mobile app
|
||||
helm/ Monolithic Helm chart (backend + web + Postgres + Dragonfly)
|
||||
planning/ Vision, roadmap, MVP scope, feature specs (German, ASCII-only)
|
||||
scripts/ Out-of-band tooling (e.g. K8s secret sync)
|
||||
.woodpecker/ CI pipelines for somegit.dev
|
||||
```
|
||||
|
||||
The admin dashboard lives in its own repo and will be added later.
|
||||
|
||||
---
|
||||
|
||||
## Getting Started
|
||||
|
||||
The repo is driven by a `Justfile`. Run `just` for the full list.
|
||||
|
||||
```bash
|
||||
# One-time setup: pre-commit hooks, web deps, golangci-lint
|
||||
just hooks-install
|
||||
|
||||
# Backend
|
||||
just backend-dev # Postgres + Valkey via docker compose
|
||||
just backend-run # go run ./cmd/api
|
||||
just backend-test
|
||||
just backend-lint
|
||||
|
||||
# Web
|
||||
just web-dev # SvelteKit dev server
|
||||
just web-check # svelte-check (types)
|
||||
just web-lint
|
||||
|
||||
# Everything
|
||||
just lint
|
||||
just test
|
||||
just fmt
|
||||
```
|
||||
|
||||
For component-specific details, see `backend/README.md`, `web/README.md`, and
|
||||
`app/README.md`.
|
||||
|
||||
---
|
||||
|
||||
## Deployment
|
||||
|
||||
Single Helm release `marktvogt` in namespace `tenant-2`, deployed from
|
||||
`helm/marktvogt/` (monolithic chart covering backend, web, Postgres, and
|
||||
Dragonfly). CI runs:
|
||||
|
||||
```bash
|
||||
helm upgrade marktvogt --reuse-values \
|
||||
--set-string backend.image.tag=<sha> \
|
||||
--set-string web.image.tag=<sha>
|
||||
```
|
||||
|
||||
`--set-string` is mandatory — all-digit short SHAs get float-coerced into
|
||||
scientific notation otherwise, which then fails K8s label validation.
|
||||
|
||||
K8s Secrets are pre-created out-of-band by `scripts/k8s-secrets-sync.sh`
|
||||
reading from `.env.helm` (gitignored). CI never touches secret values.
|
||||
|
||||
The container registry (`registry.itsh.dev/vikingowl/marktvogt.de/{backend,web}`)
|
||||
is Zot-backed and **requires attestations** on every pushed image. The
|
||||
Woodpecker pipelines use `woodpeckerci/plugin-docker-buildx`, which handles
|
||||
this by default.
|
||||
|
||||
---
|
||||
|
||||
## Status
|
||||
|
||||
Active development as of 2026-04-28. `backend/`, `web/`, and `app/` all contain
|
||||
working code (Go API scaffolding + auth, SvelteKit pages, Flutter skeleton).
|
||||
|
||||
- Current phase scope: `planning/15-mvp.md`
|
||||
- Phased feature plan: `planning/17-roadmap.md`
|
||||
- Vision: `planning/00-vision.md`
|
||||
|
||||
Planning docs are in German and use ASCII only (no umlauts) for cross-platform
|
||||
compatibility.
|
||||
|
||||
---
|
||||
|
||||
## Conventions
|
||||
|
||||
- **API design**: REST for CRUD, WebSocket for real-time chat
|
||||
- **Auth**: custom-built using Go libraries — no external auth provider
|
||||
- **Offline capability**: required for QR-ticket validation and venue maps
|
||||
- **Commits**: conventional commit messages
|
||||
- **Source of truth for product**: `planning/` — read it before adding features
|
||||
Reference in New Issue
Block a user