Construct discoveryRepo, discoveryAgent, discoveryService, and
discoveryHandler in registerRoutes(); register all 4 discovery routes
on /api/v1 with bearer-token guard on /tick and admin-session guard on
queue management endpoints.
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.
- 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
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
- 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