Initial commit - Black Canyon Tickets whitelabel platform
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
144
supabase/migrations/010_add_scanner_lock.sql
Normal file
144
supabase/migrations/010_add_scanner_lock.sql
Normal file
@@ -0,0 +1,144 @@
|
||||
-- Add scanner lock functionality to events table
|
||||
-- This migration adds support for locking scanner devices to scan-only mode
|
||||
|
||||
-- Add scanner lock fields to events table
|
||||
ALTER TABLE events ADD COLUMN scanner_lock_enabled BOOLEAN DEFAULT FALSE;
|
||||
ALTER TABLE events ADD COLUMN scanner_pin_hash TEXT;
|
||||
ALTER TABLE events ADD COLUMN scanner_lock_created_at TIMESTAMP WITH TIME ZONE;
|
||||
ALTER TABLE events ADD COLUMN scanner_lock_created_by UUID REFERENCES users(id);
|
||||
|
||||
-- Create scanner_unlock_attempts table for audit logging
|
||||
CREATE TABLE scanner_unlock_attempts (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
event_id UUID NOT NULL REFERENCES events(id) ON DELETE CASCADE,
|
||||
attempted_by UUID REFERENCES users(id),
|
||||
attempt_result TEXT NOT NULL CHECK (attempt_result IN ('SUCCESS', 'FAILED', 'INVALID_PIN')),
|
||||
ip_address TEXT,
|
||||
user_agent TEXT,
|
||||
device_info TEXT,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Add indexes for performance
|
||||
CREATE INDEX idx_scanner_unlock_attempts_event_id ON scanner_unlock_attempts(event_id);
|
||||
CREATE INDEX idx_scanner_unlock_attempts_created_at ON scanner_unlock_attempts(created_at);
|
||||
CREATE INDEX idx_scanner_unlock_attempts_result ON scanner_unlock_attempts(attempt_result);
|
||||
|
||||
-- Add RLS policies for scanner_unlock_attempts
|
||||
ALTER TABLE scanner_unlock_attempts ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- Policies for scanner_unlock_attempts
|
||||
CREATE POLICY "Users can view scanner unlock attempts in their organization" ON scanner_unlock_attempts
|
||||
FOR SELECT USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM users
|
||||
WHERE users.id = auth.uid()
|
||||
AND users.organization_id = (
|
||||
SELECT organization_id FROM events WHERE events.id = scanner_unlock_attempts.event_id
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
CREATE POLICY "Users can insert scanner unlock attempts in their organization" ON scanner_unlock_attempts
|
||||
FOR INSERT WITH CHECK (
|
||||
EXISTS (
|
||||
SELECT 1 FROM users
|
||||
WHERE users.id = auth.uid()
|
||||
AND users.organization_id = (
|
||||
SELECT organization_id FROM events WHERE events.id = scanner_unlock_attempts.event_id
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
-- Admin override policies (for users with admin privileges)
|
||||
CREATE POLICY "Admin can view all scanner unlock attempts" ON scanner_unlock_attempts
|
||||
FOR SELECT USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM users
|
||||
WHERE users.id = auth.uid()
|
||||
AND users.organization_id IS NULL
|
||||
)
|
||||
);
|
||||
|
||||
CREATE POLICY "Admin can manage all scanner unlock attempts" ON scanner_unlock_attempts
|
||||
FOR ALL USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM users
|
||||
WHERE users.id = auth.uid()
|
||||
AND users.organization_id IS NULL
|
||||
)
|
||||
);
|
||||
|
||||
-- Create function to clean up scanner lock when event ends
|
||||
CREATE OR REPLACE FUNCTION cleanup_expired_scanner_locks()
|
||||
RETURNS void AS $$
|
||||
BEGIN
|
||||
-- Disable scanner locks for events that ended more than 24 hours ago
|
||||
UPDATE events
|
||||
SET
|
||||
scanner_lock_enabled = FALSE,
|
||||
scanner_pin_hash = NULL,
|
||||
scanner_lock_created_at = NULL,
|
||||
scanner_lock_created_by = NULL
|
||||
WHERE
|
||||
scanner_lock_enabled = TRUE
|
||||
AND start_time < NOW() - INTERVAL '24 hours';
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
-- Create a function to be called when setting up scanner lock
|
||||
CREATE OR REPLACE FUNCTION setup_scanner_lock(
|
||||
p_event_id UUID,
|
||||
p_pin_hash TEXT
|
||||
) RETURNS BOOLEAN AS $$
|
||||
BEGIN
|
||||
-- Update the event with scanner lock settings
|
||||
UPDATE events
|
||||
SET
|
||||
scanner_lock_enabled = TRUE,
|
||||
scanner_pin_hash = p_pin_hash,
|
||||
scanner_lock_created_at = NOW(),
|
||||
scanner_lock_created_by = auth.uid()
|
||||
WHERE id = p_event_id;
|
||||
|
||||
-- Return true if update was successful
|
||||
RETURN FOUND;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
-- Create a function to verify scanner PIN
|
||||
CREATE OR REPLACE FUNCTION verify_scanner_pin(
|
||||
p_event_id UUID,
|
||||
p_pin_hash TEXT
|
||||
) RETURNS BOOLEAN AS $$
|
||||
DECLARE
|
||||
stored_hash TEXT;
|
||||
BEGIN
|
||||
-- Get the stored PIN hash
|
||||
SELECT scanner_pin_hash INTO stored_hash
|
||||
FROM events
|
||||
WHERE id = p_event_id AND scanner_lock_enabled = TRUE;
|
||||
|
||||
-- Return true if hashes match
|
||||
RETURN stored_hash = p_pin_hash;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
-- Create a function to disable scanner lock
|
||||
CREATE OR REPLACE FUNCTION disable_scanner_lock(
|
||||
p_event_id UUID
|
||||
) RETURNS BOOLEAN AS $$
|
||||
BEGIN
|
||||
-- Update the event to disable scanner lock
|
||||
UPDATE events
|
||||
SET
|
||||
scanner_lock_enabled = FALSE,
|
||||
scanner_pin_hash = NULL,
|
||||
scanner_lock_created_at = NULL,
|
||||
scanner_lock_created_by = NULL
|
||||
WHERE id = p_event_id;
|
||||
|
||||
-- Return true if update was successful
|
||||
RETURN FOUND;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
Reference in New Issue
Block a user