Commitc25b47b
fix(deploy): remove duplicate drizzle/0000_init.sql at same ordinal as 0000_initial.sql
fix(deploy): remove duplicate drizzle/0000_init.sql at same ordinal as 0000_initial.sql migrate.ts sorts lexicographically, so `_init` ran before `_initial` and defined the same tables with IF NOT EXISTS — except `_init` has no `--> statement-breakpoint` markers, so the whole file became one multi-statement blob and Neon's HTTP sql() rejected it. `0000_initial.sql` (drizzle-kit-generated, has breakpoints, matches src/db/schema.ts byte-for-byte) is the canonical initial migration and stays. On any DB that already applied `0000_init.sql` the row remains in `_migrations` as a harmless ghost; `0000_initial.sql` then runs and IF NOT EXISTS no-ops everything it already created.
1 file changed+0−177c25b47b70177fd34f789b937df8bdd1e4596b19d
1 changed file+0−195
Deleteddrizzle/0000_init.sql+0−195View fileUnifiedSplit
@@ -1,195 +0,0 @@
1
2CREATE EXTENSION IF NOT EXISTS "pgcrypto";
3
4CREATE TABLE IF NOT EXISTS users (
5 id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
6 username TEXT NOT NULL UNIQUE,
7 email TEXT NOT NULL UNIQUE,
8 display_name TEXT,
9 password_hash TEXT NOT NULL,
10 avatar_url TEXT,
11 bio TEXT,
12 created_at TIMESTAMP DEFAULT NOW() NOT NULL,
13 updated_at TIMESTAMP DEFAULT NOW() NOT NULL
14);
15
16CREATE TABLE IF NOT EXISTS sessions (
17 id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
18 user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
19 token TEXT NOT NULL UNIQUE,
20 expires_at TIMESTAMP NOT NULL,
21 created_at TIMESTAMP DEFAULT NOW() NOT NULL
22);
23
24CREATE TABLE IF NOT EXISTS repositories (
25 id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
26 name TEXT NOT NULL,
27 owner_id UUID NOT NULL REFERENCES users(id),
28 description TEXT,
29 is_private BOOLEAN DEFAULT FALSE NOT NULL,
30 default_branch TEXT DEFAULT 'main' NOT NULL,
31 disk_path TEXT NOT NULL,
32 forked_from_id UUID REFERENCES repositories(id) ON DELETE SET NULL,
33 created_at TIMESTAMP DEFAULT NOW() NOT NULL,
34 updated_at TIMESTAMP DEFAULT NOW() NOT NULL,
35 pushed_at TIMESTAMP,
36 star_count INTEGER DEFAULT 0 NOT NULL,
37 fork_count INTEGER DEFAULT 0 NOT NULL,
38 issue_count INTEGER DEFAULT 0 NOT NULL
39);
40CREATE UNIQUE INDEX IF NOT EXISTS repos_owner_name ON repositories(owner_id, name);
41
42CREATE TABLE IF NOT EXISTS stars (
43 id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
44 user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
45 repository_id UUID NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
46 created_at TIMESTAMP DEFAULT NOW() NOT NULL
47);
48CREATE UNIQUE INDEX IF NOT EXISTS stars_user_repo ON stars(user_id, repository_id);
49
50CREATE TABLE IF NOT EXISTS issues (
51 id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
52 number SERIAL,
53 repository_id UUID NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
54 author_id UUID NOT NULL REFERENCES users(id),
55 title TEXT NOT NULL,
56 body TEXT,
57 state TEXT NOT NULL DEFAULT 'open',
58 created_at TIMESTAMP DEFAULT NOW() NOT NULL,
59 updated_at TIMESTAMP DEFAULT NOW() NOT NULL,
60 closed_at TIMESTAMP
61);
62CREATE INDEX IF NOT EXISTS issues_repo_state ON issues(repository_id, state);
63CREATE INDEX IF NOT EXISTS issues_repo_number ON issues(repository_id, number);
64
65CREATE TABLE IF NOT EXISTS issue_comments (
66 id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
67 issue_id UUID NOT NULL REFERENCES issues(id) ON DELETE CASCADE,
68 author_id UUID NOT NULL REFERENCES users(id),
69 body TEXT NOT NULL,
70 created_at TIMESTAMP DEFAULT NOW() NOT NULL,
71 updated_at TIMESTAMP DEFAULT NOW() NOT NULL
72);
73CREATE INDEX IF NOT EXISTS comments_issue ON issue_comments(issue_id);
74
75CREATE TABLE IF NOT EXISTS labels (
76 id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
77 repository_id UUID NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
78 name TEXT NOT NULL,
79 color TEXT NOT NULL DEFAULT '#8b949e',
80 description TEXT
81);
82CREATE UNIQUE INDEX IF NOT EXISTS labels_repo_name ON labels(repository_id, name);
83
84CREATE TABLE IF NOT EXISTS issue_labels (
85 id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
86 issue_id UUID NOT NULL REFERENCES issues(id) ON DELETE CASCADE,
87 label_id UUID NOT NULL REFERENCES labels(id) ON DELETE CASCADE
88);
89CREATE UNIQUE INDEX IF NOT EXISTS issue_labels_unique ON issue_labels(issue_id, label_id);
90
91CREATE TABLE IF NOT EXISTS pull_requests (
92 id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
93 number SERIAL,
94 repository_id UUID NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
95 author_id UUID NOT NULL REFERENCES users(id),
96 title TEXT NOT NULL,
97 body TEXT,
98 state TEXT NOT NULL DEFAULT 'open',
99 base_branch TEXT NOT NULL,
100 head_branch TEXT NOT NULL,
101 merged_at TIMESTAMP,
102 merged_by UUID REFERENCES users(id),
103 created_at TIMESTAMP DEFAULT NOW() NOT NULL,
104 updated_at TIMESTAMP DEFAULT NOW() NOT NULL,
105 closed_at TIMESTAMP
106);
107CREATE INDEX IF NOT EXISTS prs_repo_state ON pull_requests(repository_id, state);
108CREATE INDEX IF NOT EXISTS prs_repo_number ON pull_requests(repository_id, number);
109
110CREATE TABLE IF NOT EXISTS pr_comments (
111 id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
112 pull_request_id UUID NOT NULL REFERENCES pull_requests(id) ON DELETE CASCADE,
113 author_id UUID NOT NULL REFERENCES users(id),
114 body TEXT NOT NULL,
115 is_ai_review BOOLEAN DEFAULT FALSE NOT NULL,
116 file_path TEXT,
117 line_number INTEGER,
118 created_at TIMESTAMP DEFAULT NOW() NOT NULL,
119 updated_at TIMESTAMP DEFAULT NOW() NOT NULL
120);
121CREATE INDEX IF NOT EXISTS pr_comments_pr ON pr_comments(pull_request_id);
122
123CREATE TABLE IF NOT EXISTS activity_feed (
124 id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
125 repository_id UUID NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
126 user_id UUID REFERENCES users(id),
127 action TEXT NOT NULL,
128 target_type TEXT,
129 target_id TEXT,
130 metadata TEXT,
131 created_at TIMESTAMP DEFAULT NOW() NOT NULL
132);
133CREATE INDEX IF NOT EXISTS activity_repo ON activity_feed(repository_id);
134CREATE INDEX IF NOT EXISTS activity_user ON activity_feed(user_id);
135
136CREATE TABLE IF NOT EXISTS webhooks (
137 id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
138 repository_id UUID NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
139 url TEXT NOT NULL,
140 secret TEXT,
141 events TEXT NOT NULL DEFAULT 'push',
142 is_active BOOLEAN DEFAULT TRUE NOT NULL,
143 last_delivered_at TIMESTAMP,
144 last_status INTEGER,
145 created_at TIMESTAMP DEFAULT NOW() NOT NULL
146);
147CREATE INDEX IF NOT EXISTS webhooks_repo ON webhooks(repository_id);
148
149CREATE TABLE IF NOT EXISTS api_tokens (
150 id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
151 user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
152 name TEXT NOT NULL,
153 token_hash TEXT NOT NULL,
154 token_prefix TEXT NOT NULL,
155 scopes TEXT NOT NULL DEFAULT 'repo',
156 last_used_at TIMESTAMP,
157 expires_at TIMESTAMP,
158 created_at TIMESTAMP DEFAULT NOW() NOT NULL
159);
160
161CREATE TABLE IF NOT EXISTS repo_topics (
162 id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
163 repository_id UUID NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
164 topic TEXT NOT NULL
165);
166CREATE UNIQUE INDEX IF NOT EXISTS repo_topics_unique ON repo_topics(repository_id, topic);
167CREATE INDEX IF NOT EXISTS topics_name ON repo_topics(topic);
168
169CREATE TABLE IF NOT EXISTS ssh_keys (
170 id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
171 user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
172 title TEXT NOT NULL,
173 fingerprint TEXT NOT NULL,
174 public_key TEXT NOT NULL,
175 last_used_at TIMESTAMP,
176 created_at TIMESTAMP DEFAULT NOW() NOT NULL
177);
1780