Commit Graph

8 Commits

Author SHA1 Message Date
vikingowl 580b9d5e3c feat: add admin panel, market submissions, and email notifications
- Admin CRUD endpoints for markets with role-based middleware
- Anonymous market submission with Cloudflare Turnstile verification
- SMTP email notifications on new submissions (LogSender fallback)
- Market status workflow (pending/approved/rejected) with admin notes
- Nullable location column for submissions without coordinates
- CLI tool for promoting users to admin role
- Slug generation package extracted from seed
- Rate limiting on submission endpoint (3/hour per IP)
- Mailpit added to docker-compose for local email testing
2026-02-27 11:03:44 +01:00
vikingowl cb2e8c4cde fix(seed): gofmt struct field alignment 2026-02-22 19:13:53 +01:00
vikingowl 78046848f2 feat(seed): enrich markets data with real web-researched info
- Reduced from 312 to 272 markets (removed 39 unverified/unconfirmed entries)
- All 272 markets now have real descriptions sourced from official websites
- Added admission prices (adult/child cents + notes) where available
- Added street addresses and corrected venue names
- Added opening hours for markets where published
- Updated websites to full https:// URLs
- Updated seedMarket struct with new fields: Street, Description,
  AdmissionAdultCents, AdmissionChildCents, AdmissionNotes
- Seed INSERT now uses description/admission from JSON instead of
  generating template descriptions; falls back to generated desc if empty
- Added jsonString() helper for SQL-safe JSON encoding
2026-02-22 19:09:21 +01:00
vikingowl 549df60f09 fix(seed): resolve lint issues (noctx, goconst) 2026-02-22 11:41:33 +01:00
vikingowl 993bab1218 fix(seed): skip seeding if database already contains markets 2026-02-22 11:39:26 +01:00
vikingowl ffaee89243 feat(seed): add 311 real medieval markets for 2026
Scrape marktkalendarium.de for 2026 market data and replace the
placeholder seed with real events across DE/AT/CH.

- Embed 311 markets as JSON with name, dates, city, zip, venue,
  organizer and website
- Geocode coordinates via Nominatim with caching and rate limiting
- Auto-derive Bundesland from postal code prefix
- Generate descriptions based on event type keywords
- Support DATABASE_URL env var for direct production seeding
2026-02-22 11:38:14 +01:00
vikingowl 3145dba255 fix(lint): resolve all golangci-lint v2 issues
- Disable revive exported/package-comments rules (style, not correctness)
- Use errors.Is instead of == for pgx.ErrNoRows comparisons
- Use errors.As instead of type assertion on validator errors
- Use http.NewRequestWithContext instead of client.Get (noctx)
- Check resp.Body.Close error return (errcheck)
- Run gofmt on files with formatting drift
2026-02-22 10:09:46 +01:00
vikingowl a1d93f7a8e feat: implement MVP backend API
Go backend with Gin, pgx, Valkey (go-valkey), and PostGIS.

Domains:
- Market search with PostGIS geo-queries (ST_DWithin, ST_Distance),
  German full-text search (tsvector + ILIKE fallback for compound words),
  date range filtering, pagination, and slug-based detail endpoint
- Auth with email+password (bcrypt), JWT access tokens (15min),
  session tokens (30d, dual Valkey+Postgres storage), OAuth
  (Google/GitHub/Facebook), magic links, and TOTP 2FA
- User profile with CRUD, soft-delete (30d grace), and restore

Infrastructure:
- 6 database migrations (users, sessions, oauth_accounts, magic_links,
  markets with PostGIS+FTS, totp_secrets)
- Middleware: recovery, request ID, structured logging (slog), CORS,
  per-IP rate limiting, JWT auth
- Seed data: 10 medieval markets across DACH region
- Docker Compose (PostGIS 17 + Valkey 8), multi-stage Dockerfile,
  Woodpecker CI pipeline, Kubernetes manifests
- Justfile, golangci-lint config, env example
2026-02-18 05:52:20 +01:00