docs: update README and Obsidian documentation

Document multi-format image pipeline, MapLibre GL map components, WASM encoder workers, loyalty stamp redesign, admin role restrictions, and Svelte 5 improvements across README, Overview, and Technical Manual.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-06-04 01:09:00 +01:00
co-authored by Sisyphus
parent 6c16d65476
commit 490274f466
3 changed files with 116 additions and 5 deletions
+11
View File
@@ -33,6 +33,17 @@ Nail salon booking platform — Go 1.25 backend + SvelteKit 5 frontend + Docker.
- **`created_by_name` on bookings**: admin booking details now show who created the booking (admin name)
- **Exceptional scheduling fix**: exceptional application queries expand start to Monday of the week, fixing single-day queries missing Monday-based `week_start` records
- **Portfolio image upload limits**: 20MB file size limit with visual feedback (red borders, error text), upload button disabled for oversized files
- **Multi-format portfolio images**: Backend stores AVIF, WebP, JPEG, and optional JXL variants for both full-size and thumbnail images. Frontend `ImageVariant` component renders `<picture>` elements with format-aware fallback. WASM-based client-side encoders (`@jsquash/avif`, `@jsquash/webp`, `@jsquash/jpeg`, `@discourse/jxl`) run in Web Workers for parallel encoding. Database schema extended with `full_avif_url`, `full_webp_url`, `full_jpg_url`, `full_jxl_url`, `thumb_avif_url`, `thumb_webp_url`, `thumb_jpg_url` columns. Image validation supports AVIF and JXL magic bytes. Legacy single-URL images remain backward-compatible.
- **MapLibre GL map components**: Reusable Svelte map components (`Map`, `MapMarker`, `MapControls`, `MapPopup`, `MapRoute`, `MapClusterLayer`, `MapArc`) wrapping MapLibre GL JS. Features: light/dark theme auto-detection, controlled/uncontrolled viewport, zoom/compass/locate/fullscreen controls, draggable markers, popup/tooltip/label children. Used on contact page for salon location display.
- **NavBar accessibility improvements**: Hamburger menu animated with 4-line to X transform, keyboard-accessible backdrop overlay (Enter/Space to close), ARIA labels, `fly` transitions on notification badge.
- **Loyalty stamp redesign**: Fuchsia-themed stamp card with procedurally-generated flower-petal SVG stamps (unique shape per slot via sine-wave perturbation), star cutout mask, hover scale animation, gradient background. Admin users see simplified account view (no History/Referral/Danger Zone tabs).
- **Admin role restrictions**: Admin accounts hide History tab, Referral tab, Danger Zone (delete account), and loyalty stamp card on the account page.
- **Svelte 5 `SvelteDate`**: Replaced `new Date()` with `new SvelteDate()` in reactive contexts (admin schedule, account page booking filter) for proper Svelte 5 reactivity.
- **`$derived` for computed values**: `totalPages` in notifications page now uses `$derived` instead of runtime calculation.
- **Svelte 5 each block keys**: Added proper keys to `{#each}` blocks across multiple components (NavBar, PortfolioCarousel, TodayCalendar, BookingConfirmed, Demo, PayTip, Tip, Account, Schedule) to fix reordering bugs and improve render performance.
- **`$app/paths` resolve**: All internal navigation hrefs now use `resolve()` from `$app/paths` for proper SPA routing.
- **Tailwind fuchsia ring safelist**: Added `ring-fuchsia-*` pattern to Tailwind safelist for loyalty stamp theming.
- **Vite WASM support**: `vite.config.ts` configured to include `.wasm` files as assets and exclude JSquash/Discourse encoder packages from dependency optimization.
- **NavBar enhancements**: admin links reordered (Today/Schedule promoted), unread notification badge on mobile burger icon, backdrop overlay + slide transition for mobile menu
- **TodayCalendar improvements**: fetches working/available hours for full week range instead of single day, closing time indicator on timeline, skips lunch suggestion for short days (5h or less)
- **Lunch protection refinement**: `shouldApplyLunchProtection()` skips lunch protection for days with 5 or fewer working hours