feat: Complete platform enhancement with multi-tenant architecture
Major additions: - Territory manager system with application workflow - Custom pricing and page builder with Craft.js - Enhanced Stripe Connect onboarding - CodeReadr QR scanning integration - Kiosk mode for venue sales - Super admin dashboard and analytics - MCP integration for AI-powered operations Infrastructure improvements: - Centralized API client and routing system - Enhanced authentication with organization context - Comprehensive theme management system - Advanced event management with custom tabs - Performance monitoring and accessibility features Database schema updates: - Territory management tables - Custom pages and pricing structures - Kiosk PIN system - Enhanced organization profiles - CodeReadr integration tables 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
186
supabase/migrations/20250109_codereadr_integration.sql
Normal file
186
supabase/migrations/20250109_codereadr_integration.sql
Normal file
@@ -0,0 +1,186 @@
|
||||
-- CodeREADr Integration Tables
|
||||
|
||||
-- Table to store CodeREADr configuration for each event
|
||||
CREATE TABLE codereadr_configs (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
event_id UUID NOT NULL REFERENCES events(id) ON DELETE CASCADE,
|
||||
organization_id UUID NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
||||
|
||||
-- CodeREADr API entities
|
||||
database_id TEXT NOT NULL,
|
||||
service_id TEXT NOT NULL,
|
||||
user_id TEXT NOT NULL,
|
||||
|
||||
-- Readable names for reference
|
||||
database_name TEXT NOT NULL,
|
||||
service_name TEXT NOT NULL,
|
||||
user_name TEXT NOT NULL,
|
||||
|
||||
-- Status and metadata
|
||||
status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'inactive', 'error')),
|
||||
last_sync_at TIMESTAMP WITH TIME ZONE,
|
||||
total_scans INTEGER DEFAULT 0,
|
||||
|
||||
-- Timestamps
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT now(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT now(),
|
||||
|
||||
-- Unique constraint to prevent multiple configs per event
|
||||
UNIQUE(event_id, organization_id)
|
||||
);
|
||||
|
||||
-- Table to store synchronized scans from CodeREADr
|
||||
CREATE TABLE codereadr_scans (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
codereadr_scan_id TEXT NOT NULL UNIQUE, -- CodeREADr's scan ID
|
||||
|
||||
-- Event and service references
|
||||
event_id UUID NOT NULL REFERENCES events(id) ON DELETE CASCADE,
|
||||
service_id TEXT NOT NULL,
|
||||
|
||||
-- Scan data
|
||||
ticket_uuid TEXT NOT NULL,
|
||||
scan_timestamp TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||
response TEXT, -- CodeREADr response data
|
||||
device_id TEXT,
|
||||
location JSONB, -- {latitude, longitude} if available
|
||||
|
||||
-- Sync metadata
|
||||
synced_at TIMESTAMP WITH TIME ZONE DEFAULT now(),
|
||||
webhook_processed BOOLEAN DEFAULT false,
|
||||
ticket_updated BOOLEAN DEFAULT false,
|
||||
error_message TEXT,
|
||||
|
||||
-- Index for quick lookups
|
||||
INDEX idx_codereadr_scans_event_id (event_id),
|
||||
INDEX idx_codereadr_scans_ticket_uuid (ticket_uuid),
|
||||
INDEX idx_codereadr_scans_timestamp (scan_timestamp),
|
||||
INDEX idx_codereadr_scans_service_id (service_id)
|
||||
);
|
||||
|
||||
-- Add scan_method column to existing tickets table to track how ticket was scanned
|
||||
ALTER TABLE tickets ADD COLUMN IF NOT EXISTS scan_method TEXT DEFAULT 'manual' CHECK (scan_method IN ('manual', 'qr', 'codereadr', 'api'));
|
||||
|
||||
-- Add scan_method column to existing scan_attempts table
|
||||
ALTER TABLE scan_attempts ADD COLUMN IF NOT EXISTS scan_method TEXT DEFAULT 'manual' CHECK (scan_method IN ('manual', 'qr', 'codereadr', 'api'));
|
||||
|
||||
-- Update existing scan attempts to have a scan_method
|
||||
UPDATE scan_attempts SET scan_method = 'qr' WHERE scan_method IS NULL;
|
||||
UPDATE tickets SET scan_method = 'qr' WHERE scan_method IS NULL AND checked_in = true;
|
||||
|
||||
-- Add RLS policies for codereadr_configs table
|
||||
ALTER TABLE codereadr_configs ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- Users can only access configs for their organization
|
||||
CREATE POLICY "Users can view codereadr_configs for their organization" ON codereadr_configs
|
||||
FOR SELECT USING (
|
||||
organization_id IN (
|
||||
SELECT organization_id FROM users WHERE id = auth.uid()
|
||||
)
|
||||
);
|
||||
|
||||
CREATE POLICY "Users can insert codereadr_configs for their organization" ON codereadr_configs
|
||||
FOR INSERT WITH CHECK (
|
||||
organization_id IN (
|
||||
SELECT organization_id FROM users WHERE id = auth.uid()
|
||||
)
|
||||
);
|
||||
|
||||
CREATE POLICY "Users can update codereadr_configs for their organization" ON codereadr_configs
|
||||
FOR UPDATE USING (
|
||||
organization_id IN (
|
||||
SELECT organization_id FROM users WHERE id = auth.uid()
|
||||
)
|
||||
);
|
||||
|
||||
CREATE POLICY "Users can delete codereadr_configs for their organization" ON codereadr_configs
|
||||
FOR DELETE USING (
|
||||
organization_id IN (
|
||||
SELECT organization_id FROM users WHERE id = auth.uid()
|
||||
)
|
||||
);
|
||||
|
||||
-- Admin bypass for codereadr_configs
|
||||
CREATE POLICY "Admins can manage all codereadr_configs" ON codereadr_configs
|
||||
FOR ALL USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM users
|
||||
WHERE id = auth.uid()
|
||||
AND role = 'admin'
|
||||
)
|
||||
);
|
||||
|
||||
-- Add RLS policies for codereadr_scans table
|
||||
ALTER TABLE codereadr_scans ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- Users can only access scans for events in their organization
|
||||
CREATE POLICY "Users can view codereadr_scans for their organization" ON codereadr_scans
|
||||
FOR SELECT USING (
|
||||
event_id IN (
|
||||
SELECT e.id FROM events e
|
||||
JOIN users u ON e.organization_id = u.organization_id
|
||||
WHERE u.id = auth.uid()
|
||||
)
|
||||
);
|
||||
|
||||
CREATE POLICY "Users can insert codereadr_scans for their organization" ON codereadr_scans
|
||||
FOR INSERT WITH CHECK (
|
||||
event_id IN (
|
||||
SELECT e.id FROM events e
|
||||
JOIN users u ON e.organization_id = u.organization_id
|
||||
WHERE u.id = auth.uid()
|
||||
)
|
||||
);
|
||||
|
||||
-- Admin bypass for codereadr_scans
|
||||
CREATE POLICY "Admins can manage all codereadr_scans" ON codereadr_scans
|
||||
FOR ALL USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM users
|
||||
WHERE id = auth.uid()
|
||||
AND role = 'admin'
|
||||
)
|
||||
);
|
||||
|
||||
-- Add indexes for better performance
|
||||
CREATE INDEX IF NOT EXISTS idx_codereadr_configs_event_id ON codereadr_configs(event_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_codereadr_configs_organization_id ON codereadr_configs(organization_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_codereadr_configs_status ON codereadr_configs(status);
|
||||
|
||||
-- Add function to automatically update updated_at timestamp
|
||||
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
NEW.updated_at = now();
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ language 'plpgsql';
|
||||
|
||||
-- Add trigger for codereadr_configs updated_at
|
||||
CREATE TRIGGER update_codereadr_configs_updated_at
|
||||
BEFORE UPDATE ON codereadr_configs
|
||||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
-- Add useful views for reporting
|
||||
CREATE VIEW codereadr_scan_summary AS
|
||||
SELECT
|
||||
c.event_id,
|
||||
c.organization_id,
|
||||
c.database_name,
|
||||
c.service_name,
|
||||
c.status,
|
||||
c.last_sync_at,
|
||||
COUNT(s.id) as total_scans,
|
||||
COUNT(CASE WHEN s.ticket_updated = true THEN 1 END) as successful_checkins,
|
||||
COUNT(CASE WHEN s.webhook_processed = true THEN 1 END) as webhook_scans,
|
||||
MAX(s.scan_timestamp) as latest_scan_time
|
||||
FROM codereadr_configs c
|
||||
LEFT JOIN codereadr_scans s ON c.event_id = s.event_id
|
||||
GROUP BY c.event_id, c.organization_id, c.database_name, c.service_name, c.status, c.last_sync_at;
|
||||
|
||||
-- Add RLS to the view
|
||||
ALTER VIEW codereadr_scan_summary SET (security_invoker = true);
|
||||
|
||||
COMMENT ON TABLE codereadr_configs IS 'Configuration for CodeREADr integration per event';
|
||||
COMMENT ON TABLE codereadr_scans IS 'Synchronized scan records from CodeREADr';
|
||||
COMMENT ON VIEW codereadr_scan_summary IS 'Summary view of CodeREADr scan statistics per event';
|
||||
Reference in New Issue
Block a user