nxtgauge-backend-rust/crates/db/migrations_new/002_pricing_and_leads.up.sql

286 lines
11 KiB
MySQL
Raw Normal View History

-- ============================================================================
-- MIGRATION: Complete Schema Updates for Pricing & Lead Requests
-- ============================================================================
BEGIN;
-- ============================================================================
-- 1. Update pricing_packages table with new columns
-- ============================================================================
ALTER TABLE pricing_packages
DROP COLUMN IF EXISTS user_role_profile_id,
ADD COLUMN IF NOT EXISTS package_type VARCHAR(50) NOT NULL DEFAULT 'TRACECOIN_BUNDLE',
ADD COLUMN IF NOT EXISTS applicable_roles TEXT[] DEFAULT '{}',
ADD COLUMN IF NOT EXISTS tracecoins_amount INTEGER DEFAULT 0,
ADD COLUMN IF NOT EXISTS valid_from TIMESTAMPTZ,
ADD COLUMN IF NOT EXISTS valid_until TIMESTAMPTZ,
ADD COLUMN IF NOT EXISTS is_promotional BOOLEAN DEFAULT false;
-- Add index for package lookup
CREATE INDEX IF NOT EXISTS idx_pricing_packages_type ON pricing_packages(package_type);
-- ============================================================================
-- 2. Update payments table with new columns
-- ============================================================================
ALTER TABLE payments
ADD COLUMN IF NOT EXISTS package_id UUID,
ADD COLUMN IF NOT EXISTS razorpay_order_id VARCHAR(255),
ADD COLUMN IF NOT EXISTS razorpay_payment_id VARCHAR(255),
ADD COLUMN IF NOT EXISTS tracecoins_credited INTEGER DEFAULT 0,
ADD COLUMN IF NOT EXISTS verified_at TIMESTAMPTZ;
-- Add foreign key if not exists
ALTER TABLE payments
ADD CONSTRAINT payments_package_id_fkey
FOREIGN KEY (package_id) REFERENCES pricing_packages(id) ON DELETE SET NULL;
CREATE INDEX IF NOT EXISTS idx_payments_package_id ON payments(package_id);
CREATE INDEX IF NOT EXISTS idx_payments_razorpay_order_id ON payments(razorpay_order_id);
-- ============================================================================
-- 3. Create lead_requests table
-- ============================================================================
CREATE TABLE IF NOT EXISTS lead_requests (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
lead_id UUID NOT NULL REFERENCES leads(id) ON DELETE CASCADE,
user_role_profile_id UUID NOT NULL REFERENCES user_role_profiles(id) ON DELETE CASCADE,
customer_user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
status VARCHAR(50) NOT NULL DEFAULT 'PENDING',
tracecoins_reserved INTEGER NOT NULL DEFAULT 25,
message TEXT,
expires_at TIMESTAMPTZ NOT NULL,
accepted_at TIMESTAMPTZ,
rejected_at TIMESTAMPTZ,
rejected_reason TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_lead_requests_lead_id ON lead_requests(lead_id);
CREATE INDEX IF NOT EXISTS idx_lead_requests_user_role_profile_id ON lead_requests(user_role_profile_id);
CREATE INDEX IF NOT EXISTS idx_lead_requests_customer_user_id ON lead_requests(customer_user_id);
CREATE INDEX IF NOT EXISTS idx_lead_requests_status ON lead_requests(status);
CREATE INDEX IF NOT EXISTS idx_lead_requests_expires_at ON lead_requests(expires_at);
-- ============================================================================
-- 4. Add display_code to company_profiles
-- ============================================================================
ALTER TABLE company_profiles
ADD COLUMN IF NOT EXISTS display_code VARCHAR(20) UNIQUE;
-- ============================================================================
-- 5. Add display_code to customer_profiles
-- ============================================================================
ALTER TABLE customer_profiles
ADD COLUMN IF NOT EXISTS display_code VARCHAR(20) UNIQUE;
-- ============================================================================
-- 6. Add display_code to job_seeker_profiles
-- ============================================================================
ALTER TABLE job_seeker_profiles
ADD COLUMN IF NOT EXISTS display_code VARCHAR(20) UNIQUE;
-- ============================================================================
-- 7. Add free_requirement_slots and purchased_requirement_slots to customer_profiles
-- ============================================================================
ALTER TABLE customer_profiles
ADD COLUMN IF NOT EXISTS free_requirement_slots INTEGER DEFAULT 2,
ADD COLUMN IF NOT EXISTS purchased_requirement_slots INTEGER DEFAULT 0;
-- ============================================================================
-- 8. Update leads table with new columns
-- ============================================================================
ALTER TABLE leads
ADD COLUMN IF NOT EXISTS customer_user_id UUID REFERENCES users(id),
ADD COLUMN IF NOT EXISTS max_acceptances INTEGER DEFAULT 10,
ADD COLUMN IF NOT EXISTS current_acceptances INTEGER DEFAULT 0,
ADD COLUMN IF NOT EXISTS expires_at TIMESTAMPTZ,
ADD COLUMN IF NOT EXISTS cover_image_url TEXT;
-- ============================================================================
-- 9. Add tracecoins_reserved column to lead_requests for proper tracking
-- ============================================================================
-- Already added in step 3
-- ============================================================================
-- 10. Create function to auto-generate display codes
-- ============================================================================
CREATE OR REPLACE FUNCTION generate_display_code(prefix VARCHAR(10))
RETURNS VARCHAR(20) AS $$
DECLARE
new_code VARCHAR(20);
seq_num INTEGER;
BEGIN
-- Get the next sequence number for this prefix
SELECT COALESCE(
(SELECT MAX(CAST(SUBSTRING(code FROM 4) AS INTEGER)) + 1
FROM (
SELECT display_code as code FROM company_profiles WHERE display_code LIKE prefix || '%'
UNION ALL
SELECT display_code as code FROM customer_profiles WHERE display_code LIKE prefix || '%'
UNION ALL
SELECT display_code as code FROM job_seeker_profiles WHERE display_code LIKE prefix || '%'
) all_codes
),
1
) INTO seq_num;
new_code := prefix || LPAD(seq_num::TEXT, 4, '0');
RETURN new_code;
END;
$$ LANGUAGE plpgsql;
-- ============================================================================
-- 11. Create indexes for performance
-- ============================================================================
CREATE INDEX IF NOT EXISTS idx_leads_customer_user_id ON leads(customer_user_id);
CREATE INDEX IF NOT EXISTS idx_leads_status_expires ON leads(status, expires_at);
CREATE INDEX IF NOT EXISTS idx_user_role_profiles_role_key ON user_role_profiles(role_key);
-- ============================================================================
-- 12. Create tracecoin ledger entry types enum support
-- ============================================================================
-- Add transaction_type values for ledger tracking
-- The ledger already has 'type' column, ensure we have proper entries
-- ============================================================================
-- 13. Add indexes for verification queries
-- ============================================================================
CREATE INDEX IF NOT EXISTS idx_verifications_user_role_profile_id ON verifications(user_role_profile_id);
CREATE INDEX IF NOT EXISTS idx_verifications_status ON verifications(status);
CREATE INDEX IF NOT EXISTS idx_verification_requests_user_role_profile_id ON verification_requests(user_role_profile_id);
-- ============================================================================
-- 14. Add tracecoin refund support to ledger
-- ============================================================================
-- Reserve tracecoins for lead request
CREATE OR REPLACE FUNCTION reserve_tracecoins_for_lead_request(
p_user_id UUID,
p_amount INTEGER,
p_lead_request_id UUID
) RETURNS BOOLEAN AS $$
DECLARE
v_wallet_id UUID;
v_balance BIGINT;
BEGIN
-- Get wallet
SELECT id, balance INTO v_wallet_id, v_balance
FROM tracecoin_wallets
WHERE user_id = p_user_id
FOR UPDATE;
IF v_wallet_id IS NULL THEN
RETURN FALSE;
END IF;
IF v_balance < p_amount THEN
RETURN FALSE;
END IF;
-- Deduct from balance (reserved, not yet spent)
UPDATE tracecoin_wallets
SET balance = balance - p_amount,
reserved = COALESCE(reserved, 0) + p_amount,
updated_at = NOW()
WHERE id = v_wallet_id;
-- Add ledger entry
INSERT INTO tracecoin_ledger (wallet_id, type, amount, balance_after, reference_type, reference_id, reason)
VALUES (v_wallet_id, 'RESERVE', -p_amount, v_balance - p_amount, 'LEAD_REQUEST', p_lead_request_id, 'Lead request reservation');
RETURN TRUE;
END;
$$ LANGUAGE plpgsql;
-- Confirm tracecoins (when customer accepts)
CREATE OR REPLACE FUNCTION confirm_tracecoins_for_lead(
p_user_id UUID,
p_amount INTEGER,
p_lead_request_id UUID
) RETURNS BOOLEAN AS $$
DECLARE
v_wallet_id UUID;
v_balance BIGINT;
BEGIN
-- Get wallet
SELECT id, balance, COALESCE(reserved, 0) INTO v_wallet_id, v_balance, v_balance
FROM tracecoin_wallets
WHERE user_id = p_user_id
FOR UPDATE;
IF v_wallet_id IS NULL THEN
RETURN FALSE;
END IF;
-- Move from reserved to spent
UPDATE tracecoin_wallets
SET reserved = reserved - p_amount,
updated_at = NOW()
WHERE id = v_wallet_id;
-- Add ledger entry for confirmation
INSERT INTO tracecoin_ledger (wallet_id, type, amount, balance_after, reference_type, reference_id, reason)
VALUES (v_wallet_id, 'SPEND', -p_amount, v_balance, 'LEAD_REQUEST', p_lead_request_id, 'Lead request accepted');
RETURN TRUE;
END;
$$ LANGUAGE plpgsql;
-- Release tracecoins (when customer rejects or request expires)
CREATE OR REPLACE FUNCTION release_tracecoins_for_lead(
p_user_id UUID,
p_amount INTEGER,
p_lead_request_id UUID
) RETURNS BOOLEAN AS $$
DECLARE
v_wallet_id UUID;
v_balance BIGINT;
BEGIN
-- Get wallet
SELECT id, balance INTO v_wallet_id, v_balance
FROM tracecoin_wallets
WHERE user_id = p_user_id
FOR UPDATE;
IF v_wallet_id IS NULL THEN
RETURN FALSE;
END IF;
-- Return to available balance from reserved
UPDATE tracecoin_wallets
SET balance = balance + p_amount,
reserved = reserved - p_amount,
updated_at = NOW()
WHERE id = v_wallet_id;
-- Add ledger entry for release
INSERT INTO tracecoin_ledger (wallet_id, type, amount, balance_after, reference_type, reference_id, reason)
VALUES (v_wallet_id, 'RELEASE', p_amount, v_balance + p_amount, 'LEAD_REQUEST', p_lead_request_id, 'Lead request rejected/expired');
RETURN TRUE;
END;
$$ LANGUAGE plpgsql;
-- ============================================================================
-- 15. Update tracecoin_wallets to have reserved column
-- ============================================================================
ALTER TABLE tracecoin_wallets
ADD COLUMN IF NOT EXISTS reserved BIGINT DEFAULT 0;
COMMIT;