Commit Graph

14 Commits

Author SHA1 Message Date
vikingowl 92a5b05875 feat(discovery): add Pass 0 agent client + parser (Mistral) 2026-04-18 07:28:25 +02:00
vikingowl c78e24e4f9 fix(ai): address review feedback on rate limiter (sort/tolerance, ctx-cancel TODO) 2026-04-18 07:06:22 +02:00
vikingowl c95261d747 feat(ai): add process-wide 1 req/s rate limiter to Mistral client 2026-04-18 07:00:35 +02:00
vikingowl 79001011df fix(search): support PLZ filter on home page
The home page dropped `plz` server-side, so /markets was called with
radius but no center (unfiltered) and the PLZ input rendered empty
after reload. +page.server.ts now reads plz, geocodes via /geocode,
and echoes plz back in searchParams for form rehydration.

Relaxes /geocode DTO + guard to accept PLZ without city — Nominatim
already supports postal-only lookups. URL lat/lon (GPS flow) take
priority over plz on tie-break; geocode failures fall through to no
geo-filter so the page always renders.
2026-04-18 05:32:28 +02:00
vikingowl 7d07d47ec5 chore: convert to GitLab monorepo
- Merge backend, web, app, planning histories (118 commits preserved)
- Replace Woodpecker CI with .gitlab-ci.yml (path-based triggering)
- Switch mistral-go-sdk from somegit.dev to github.com/VikingOwl91/mistral-go-sdk v1.3.0
- Consolidate .pre-commit-config.yaml and .gitignore at repo root
- Remove per-service .woodpecker.yml files
2026-04-07 02:53:03 +02:00
vikingowl 41876cd698 fix: remove completion_args from agent conversation request
Mistral rejects completion_args when agent_id is set. The agent's
own configuration (set in Mistral UI) controls response format.
2026-03-05 21:37:37 +01:00
vikingowl 209efe5309 fix: override response format to text for agent conversations
Mistral rejects json response format when tools (web search) are
active. Override to text since the prompt already requests JSON
output in the instructions.
2026-03-05 21:32:03 +01:00
vikingowl 340132626c refactor: replace hand-rolled Mistral HTTP client with mistral-go-sdk
Use the Conversations API (POST /v1/conversations) via the SDK for
Pass 1 agent calls instead of /agents/completions which doesn't
support built-in web search connectors. Pass 2 uses the SDK's
ChatComplete method.
2026-03-05 21:21:41 +01:00
vikingowl b5ac2620bf feat: market series/editions model, two-pass AI research, source-derived confidence
Split markets into market_series (persistent identity) + market_editions
(yearly instances). Migration preserves edition UUIDs from old market IDs
for URL backward compatibility. Edition statuses: rumored, confirmed,
active, completed, cancelled, archived.

AI research now uses two-pass pipeline: Pass 1 via pre-created Mistral
agent with web search for structured extraction, Pass 2 via
mistral-large-latest for description writing and field retry. Confidence
scoring is source-derived (source count + extraction type) instead of
LLM self-reported.
2026-03-05 16:38:43 +01:00
vikingowl aa7a982caf feat: add AI research, geocoding, duplicate detection, enriched market submit
- AI research via Mistral API for admin market editing
- Auto-geocoding via Nominatim OSM with rate limiting
- Public geocode endpoint (POST /api/v1/geocode)
- Duplicate detection using pg_trgm trigram similarity
- Extended SubmitMarketRequest with street, opening_hours, admission_info
- pg_trgm migration for fuzzy name matching
2026-03-05 15:18:44 +01:00
vikingowl e07f4c4c64 feat: add HTML email templates with medieval aesthetic
Add styled HTML email templates for market submission notifications
and magic link authentication, matching the frontend's forest green
and gold design language.

- Template engine using go:embed with clone-per-content pattern
- Multipart/alternative MIME (text/plain + text/html) in SMTPSender
- Base layout: dark green header, gold accent, parchment tones
- Market submission template with details table and admin CTA
- Magic link template with CTA button and fallback URL
- Wire email sending into MagicLinkHandler (replaces TODO)
- Add FRONTEND_URL config for template links
2026-02-27 11:36:59 +01:00
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 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