Files
pezkuwi-telegram-miniapp/supabase/migrations/20260208_deposit_system.sql
T

97 lines
3.2 KiB
PL/PgSQL

-- Deposit System Tables
-- For USDT deposits (TRC20 and Polkadot)
-- User deposit codes (unique memo for each user)
CREATE TABLE IF NOT EXISTS tg_user_deposit_codes (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES tg_users(id) ON DELETE CASCADE,
code VARCHAR(12) NOT NULL UNIQUE,
created_at TIMESTAMPTZ DEFAULT NOW(),
CONSTRAINT unique_user_deposit_code UNIQUE (user_id)
);
-- Deposit records
CREATE TABLE IF NOT EXISTS tg_deposits (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES tg_users(id) ON DELETE CASCADE,
network VARCHAR(20) NOT NULL CHECK (network IN ('trc20', 'polkadot')),
amount DECIMAL(20, 6) NOT NULL,
tx_hash VARCHAR(100),
memo VARCHAR(50),
status VARCHAR(20) NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'confirming', 'completed', 'failed', 'expired')),
wusdt_tx_hash VARCHAR(100),
error_message TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
confirmed_at TIMESTAMPTZ,
processed_at TIMESTAMPTZ
);
-- Indexes
CREATE INDEX IF NOT EXISTS idx_deposits_user_id ON tg_deposits(user_id);
CREATE INDEX IF NOT EXISTS idx_deposits_status ON tg_deposits(status);
CREATE INDEX IF NOT EXISTS idx_deposits_network ON tg_deposits(network);
CREATE INDEX IF NOT EXISTS idx_deposits_tx_hash ON tg_deposits(tx_hash);
CREATE INDEX IF NOT EXISTS idx_deposit_codes_code ON tg_user_deposit_codes(code);
-- Function to generate unique deposit code
CREATE OR REPLACE FUNCTION generate_deposit_code()
RETURNS VARCHAR(12) AS $$
DECLARE
chars VARCHAR(36) := 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
result VARCHAR(12) := 'PEZ-';
i INTEGER;
BEGIN
FOR i IN 1..8 LOOP
result := result || substr(chars, floor(random() * length(chars) + 1)::integer, 1);
END LOOP;
RETURN result;
END;
$$ LANGUAGE plpgsql;
-- Trigger to auto-generate deposit code for new users
CREATE OR REPLACE FUNCTION create_user_deposit_code()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO tg_user_deposit_codes (user_id, code)
VALUES (NEW.id, generate_deposit_code())
ON CONFLICT (user_id) DO NOTHING;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS trigger_create_deposit_code ON tg_users;
CREATE TRIGGER trigger_create_deposit_code
AFTER INSERT ON tg_users
FOR EACH ROW
EXECUTE FUNCTION create_user_deposit_code();
-- Generate codes for existing users
INSERT INTO tg_user_deposit_codes (user_id, code)
SELECT id, generate_deposit_code()
FROM tg_users
WHERE id NOT IN (SELECT user_id FROM tg_user_deposit_codes)
ON CONFLICT DO NOTHING;
-- RLS Policies
ALTER TABLE tg_user_deposit_codes ENABLE ROW LEVEL SECURITY;
ALTER TABLE tg_deposits ENABLE ROW LEVEL SECURITY;
-- Users can read their own deposit code
CREATE POLICY "Users can view own deposit code"
ON tg_user_deposit_codes FOR SELECT
USING (auth.uid() = user_id);
-- Users can view their own deposits
CREATE POLICY "Users can view own deposits"
ON tg_deposits FOR SELECT
USING (auth.uid() = user_id);
-- Service role can do everything (for backend)
CREATE POLICY "Service role full access to deposit codes"
ON tg_user_deposit_codes FOR ALL
USING (auth.role() = 'service_role');
CREATE POLICY "Service role full access to deposits"
ON tg_deposits FOR ALL
USING (auth.role() = 'service_role');