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:
2025-07-12 18:21:40 -06:00
parent a02d64a86c
commit 26a87d0d00
232 changed files with 33175 additions and 5365 deletions

View 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';