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
This commit is contained in:
@@ -38,6 +38,7 @@ CREATE TABLE IF NOT EXISTS bottles (
|
||||
abv DECIMAL,
|
||||
age INTEGER,
|
||||
status TEXT DEFAULT 'sealed' CHECK (status IN ('sealed', 'open', 'sampled', 'empty')),
|
||||
processing_status TEXT DEFAULT 'complete' CHECK (processing_status IN ('pending', 'analyzing', 'complete', 'error')),
|
||||
whiskybase_id TEXT,
|
||||
image_url TEXT,
|
||||
purchase_price DECIMAL(10, 2),
|
||||
@@ -415,3 +416,32 @@ SELECT
|
||||
(SELECT id FROM subscription_plans WHERE name = 'starter' LIMIT 1)
|
||||
FROM auth.users u
|
||||
ON CONFLICT (user_id) DO NOTHING;
|
||||
|
||||
-- ============================================
|
||||
-- Buddy Invites (Handshake Codes)
|
||||
-- ============================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS buddy_invites (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
creator_id UUID REFERENCES profiles(id) ON DELETE CASCADE NOT NULL,
|
||||
code TEXT NOT NULL UNIQUE, -- 6 char uppercase alphanumeric
|
||||
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('Europe/Berlin'::text, now())
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_buddy_invites_code ON buddy_invites(code);
|
||||
CREATE INDEX IF NOT EXISTS idx_buddy_invites_creator_id ON buddy_invites(creator_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_buddy_invites_expires_at ON buddy_invites(expires_at);
|
||||
|
||||
ALTER TABLE buddy_invites ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- Only creator can see their own invites
|
||||
DROP POLICY IF EXISTS "buddy_invites_creator_policy" ON buddy_invites;
|
||||
CREATE POLICY "buddy_invites_creator_policy" ON buddy_invites
|
||||
FOR ALL USING ((SELECT auth.uid()) = creator_id);
|
||||
|
||||
-- Allow anyone to SELECT by code (needed for redemption) but only if not expired
|
||||
DROP POLICY IF EXISTS "buddy_invites_redeem_policy" ON buddy_invites;
|
||||
CREATE POLICY "buddy_invites_redeem_policy" ON buddy_invites
|
||||
FOR SELECT USING (expires_at > now());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user