|
| 1 | +-- ============================================== |
| 2 | +-- CREATE TICKET SUPPORT TABLE |
| 3 | +-- Date: 2026-03-09 |
| 4 | +-- ============================================== |
| 5 | + |
| 6 | +-- 1. Create a sequence for the ticket number |
| 7 | +CREATE SEQUENCE IF NOT EXISTS ticket_number_seq START 1001; |
| 8 | + |
| 9 | +-- 2. Create the ticket_support table |
| 10 | +CREATE TABLE IF NOT EXISTS ticket_support ( |
| 11 | + id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), |
| 12 | + ticket_number TEXT UNIQUE NOT NULL, |
| 13 | + user_id UUID REFERENCES codev(id) ON DELETE SET NULL, |
| 14 | + full_name TEXT NOT NULL, |
| 15 | + email TEXT, |
| 16 | + role_position TEXT, |
| 17 | + project_id UUID REFERENCES project(id) ON DELETE SET NULL, |
| 18 | + assigned_team TEXT, |
| 19 | + ticket_type TEXT NOT NULL, |
| 20 | + other_type TEXT, |
| 21 | + subject TEXT, -- This will correspond to 'ticketTitle' from frontend |
| 22 | + message TEXT NOT NULL, -- This will correspond to 'ticketDetails' from frontend |
| 23 | + status TEXT NOT NULL DEFAULT 'PENDING' CHECK (status IN ('PENDING', 'OPEN', 'IN_PROGRESS', 'RESOLVED', 'CLOSED')), |
| 24 | + priority TEXT NOT NULL DEFAULT 'MEDIUM' CHECK (priority IN ('LOW', 'MEDIUM', 'HIGH', 'URGENT')), |
| 25 | + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), |
| 26 | + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() |
| 27 | +); |
| 28 | + |
| 29 | +-- 3. Create a function to generate the formatted ticket number |
| 30 | +CREATE OR REPLACE FUNCTION generate_ticket_number() |
| 31 | +RETURNS TRIGGER AS $$ |
| 32 | +BEGIN |
| 33 | + IF NEW.ticket_number IS NULL THEN |
| 34 | + NEW.ticket_number := 'TS-' || LPAD(nextval('ticket_number_seq')::text, 6, '0'); |
| 35 | + END IF; |
| 36 | + RETURN NEW; |
| 37 | +END; |
| 38 | +$$ LANGUAGE plpgsql; |
| 39 | + |
| 40 | +-- 4. Create the shared update_updated_at_column function if it doesn't exist |
| 41 | +CREATE OR REPLACE FUNCTION update_updated_at_column() |
| 42 | +RETURNS TRIGGER AS $$ |
| 43 | +BEGIN |
| 44 | + NEW.updated_at = NOW(); |
| 45 | + RETURN NEW; |
| 46 | +END; |
| 47 | +$$ language 'plpgsql'; |
| 48 | + |
| 49 | +-- 5. Create trigger to auto-generate ticket number before insert |
| 50 | +CREATE TRIGGER set_ticket_number |
| 51 | + BEFORE INSERT ON ticket_support |
| 52 | + FOR EACH ROW |
| 53 | + EXECUTE FUNCTION generate_ticket_number(); |
| 54 | + |
| 55 | +-- 6. Create trigger to update updated_at timestamp |
| 56 | +CREATE TRIGGER update_ticket_support_updated_at |
| 57 | + BEFORE UPDATE ON ticket_support |
| 58 | + FOR EACH ROW |
| 59 | + EXECUTE FUNCTION update_updated_at_column(); |
| 60 | + |
| 61 | +-- 7. Enable Row Level Security (RLS) |
| 62 | +ALTER TABLE ticket_support ENABLE ROW LEVEL SECURITY; |
| 63 | + |
| 64 | +-- 8. Define RLS Policies |
| 65 | + |
| 66 | +-- Policy: Authenticated users can create tickets |
| 67 | +CREATE POLICY "Authenticated users can create tickets" |
| 68 | + ON ticket_support FOR INSERT |
| 69 | + TO authenticated |
| 70 | + WITH CHECK (auth.uid() = user_id OR user_id IS NULL); |
| 71 | + |
| 72 | +-- Policy: Users can view their own tickets |
| 73 | +CREATE POLICY "Users can view own tickets" |
| 74 | + ON ticket_support FOR SELECT |
| 75 | + TO authenticated |
| 76 | + USING (auth.uid() = user_id); |
| 77 | + |
| 78 | +-- Policy: Admins can manage all tickets |
| 79 | +CREATE POLICY "Admins can manage all tickets" |
| 80 | + ON ticket_support FOR ALL |
| 81 | + TO authenticated |
| 82 | + USING ( |
| 83 | + EXISTS ( |
| 84 | + SELECT 1 FROM codev |
| 85 | + WHERE id = auth.uid() |
| 86 | + AND (internal_status = 'ADMIN' OR role_id IN (SELECT id FROM roles WHERE (name ILIKE '%admin%' OR name ILIKE '%super%'))) |
| 87 | + ) |
| 88 | + ); |
| 89 | + |
| 90 | +-- 8. Create Indexes for performance |
| 91 | +CREATE INDEX IF NOT EXISTS idx_ticket_support_ticket_number ON ticket_support(ticket_number); |
| 92 | +CREATE INDEX IF NOT EXISTS idx_ticket_support_user_id ON ticket_support(user_id); |
| 93 | +CREATE INDEX IF NOT EXISTS idx_ticket_support_status ON ticket_support(status); |
| 94 | +CREATE INDEX IF NOT EXISTS idx_ticket_support_created_at ON ticket_support(created_at); |
| 95 | + |
| 96 | +-- 9. Comment on table |
| 97 | +COMMENT ON TABLE ticket_support IS 'Stores support tickets submitted by users.'; |
0 commit comments