Commit Graph

145 Commits

Author SHA1 Message Date
02bd025bce feat: Enhanced registration with username, name, and auto-subscription
Registration form now includes:
- Username field (required, unique, validated)
- Full name field (optional)
- Auto-validates username format and availability
- Auto-creates 'starter' subscription on signup

Login form unchanged (email + password only)
2025-12-26 22:52:47 +01:00
73a057b1e3 feat: Hide tutorial on login, add 'Angemeldet bleiben' checkbox
- OnboardingTutorial: Skip on /login, /auth, /register paths
- AuthForm: Added remember-me checkbox (default: checked)
- Session persistence based on checkbox selection
2025-12-26 22:46:22 +01:00
1017ec2c57 fix: Add Glengyle distillery (producer of Kilkerran)
Glengyle is the actual distillery name, Kilkerran is the brand.
AI returns 'Glengyle' which was being mismatched to 'Glenglassaugh'.
2025-12-26 22:34:49 +01:00
e3d61af40a fix: Make distillery fuzzy matching stricter
- Threshold: 0.25 (was 0.4)
- Score check: 0.3 (was 0.5)
- minMatchCharLength: 4 (was 3)

Prevents false positives like 'Kilkeran' → 'Glenglassaugh'
2025-12-26 22:30:59 +01:00
883b2b61b4 feat: Add Fuse.js distillery name normalization
New: src/lib/distillery-matcher.ts
- normalizeDistillery(): Fuzzy matches AI responses against distilleries.json
- cleanBottleName(): Removes distillery from bottle name to avoid duplication
- normalizeWhiskyData(): Combined helper for both operations

Example transformations:
- 'ARDNAHOE DISTILLERY CO LTD' → 'Ardnahoe'
- 'Laphroaig 10 Year Old' → '10 Year Old' (with distillery in separate field)

Integration:
- gemini-vision.ts now normalizes results after AI response
- Enables consistent distillery names for enrichment cache
2025-12-26 22:20:31 +01:00
daf6c86633 feat: Add distillery enrichment cache
Caches AI enrichment results per distillery to save API calls:
- New table: enrichment_cache (distillery, tags, hit_count)
- New service: cache-enrichment.ts (get, save, increment, stats)
- enrich-data.ts checks cache before AI query
- Saves to cache after successful AI response
- Returns cached: true/false flag for transparency

Benefits:
- 0 API cost for repeated distillery scans
- Near-instant response for cached distilleries
- Shared across all users
2025-12-26 22:12:27 +01:00
537081cd1f fix: Add 'use client' to impressum page for onClick handlers 2025-12-26 22:05:34 +01:00
e6278e5ec6 feat: Add footer with legal links (Impressum, Datenschutz, Einstellungen) 2025-12-26 22:02:00 +01:00
f1990ebf2d feat: Add bot-proof Impressum page
- Email displayed as user[at]domain with onClick handler
- Phone displayed split with dashes
- All contact info clickable but not easily scraped
- Ready to fill in at src/app/impressum/page.tsx
2025-12-26 21:58:37 +01:00
f21b2738ad feat: Add onboarding tutorial and improved empty states
Onboarding Tutorial:
- 5-step walkthrough for new users
- Welcome, Scan, Taste, Sessions, Ready steps
- Skippable, stores completion in localStorage
- Beautiful full-screen overlay with animations

Empty States:
- SessionList: Visual empty state with icon and description
- BuddyList: Visual empty state with icon and description
- Reusable EmptyState component ready for more usage

Layout: Added OnboardingTutorial and CookieBanner
2025-12-26 21:43:26 +01:00
82531c5aff feat: Add navigation labels and EmptyState component
Bottom Navigation:
- Added text labels under icons (Start, Sammlung, Filter, Profil)
- Elevated SCAN button with label
- Improved touch targets and visual hierarchy

EmptyState Component:
- Reusable component for empty lists
- Icon, title, description, optional CTA button
- Ready for use in SessionList, BuddyList, BottleGrid
2025-12-26 21:40:31 +01:00
af54d8061c fix: Use username field instead of display_name in profile
- Updated profile-actions.ts to use username column
- Updated ProfileForm.tsx to use username
- Updated settings page to pass username
- Matches database schema (profiles.username)
2025-12-26 21:35:41 +01:00
f74090c8a5 feat: Link profile button to /settings page
- Added router.push('/settings') to onProfile handler
- User icon in bottom nav now navigates to settings
2025-12-26 21:33:36 +01:00
6c37481d17 feat: Add EU cookie banner and user settings page
Cookie Banner:
- GDPR-compliant consent banner
- Shows on first visit, stores consent in localStorage
- Two options: Accept All / Only Essential
- Dark theme with smooth animations

Settings Page (/settings):
- Profile form: display name editing
- Password change with validation
- Cookie settings info section
- Privacy links and account info

