- Moved OpenAI client initialization to a lazy getter function
- Added explicit check for NEBIUS_API_KEY in the getter
- Ensures Server Actions return structured errors instead of crashing when keys are missing
- Moved Supabase client initialization inside try-catch in Server Actions
- Added safety checks for null Supabase client in magicScan
- Added detailed server-side logging for debugging deployment issues
- Ensures all failure paths return a structured error response instead of 500
- Fixed undefined setTags in TagSelector.tsx
- Updated TagSelector to use Dexie cache for immediate UI updates
- Refined TastingList mapping to satisfy TypeScript interface
- Verified fix with a successful production build
- Migrated to Dexie.js for IndexedDB management
- Added optimistic UI for tasting notes with 'Wartet auf Sync' badge
- Implemented background caching for tags and buddies
- Unified scanning and tasting sync in a global UploadQueue
- Fixed data fetching in TastingNoteForm to include suggested_custom_tags
- Verified Nebius service compatibility with updated AI prompts
- Cleaned up artifacts and implementation plan
- AI now suggests dominant notes not in the system list (Part 3: Custom Suggestions)
- Updated TagSelector to show 'Neu anlegen?' buttons for AI-proposed custom tags
- Added suggested_custom_tags to bottles table and metadata schema
- Updated TastingNoteForm to handle both system and custom AI suggestions
- Implemented reusable TagSelector component with i18n support
- Added tag weighting system (popularity scores 1-5)
- Created admin panel for tag management
- Integrated Nebius AI and Brave Search for 'Magic Scan'
- Refactored app focus: removed bottle status, updated counters, and displayed extended bottle details
- Updated i18n for German and English
- Added database migration scripts
- Introduced shortenCategory utility to strip redundant terms from labels
- Refactored BottleGrid filters into a compact, collapsible layout
- Added filter count indicator and improved chip styling
- Fully localized new filter UI elements
- Applied strict RLS and auth validation to tracking/credit services
- Set Service Worker to Network First to fix mobile session/loading issues
- Expanded Gemini analysis summary to show distilled/bottled/batch info
- Updated SQL schema document with hardening policies
- Added distilled date, bottled date, and batch info to the analysis result summary in CameraCapture
- These fields now appear only if Gemini successfully identifies them from the photo
- Added 'Upload from Gallery' button to CameraCapture component
- Implemented secondary file input without 'capture' attribute to allow gallery selection on mobile
- Fixed overlapping header elements on mobile by making the header responsive
- Compacted 'Dram of the Day' button on small screens
- Added translations for the new gallery upload feature
- Fetched api_usage and profiles separately to avoid Supabase join errors when relationships are not explicitly defined in the schema cache.
- Updated Gemini AI tracking integration to ensure all calls are recorded correctly.
- Improved error handling in admin dashboard.
- Integrated API tracking into analyze-bottle service
- Added credit balance check before Gemini API calls
- Deduct credits after successful Gemini analysis
- Track both successful and failed Gemini API calls
- Added debug logging to admin dashboard for recent API calls
- Fixed error handling in analyze-bottle
Now tracks both Google Search and Gemini AI API usage!
- Added plan dropdown to user edit modal
- Shows current plan with highlighted card
- Allows admin to assign/change user's subscription plan
- Loads user's current plan when opening edit modal
- Updates plan via setUserPlan service
- Visual feedback with success/error messages
Admins can now:
- View user's current subscription plan
- Assign users to different plans (Starter, Bronze, Silver, Gold)
- See plan details (credits/month, price) in dropdown
This completes the subscription plan system!
- Database schema:
* subscription_plans table - stores plan tiers (Starter, Bronze, Silver, Gold)
* user_subscriptions table - assigns users to plans
* Default plans created (10, 50, 100, 250 credits/month)
* All existing users assigned to Starter plan
- Subscription service (subscription-service.ts):
* getAllPlans() - fetch all plans
* getActivePlans() - fetch active plans for users
* createPlan() - admin creates new plan
* updatePlan() - admin edits plan
* deletePlan() - admin removes plan
* getUserSubscription() - get user's current plan
* setUserPlan() - admin assigns user to plan
* grantMonthlyCredits() - distribute credits to all users
- Plan management interface (/admin/plans):
* Visual plan cards with credits, price, description
* Create/Edit/Delete plans
* Toggle active/inactive status
* Sort order management
* Grant monthly credits button (manual trigger)
- Features:
* Monthly credit allocation based on plan
* Prevents duplicate credit grants (tracks last_credit_grant_at)
* Admin can manually trigger monthly credit distribution
* Plans can be activated/deactivated
* Custom pricing and credit amounts per plan
- UI:
* Beautiful plan cards with color coding
* Modal for create/edit with validation
* Success/error messages
* Manage Plans button in admin dashboard
Ready for future automation (cron job for monthly credits)
and payment integration (Stripe/PayPal).