File size: 6,732 Bytes
53e1531
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
-- Shortlist: Initial Database Schema
-- Phase 1 Migration

-- Enable UUID generation
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

-- ============================================================
-- TABLE: jd_analyses
-- Stores JD input text & AI-extracted analysis results
-- ============================================================
CREATE TABLE IF NOT EXISTS public.jd_analyses (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
    jd_text TEXT NOT NULL CHECK (char_length(jd_text) BETWEEN 50 AND 15000),
    role VARCHAR(200) NOT NULL,
    company_type VARCHAR(50) NOT NULL CHECK (company_type IN ('startup', 'mid_level', 'faang', 'research', 'enterprise')),
    geography VARCHAR(100),
    skill_profile JSONB,
    engineering_expectations JSONB,
    company_modifiers JSONB,
    status VARCHAR(20) NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'processing', 'completed', 'failed')),
    error_message TEXT,
    processing_time_ms INTEGER,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- ============================================================
-- TABLE: capstone_projects
-- Stores AI-generated capstone projects linked to an analysis
-- ============================================================
CREATE TABLE IF NOT EXISTS public.capstone_projects (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
    analysis_id UUID NOT NULL REFERENCES public.jd_analyses(id) ON DELETE CASCADE,
    title VARCHAR(300) NOT NULL,
    problem_statement TEXT NOT NULL,
    architecture TEXT,
    tech_stack JSONB NOT NULL DEFAULT '[]'::jsonb,
    complexity INTEGER NOT NULL CHECK (complexity BETWEEN 1 AND 5),
    resume_bullet TEXT,
    differentiator TEXT,
    is_selected BOOLEAN NOT NULL DEFAULT FALSE,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- ============================================================
-- TABLE: repo_analyses  (Phase 2 placeholder)
-- Stores GitHub repo analysis results
-- ============================================================
CREATE TABLE IF NOT EXISTS public.repo_analyses (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
    github_url VARCHAR(500) NOT NULL,
    scorecard JSONB,
    status VARCHAR(20) NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'processing', 'completed', 'failed')),
    error_message TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- ============================================================
-- INDEXES
-- ============================================================
CREATE INDEX IF NOT EXISTS idx_jd_analyses_user_id ON public.jd_analyses(user_id);
CREATE INDEX IF NOT EXISTS idx_jd_analyses_status ON public.jd_analyses(status);
CREATE INDEX IF NOT EXISTS idx_jd_analyses_created_at ON public.jd_analyses(created_at DESC);
CREATE INDEX IF NOT EXISTS idx_capstone_projects_user_id ON public.capstone_projects(user_id);
CREATE INDEX IF NOT EXISTS idx_capstone_projects_analysis_id ON public.capstone_projects(analysis_id);
CREATE INDEX IF NOT EXISTS idx_repo_analyses_user_id ON public.repo_analyses(user_id);

-- ============================================================
-- TRIGGER: auto-update updated_at on jd_analyses
-- ============================================================
CREATE OR REPLACE FUNCTION public.update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = NOW();
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS set_updated_at ON public.jd_analyses;
CREATE TRIGGER set_updated_at
    BEFORE UPDATE ON public.jd_analyses
    FOR EACH ROW
    EXECUTE FUNCTION public.update_updated_at_column();

-- ============================================================
-- ROW LEVEL SECURITY (RLS)
-- Users can only see/modify their own records
-- Service role bypasses RLS
-- ============================================================

-- jd_analyses RLS
ALTER TABLE public.jd_analyses ENABLE ROW LEVEL SECURITY;

DROP POLICY IF EXISTS "Users can view own JD analyses" ON public.jd_analyses;
CREATE POLICY "Users can view own JD analyses"
    ON public.jd_analyses FOR SELECT
    USING (auth.uid() = user_id);

DROP POLICY IF EXISTS "Users can insert own JD analyses" ON public.jd_analyses;
CREATE POLICY "Users can insert own JD analyses"
    ON public.jd_analyses FOR INSERT
    WITH CHECK (auth.uid() = user_id);

DROP POLICY IF EXISTS "Users can update own JD analyses" ON public.jd_analyses;
CREATE POLICY "Users can update own JD analyses"
    ON public.jd_analyses FOR UPDATE
    USING (auth.uid() = user_id);

DROP POLICY IF EXISTS "Service role full access jd_analyses" ON public.jd_analyses;
CREATE POLICY "Service role full access jd_analyses"
    ON public.jd_analyses FOR ALL
    USING (auth.jwt() ->> 'role' = 'service_role');

-- capstone_projects RLS
ALTER TABLE public.capstone_projects ENABLE ROW LEVEL SECURITY;

DROP POLICY IF EXISTS "Users can view own capstone projects" ON public.capstone_projects;
CREATE POLICY "Users can view own capstone projects"
    ON public.capstone_projects FOR SELECT
    USING (auth.uid() = user_id);

DROP POLICY IF EXISTS "Users can insert own capstone projects" ON public.capstone_projects;
CREATE POLICY "Users can insert own capstone projects"
    ON public.capstone_projects FOR INSERT
    WITH CHECK (auth.uid() = user_id);

DROP POLICY IF EXISTS "Users can update own capstone projects" ON public.capstone_projects;
CREATE POLICY "Users can update own capstone projects"
    ON public.capstone_projects FOR UPDATE
    USING (auth.uid() = user_id);

DROP POLICY IF EXISTS "Service role full access capstone_projects" ON public.capstone_projects;
CREATE POLICY "Service role full access capstone_projects"
    ON public.capstone_projects FOR ALL
    USING (auth.jwt() ->> 'role' = 'service_role');

-- repo_analyses RLS
ALTER TABLE public.repo_analyses ENABLE ROW LEVEL SECURITY;

DROP POLICY IF EXISTS "Users can view own repo analyses" ON public.repo_analyses;
CREATE POLICY "Users can view own repo analyses"
    ON public.repo_analyses FOR SELECT
    USING (auth.uid() = user_id);

DROP POLICY IF EXISTS "Users can insert own repo analyses" ON public.repo_analyses;
CREATE POLICY "Users can insert own repo analyses"
    ON public.repo_analyses FOR INSERT
    WITH CHECK (auth.uid() = user_id);

DROP POLICY IF EXISTS "Service role full access repo_analyses" ON public.repo_analyses;
CREATE POLICY "Service role full access repo_analyses"
    ON public.repo_analyses FOR ALL
    USING (auth.jwt() ->> 'role' = 'service_role');