- Admin layout with auth guard at /admin
- Admin market list with status filter tabs (pending/approved/rejected)
- Admin market detail/review with approve/reject actions
- Admin market create and edit forms with shared MarketForm component
- Anonymous market submission form at /markt/einreichen with Turnstile
- Optional latitude/longitude fields on submission form
- Admin and submission types added to API types
- requireAdmin guard for role-based frontend access
- Header/mobile nav updated with admin and submission links
- Auth layout redirect removed to re-enable login flow
- Login form action renamed to fix named actions conflict
- Impressum updated with user-submitted content section
- Datenschutz updated with submission form and Turnstile sections
Parse semi-structured notes text (e.g. "Samstag: Erw. 15 €, Kinder 8 €")
into grouped table rows instead of showing raw text below the table.
- Split notes on sentence boundaries (". " + uppercase), handling
abbreviations like "Erw." correctly
- Extract "Label: Category Price €" patterns into table groups
- Expand common abbreviations (Erw. → Erwachsene, Erm. → Ermäßigt)
- Guard against "Cat: Price, Cat: Price" format (colons in pricesStr)
- Guard against bare prices after colon (letter-start requirement)
- Graceful fallback to flat table + raw notes when parsing fails
Add /healthz handler in hooks.server.ts that returns early without auth
or SSR processing. Update Helm probes from / to /healthz to avoid
unnecessary log noise and wasted SSR renders.
Add /maerkte/ browse-by-state overview, /maerkte/[state]/ state detail
pages, and /maerkte/[state]/[city]/ city detail pages. Each page fetches
all markets and filters client-side (SSR). Includes slug utilities with
umlaut handling, JSON-LD structured data, breadcrumb navigation on all
pages including market detail, and sitemap entries for all new routes.
- Enable kit.version.pollInterval (60s) so SvelteKit detects new
deploys via version.json
- Add beforeNavigate guard that forces a full page reload when a
new version is detected, preventing stale client-side state
- Preload fonts, JS, and CSS for faster initial paint
With 900m/1000m CPU limits used, rolling updates fail because the
new pod cannot be created alongside the old one. Setting maxSurge=0
and maxUnavailable=1 kills the old pod first, avoiding quota exhaustion
at the cost of brief downtime during deploys.
The auth and profile layout redirects break SvelteKit's type
generation for child page loads, causing false-positive type
errors where PageData requires `user` from the root layout.
- Add dynamic sitemap.xml with static pages and market entries
- Add canonical URLs and base OG/Twitter meta tags in root layout
- Add JSON-LD WebSite schema with SearchAction on home page
- Add JSON-LD Event schema on market detail pages
- Add twitter:card summary_large_image for markets with images
- Add OG tags to impressum and datenschutz pages
- Add font preloading for critical rendering path fonts
- Add Sitemap directive to robots.txt
Add legal pages required by German law (TMG §5, DSGVO).
Impressum includes operator identity, contact, and liability notices.
Datenschutz covers all data processing: registration, OAuth, sessions,
cookies, geolocation, map tiles, and user rights.
Introduces brand identity with a medieval signet ring motif:
gold fleur-de-lis on dark green signet face. Adds SVG favicon,
raster fallbacks (ICO/PNG), apple-touch-icon, web manifest,
and inline signet ring logo in the header next to the wordmark.
- Add MedievalSharp + Crimson Pro fonts (woff2)
- Implement OKLCH color theme: forest green primary, gold accent,
warm stone neutrals, parchment/vellum surfaces, brick red danger
- Add dark/light mode with system preference detection and user toggle
(ThemeToggle component cycling system/light/dark)
- Prevent FOUC with inline script in app.html
- Replace native <select> with custom accessible dropdown (combobox/
listbox pattern, keyboard nav, type-ahead, app-themed styling)
- Add IP geolocation fallback via geojs.io when native geolocation
fails, with visual location badge showing resolved city name
- Shared form control styles via @layer base
- WCAG/a11y: skip-to-content link, aria-invalid, aria-describedby,
aria-live, focus-visible, role="search", color-scheme:dark
- Update all 23 component/page files with new color system and
dark: variants