New files:
- src/hooks/useCookieConsent.ts
- src/components/CookieBanner.tsx
- src/components/ProfileForm.tsx
- src/components/PasswordChangeForm.tsx
- src/services/profile-actions.ts
- src/app/settings/page.tsx
2025-12-26 21:30:00 +01:00
9c5f538efb refactor: Consolidate all AI calls to use OpenRouter provider switch
- bulk-scan.ts: Now uses OpenRouter for batch analysis
- scan-label.ts: Now uses OpenRouter with Gemini fallback
- analyze-bottle.ts: Now uses OpenRouter with Gemini fallback
- All AI calls now respect AI_PROVIDER env variable
- Uses Nebius/FP8 provider preferences consistently
- Unified logging: [FunctionName] Using provider: openrouter/gemini
2025-12-26 21:21:56 +01:00
e978499b54 feat: Switch enrichment to use OpenRouter provider
- enrichData now uses same AI provider switch as vision
- Both scan and enrichment use OpenRouter by default
- Added retry logic for rate limits
- Uses Nebius/FP8 provider preferences
- Logs which provider is being used
2025-12-26 00:16:48 +01:00
ce49c9e347 feat: Route OpenRouter requests via Nebius with FP8 quantization
- Added OPENROUTER_PROVIDER_PREFERENCES config
- Prioritizes Nebius provider for better availability/speed
- Uses FP8 quantization for quality/speed balance
- Falls back to other providers if Nebius unavailable
2025-12-26 00:12:42 +01:00
8cf51d4aea fix: Add retry logic for OpenRouter 429 rate limit errors
- Retries up to 3 times with exponential backoff (2s, 4s, 8s)
- Also handles 503 service unavailable errors
- Logs retry attempts for debugging
- Only retries rate limit errors, other errors fail immediately
2025-12-26 00:06:21 +01:00
8ccd600dcb feat: Instant editor opening with background AI analysis
- Editor opens immediately with placeholder data
- AI analyzes label in background while user can already edit
- Blue 'KI analysiert...' banner shows when AI is still working
- User edits preserved when AI results arrive (dirty field tracking)
- Model/provider shown in admin perf overlay
- Renamed 'CLOUD' to 'AI' in perf display
2025-12-26 00:02:38 +01:00
fb2a8d0f7b feat: Add OpenRouter as AI provider with easy switch
- Added openrouter.ts with provider configuration
- Default provider: OpenRouter with google/gemma-3-27b-it
- Switch to Gemini via AI_PROVIDER=gemini in .env.local
- Both providers use same credit system
- OpenRouter uses OpenAI-compatible API

To switch providers, set in .env.local:
AI_PROVIDER=openrouter  # default
AI_PROVIDER=gemini      # Google Gemini
2025-12-25 23:56:24 +01:00
f0f36e9c03 perf: Remove Tesseract OCR - saves ~45MB on mobile
- Removed Tesseract.js files from precache (~45MB)
- Scanner now uses only Gemini AI (more accurate, less data)
- Offline scans queued for later processing when online
- App download from ~50MB to ~5MB

BREAKING: Local offline OCR no longer available
Use Gemini AI instead (requires network for scanning)
2025-12-25 23:39:08 +01:00
462d27ea7b fix: Switch to @supabase/ssr for browser client
- Use createBrowserClient from @supabase/ssr instead of supabase-js
- Stores auth session in cookies (not localStorage) for SSR compatibility
- Server actions can now access authenticated user sessions
- Fixes 'Nicht autorisiert' error in split creation
2025-12-25 23:20:53 +01:00
2286867447 feat: Improve Bottle Split UX
- Add 'Split starten' button to bottle detail page
- Support flexible sample sizes (1-20cl) instead of fixed 5/10cl
- Preselect bottle when coming from bottle page
- Save sample sizes/shipping defaults to localStorage
- Update schema: sample_sizes JSONB array
- Update server actions and UI for dynamic sizes
2025-12-25 22:46:58 +01:00
0c7786db90 feat: Bottle Split System (Flaschenteilung)
- Add bottle_splits and split_participants tables with RLS
- Implement soft-lock: pending requests count as reserved
- Create /splits/create wizard (3 steps: bottle, pricing, shipping)
- Create /splits/[slug] public page with price calculator
- Create /splits/manage host dashboard with participant workflow
- Add SplitProgressBar component for visual volume display
- Status workflow: PENDING -> APPROVED -> PAID -> SHIPPED
- Forum export (BBCode format)
- Saved defaults in localStorage for glass/shipping costs
2025-12-25 22:36:38 +01:00
75461d7c30 feat: Buddy System & Bulk Scanner
- Add Buddy linking via QR code/handshake (buddy_invites table)
- Add Bulk Scanner for rapid-fire bottle scanning in sessions
- Add processing_status to bottles for background AI analysis
- Fix offline OCR with proper tessdata caching in Service Worker
- Fix Supabase GoTrueClient singleton warning
- Add collection refresh after offline sync completes

New components:
- BuddyHandshake.tsx - QR code display and code entry
- BulkScanSheet.tsx - Camera UI with capture queue
- BottleSkeletonCard.tsx - Pending bottle display
- useBulkScanner.ts - Queue management hook
- buddy-link.ts - Server actions for buddy linking
- bulk-scan.ts - Server actions for batch processing
2025-12-25 22:11:50 +01:00
afe9197776 feat: improved local OCR with Strip & Match distillery detection
- Added comprehensive distillery database (200+ entries)
- Implemented Strip & Match heuristic for fuzzy matching
- Added contextual age detection from distillery lines
- Added whitespace normalization for OCR text
- Disabled local name extraction (too noisy, let Gemini handle it)
- Fixed confidence scale normalization in TastingEditor (0-1 vs 0-100)
- Improved extractName filter (60% letters required)
- Relaxed Fuse.js thresholds for partial matches
2025-12-25 13:14:08 +01:00
a1a91795d1 feat: optimize scan OCR with sharp preprocessing and 1024px resizing 2025-12-24 00:02:58 +01:00
11275dd875 feat: unify tasting form refactor & align db schema status levels 2025-12-23 22:13:05 +01:00
6a41667f9c feat: refactor UploadQueue to floating bubble UI for mobile 2025-12-23 16:20:14 +01:00
c134c78a2c feat: improve AI resilience, add background enrichment loading states, and fix duplicate identifier in TagSelector 2025-12-23 11:38:16 +01:00
1d98bb9947 feat: log raw AI JSON response to browser console 2025-12-22 11:33:15 +01:00
83229e9c67 fix: ignore non-http schemes in service worker to prevent cache error 2025-12-22 10:46:50 +01:00
fd168fea0e feat: granular performance tracking and cache hit indicators for AI scans 2025-12-22 10:45:05 +01:00
7d06ba7a57 feat: robust FormData handling for AI services to improve N100 performance and stability 2025-12-22 10:36:26 +01:00
5e35710b67 feat: optimize scan flow with WebP compression and fix admin metrics visibility 2025-12-22 10:15:29 +01:00
f0588418c8 Industrial Dark UI Overhaul: Updated colors, typography, navigation, and component styling across the application 2025-12-22 00:05:31 +01:00
cf491d83b6 DramLog UI Overhaul: Rebranding, Navigation Improvements, and Scan Workflow Fixes
- Renamed app to DramLog and updated branding to Gold (#C89D46)
- Implemented new BottomNavigation with Floating Scan Button
- Fixed 'black screen' race condition in ScanAndTasteFlow
- Refactored TastingEditor and StatsDashboard for a cleaner editorial look
- Standardized colors and typography across the application
2025-12-21 23:41:33 +01:00
d83d2a8873 feat: enable gallery upload and update scanner button theme to amber 2025-12-21 22:45:07 +01:00
b57f5dc2ad feat: refine Scan & Taste UI, fix desktop scrolling, and resolve production login fetch error
- Reverted theme from gold to amber and restored legacy typography.
- Refactored ScanAndTasteFlow and TastingEditor for robust desktop scrolling.
- Hotfixed sw.js to completely bypass Supabase Auth/API requests to fix 'Failed to fetch' in production.
- Integrated full tasting note persistence (tags, buddies, sessions).
2025-12-21 22:29:16 +01:00
4e8af60488 fix: robust SW status tracking and polling for mobile production 2025-12-21 00:33:50 +01:00
ab8f0fe3ef fix: robust SW progress sync and startup delay 2025-12-21 00:21:01 +01:00
f0cb661d91 fix: enable SW on localhost and optimize pre-cache sequence for faster feedback 2025-12-21 00:18:38 +01:00
716afce2ae feat: move offline indicator to header, rename to Offline-Modus, and redesign tasting form 2025-12-21 00:13:33 +01:00
74a10b193c fix: mobile indicator visibility, sequential pre-cache, and verified ready state 2025-12-21 00:02:39 +01:00
000f2582a3 fix: optimize bunker loading and add progress feedback 2025-12-20 23:57:55 +01:00
b0a79541b6 feat: add Offline Mode Indicator (Bunker Status) 2025-12-20 23:51:16 +01:00
7d5091a139 fix: resolve pre-cache 404s and implement Bunker v7 with SWR 2025-12-20 23:44:37 +01:00
b2c8ef222f sw.js fixed 2 2025-12-20 23:33:50 +01:00
87856c87f0 sw.js fixed 2025-12-20 23:32:07 +01:00
8bafbf2ece feat: implement Paranoid Mode (SWR for Navigation) 2025-12-20 23:22:02 +01:00