ework-web 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -2
- package/src/auth.ts +8 -8
- package/src/config.ts +2 -2
- package/src/db.ts +286 -49
- package/src/giteaApi.ts +53 -53
- package/src/index.ts +102 -101
- package/src/reactions.ts +2 -2
- package/src/schema-mysql.sql +178 -0
- package/src/schema.sql +40 -40
- package/src/store.ts +339 -379
- package/src/views/home.ts +10 -9
- package/src/views/issueList.ts +4 -4
- package/src/views/issueThread.ts +21 -21
- package/src/views/issues.ts +3 -3
- package/src/views/projectMembers.ts +8 -9
- package/src/views/projectUpstreams.ts +3 -3
- package/src/webhooks.ts +63 -73
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
-- ework schema (MySQL 8.0+ / MariaDB 10.5+). Applied idempotently on boot:
|
|
2
|
+
-- CREATE TABLE IF NOT EXISTS + CREATE INDEX (no IF NOT EXISTS — MySQL lacks it;
|
|
3
|
+
-- re-runs tolerate ER_DUP_KEYNAME 1061). FK constraint names are {{tokenized}}
|
|
4
|
+
-- so prefixed instances don't collide on constraint-name uniqueness. Date
|
|
5
|
+
-- columns are VARCHAR(40) holding ISO-8601 strings — the app formats dates in
|
|
6
|
+
-- JS, never SQL date arithmetic, so strings avoid Date-vs-string friction
|
|
7
|
+
-- across drivers. FK columns carry their own indexes (MySQL requirement). All
|
|
8
|
+
-- tables InnoDB + utf8mb4 for FK CASCADE + full Unicode (emoji).
|
|
9
|
+
|
|
10
|
+
CREATE TABLE IF NOT EXISTS {{users}} (
|
|
11
|
+
login VARCHAR(255) PRIMARY KEY,
|
|
12
|
+
kind VARCHAR(16) NOT NULL DEFAULT 'human'
|
|
13
|
+
CHECK (kind IN ('human','bot','system')),
|
|
14
|
+
display_name VARCHAR(255) DEFAULT NULL,
|
|
15
|
+
password_hash VARCHAR(255) DEFAULT NULL,
|
|
16
|
+
email VARCHAR(255) DEFAULT NULL,
|
|
17
|
+
is_admin TINYINT NOT NULL DEFAULT 0,
|
|
18
|
+
is_active TINYINT NOT NULL DEFAULT 1,
|
|
19
|
+
created_at VARCHAR(40) NOT NULL,
|
|
20
|
+
updated_at VARCHAR(40) NOT NULL DEFAULT ''
|
|
21
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
22
|
+
|
|
23
|
+
CREATE TABLE IF NOT EXISTS {{projects}} (
|
|
24
|
+
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
25
|
+
owner VARCHAR(255) NOT NULL,
|
|
26
|
+
name VARCHAR(255) NOT NULL,
|
|
27
|
+
description VARCHAR(2048) NOT NULL DEFAULT '',
|
|
28
|
+
upstream_urls VARCHAR(4096) NOT NULL DEFAULT '[]',
|
|
29
|
+
model VARCHAR(128) NOT NULL DEFAULT '',
|
|
30
|
+
created_at VARCHAR(40) NOT NULL,
|
|
31
|
+
updated_at VARCHAR(40) NOT NULL,
|
|
32
|
+
UNIQUE (owner, name)
|
|
33
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
34
|
+
|
|
35
|
+
CREATE TABLE IF NOT EXISTS {{model_cache}} (
|
|
36
|
+
provider_model VARCHAR(128) PRIMARY KEY,
|
|
37
|
+
label VARCHAR(255) NOT NULL,
|
|
38
|
+
refreshed_at VARCHAR(40) NOT NULL
|
|
39
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
40
|
+
|
|
41
|
+
CREATE TABLE IF NOT EXISTS {{issues}} (
|
|
42
|
+
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
43
|
+
project_id BIGINT NOT NULL,
|
|
44
|
+
number INT NOT NULL,
|
|
45
|
+
title VARCHAR(512) NOT NULL,
|
|
46
|
+
body TEXT NOT NULL,
|
|
47
|
+
state VARCHAR(16) NOT NULL DEFAULT 'open'
|
|
48
|
+
CHECK (state IN ('open','closed')),
|
|
49
|
+
author VARCHAR(255) NOT NULL,
|
|
50
|
+
created_at VARCHAR(40) NOT NULL,
|
|
51
|
+
updated_at VARCHAR(40) NOT NULL,
|
|
52
|
+
closed_at VARCHAR(40) DEFAULT NULL,
|
|
53
|
+
UNIQUE (project_id, number),
|
|
54
|
+
CONSTRAINT {{fk_issues_project}} FOREIGN KEY (project_id) REFERENCES {{projects}}(id) ON DELETE CASCADE,
|
|
55
|
+
CONSTRAINT {{fk_issues_author}} FOREIGN KEY (author) REFERENCES {{users}}(login)
|
|
56
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
57
|
+
CREATE INDEX issues_project_state_updated
|
|
58
|
+
ON {{issues}} (project_id, state, updated_at DESC);
|
|
59
|
+
CREATE INDEX issues_state_updated
|
|
60
|
+
ON {{issues}} (state, updated_at DESC);
|
|
61
|
+
CREATE INDEX issues_author ON {{issues}} (author);
|
|
62
|
+
|
|
63
|
+
CREATE TABLE IF NOT EXISTS {{comments}} (
|
|
64
|
+
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
65
|
+
issue_id BIGINT NOT NULL,
|
|
66
|
+
author VARCHAR(255) NOT NULL,
|
|
67
|
+
body TEXT NOT NULL,
|
|
68
|
+
created_at VARCHAR(40) NOT NULL,
|
|
69
|
+
updated_at VARCHAR(40) NOT NULL DEFAULT '',
|
|
70
|
+
CONSTRAINT {{fk_comments_issue}} FOREIGN KEY (issue_id) REFERENCES {{issues}}(id) ON DELETE CASCADE,
|
|
71
|
+
CONSTRAINT {{fk_comments_author}} FOREIGN KEY (author) REFERENCES {{users}}(login)
|
|
72
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
73
|
+
CREATE INDEX comments_issue_created ON {{comments}} (issue_id, created_at);
|
|
74
|
+
CREATE INDEX comments_author ON {{comments}} (author);
|
|
75
|
+
|
|
76
|
+
CREATE TABLE IF NOT EXISTS {{labels}} (
|
|
77
|
+
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
78
|
+
project_id BIGINT NOT NULL,
|
|
79
|
+
name VARCHAR(255) NOT NULL,
|
|
80
|
+
color VARCHAR(16) NOT NULL DEFAULT '#888888',
|
|
81
|
+
UNIQUE (project_id, name),
|
|
82
|
+
CONSTRAINT {{fk_labels_project}} FOREIGN KEY (project_id) REFERENCES {{projects}}(id) ON DELETE CASCADE
|
|
83
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
84
|
+
|
|
85
|
+
CREATE TABLE IF NOT EXISTS {{issue_labels}} (
|
|
86
|
+
issue_id BIGINT NOT NULL,
|
|
87
|
+
label_id BIGINT NOT NULL,
|
|
88
|
+
PRIMARY KEY (issue_id, label_id),
|
|
89
|
+
CONSTRAINT {{fk_il_issue}} FOREIGN KEY (issue_id) REFERENCES {{issues}}(id) ON DELETE CASCADE,
|
|
90
|
+
CONSTRAINT {{fk_il_label}} FOREIGN KEY (label_id) REFERENCES {{labels}}(id) ON DELETE CASCADE
|
|
91
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
92
|
+
CREATE INDEX issue_labels_label ON {{issue_labels}} (label_id);
|
|
93
|
+
|
|
94
|
+
CREATE TABLE IF NOT EXISTS {{reactions}} (
|
|
95
|
+
comment_id BIGINT NOT NULL,
|
|
96
|
+
user_login VARCHAR(255) NOT NULL,
|
|
97
|
+
content VARCHAR(64) NOT NULL,
|
|
98
|
+
PRIMARY KEY (comment_id, user_login, content),
|
|
99
|
+
CONSTRAINT {{fk_reactions_comment}} FOREIGN KEY (comment_id) REFERENCES {{comments}}(id) ON DELETE CASCADE,
|
|
100
|
+
CONSTRAINT {{fk_reactions_user}} FOREIGN KEY (user_login) REFERENCES {{users}}(login)
|
|
101
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
102
|
+
CREATE INDEX reactions_comment ON {{reactions}} (comment_id);
|
|
103
|
+
CREATE INDEX reactions_user ON {{reactions}} (user_login);
|
|
104
|
+
|
|
105
|
+
CREATE TABLE IF NOT EXISTS {{attachments}} (
|
|
106
|
+
uuid VARCHAR(64) PRIMARY KEY,
|
|
107
|
+
issue_id BIGINT NOT NULL,
|
|
108
|
+
filename VARCHAR(255) NOT NULL,
|
|
109
|
+
content_type VARCHAR(128) NOT NULL DEFAULT 'application/octet-stream',
|
|
110
|
+
size BIGINT NOT NULL,
|
|
111
|
+
blob_path VARCHAR(1024) NOT NULL,
|
|
112
|
+
uploaded_by VARCHAR(255) NOT NULL,
|
|
113
|
+
created_at VARCHAR(40) NOT NULL,
|
|
114
|
+
CONSTRAINT {{fk_attachments_issue}} FOREIGN KEY (issue_id) REFERENCES {{issues}}(id) ON DELETE CASCADE,
|
|
115
|
+
CONSTRAINT {{fk_attachments_user}} FOREIGN KEY (uploaded_by) REFERENCES {{users}}(login)
|
|
116
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
117
|
+
CREATE INDEX attachments_issue ON {{attachments}} (issue_id);
|
|
118
|
+
CREATE INDEX attachments_user ON {{attachments}} (uploaded_by);
|
|
119
|
+
|
|
120
|
+
CREATE TABLE IF NOT EXISTS {{webhooks}} (
|
|
121
|
+
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
122
|
+
project_id BIGINT NOT NULL,
|
|
123
|
+
url VARCHAR(1024) NOT NULL,
|
|
124
|
+
secret VARCHAR(255) NOT NULL DEFAULT '',
|
|
125
|
+
content_type VARCHAR(128) NOT NULL DEFAULT 'application/json',
|
|
126
|
+
events VARCHAR(2048) NOT NULL DEFAULT '["issues","issue_comment"]',
|
|
127
|
+
active TINYINT NOT NULL DEFAULT 1,
|
|
128
|
+
created_at VARCHAR(40) NOT NULL,
|
|
129
|
+
updated_at VARCHAR(40) NOT NULL,
|
|
130
|
+
CONSTRAINT {{fk_webhooks_project}} FOREIGN KEY (project_id) REFERENCES {{projects}}(id) ON DELETE CASCADE
|
|
131
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
132
|
+
CREATE INDEX webhooks_project ON {{webhooks}} (project_id);
|
|
133
|
+
|
|
134
|
+
CREATE TABLE IF NOT EXISTS {{webhook_deliveries}} (
|
|
135
|
+
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
136
|
+
webhook_id BIGINT NOT NULL,
|
|
137
|
+
event VARCHAR(64) NOT NULL,
|
|
138
|
+
delivery_uuid VARCHAR(64) NOT NULL,
|
|
139
|
+
payload LONGTEXT NOT NULL,
|
|
140
|
+
response_status INT DEFAULT NULL,
|
|
141
|
+
response_body LONGTEXT,
|
|
142
|
+
duration_ms INT DEFAULT NULL,
|
|
143
|
+
error TEXT,
|
|
144
|
+
created_at VARCHAR(40) NOT NULL,
|
|
145
|
+
CONSTRAINT {{fk_deliveries_webhook}} FOREIGN KEY (webhook_id) REFERENCES {{webhooks}}(id) ON DELETE CASCADE
|
|
146
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
147
|
+
CREATE INDEX deliveries_webhook ON {{webhook_deliveries}} (webhook_id);
|
|
148
|
+
CREATE INDEX deliveries_created ON {{webhook_deliveries}} (created_at DESC);
|
|
149
|
+
|
|
150
|
+
CREATE TABLE IF NOT EXISTS {{personal_access_tokens}} (
|
|
151
|
+
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
152
|
+
user_login VARCHAR(255) NOT NULL,
|
|
153
|
+
name VARCHAR(255) NOT NULL,
|
|
154
|
+
salt VARCHAR(32) NOT NULL,
|
|
155
|
+
token_hash VARCHAR(64) NOT NULL,
|
|
156
|
+
token_last_eight CHAR(8) NOT NULL,
|
|
157
|
+
scopes VARCHAR(2048) NOT NULL DEFAULT '[]',
|
|
158
|
+
ip_allowlist VARCHAR(2048) NOT NULL DEFAULT '[]',
|
|
159
|
+
expires_at VARCHAR(40) DEFAULT NULL,
|
|
160
|
+
last_used_at VARCHAR(40) DEFAULT NULL,
|
|
161
|
+
created_at VARCHAR(40) NOT NULL,
|
|
162
|
+
revoked_at VARCHAR(40) DEFAULT NULL,
|
|
163
|
+
CONSTRAINT {{fk_pat_user}} FOREIGN KEY (user_login) REFERENCES {{users}}(login) ON DELETE CASCADE
|
|
164
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
165
|
+
CREATE INDEX pat_user ON {{personal_access_tokens}} (user_login);
|
|
166
|
+
CREATE INDEX pat_last_eight ON {{personal_access_tokens}} (token_last_eight);
|
|
167
|
+
|
|
168
|
+
CREATE TABLE IF NOT EXISTS {{project_members}} (
|
|
169
|
+
project_id BIGINT NOT NULL,
|
|
170
|
+
user_login VARCHAR(255) NOT NULL,
|
|
171
|
+
role VARCHAR(16) NOT NULL DEFAULT 'writer'
|
|
172
|
+
CHECK (role IN ('reader','writer','admin')),
|
|
173
|
+
created_at VARCHAR(40) NOT NULL,
|
|
174
|
+
PRIMARY KEY (project_id, user_login),
|
|
175
|
+
CONSTRAINT {{fk_pm_project}} FOREIGN KEY (project_id) REFERENCES {{projects}}(id) ON DELETE CASCADE,
|
|
176
|
+
CONSTRAINT {{fk_pm_user}} FOREIGN KEY (user_login) REFERENCES {{users}}(login) ON DELETE CASCADE
|
|
177
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
|
178
|
+
CREATE INDEX project_members_user ON {{project_members}} (user_login);
|
package/src/schema.sql
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
-- login stays PRIMARY KEY intentionally. Renaming users is not supported;
|
|
5
5
|
-- swap to INTEGER user_id + UNIQUE(login) if that ever changes.
|
|
6
|
-
CREATE TABLE IF NOT EXISTS users (
|
|
6
|
+
CREATE TABLE IF NOT EXISTS {{users}} (
|
|
7
7
|
login TEXT PRIMARY KEY,
|
|
8
8
|
kind TEXT NOT NULL DEFAULT 'human'
|
|
9
9
|
CHECK (kind IN ('human','bot','system')),
|
|
@@ -16,7 +16,7 @@ CREATE TABLE IF NOT EXISTS users (
|
|
|
16
16
|
updated_at TEXT NOT NULL DEFAULT ''
|
|
17
17
|
);
|
|
18
18
|
|
|
19
|
-
CREATE TABLE IF NOT EXISTS projects (
|
|
19
|
+
CREATE TABLE IF NOT EXISTS {{projects}} (
|
|
20
20
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
21
21
|
owner TEXT NOT NULL,
|
|
22
22
|
name TEXT NOT NULL,
|
|
@@ -39,21 +39,21 @@ CREATE TABLE IF NOT EXISTS projects (
|
|
|
39
39
|
-- the /settings page (or on first access if empty). Stored as rows rather
|
|
40
40
|
-- than a single JSON blob so the settings UI can render a select without
|
|
41
41
|
-- parsing JSON in SQL.
|
|
42
|
-
CREATE TABLE IF NOT EXISTS model_cache (
|
|
42
|
+
CREATE TABLE IF NOT EXISTS {{model_cache}} (
|
|
43
43
|
provider_model TEXT PRIMARY KEY,
|
|
44
44
|
label TEXT NOT NULL,
|
|
45
45
|
refreshed_at TEXT NOT NULL
|
|
46
46
|
);
|
|
47
47
|
|
|
48
|
-
CREATE TABLE IF NOT EXISTS issues (
|
|
48
|
+
CREATE TABLE IF NOT EXISTS {{issues}} (
|
|
49
49
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
50
|
-
project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
50
|
+
project_id INTEGER NOT NULL REFERENCES {{projects}}(id) ON DELETE CASCADE,
|
|
51
51
|
number INTEGER NOT NULL,
|
|
52
52
|
title TEXT NOT NULL,
|
|
53
53
|
body TEXT NOT NULL DEFAULT '',
|
|
54
54
|
state TEXT NOT NULL DEFAULT 'open'
|
|
55
55
|
CHECK (state IN ('open','closed')),
|
|
56
|
-
author TEXT NOT NULL REFERENCES users(login),
|
|
56
|
+
author TEXT NOT NULL REFERENCES {{users}}(login),
|
|
57
57
|
created_at TEXT NOT NULL,
|
|
58
58
|
updated_at TEXT NOT NULL,
|
|
59
59
|
-- NULL when open; stamped on close, cleared on reopen. Backfill-safe because
|
|
@@ -62,63 +62,63 @@ CREATE TABLE IF NOT EXISTS issues (
|
|
|
62
62
|
UNIQUE (project_id, number)
|
|
63
63
|
);
|
|
64
64
|
CREATE INDEX IF NOT EXISTS issues_project_state_updated
|
|
65
|
-
ON issues (project_id, state, updated_at DESC);
|
|
65
|
+
ON {{issues}} (project_id, state, updated_at DESC);
|
|
66
66
|
CREATE INDEX IF NOT EXISTS issues_state_updated
|
|
67
|
-
ON issues (state, updated_at DESC);
|
|
67
|
+
ON {{issues}} (state, updated_at DESC);
|
|
68
68
|
|
|
69
|
-
CREATE TABLE IF NOT EXISTS comments (
|
|
69
|
+
CREATE TABLE IF NOT EXISTS {{comments}} (
|
|
70
70
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
71
|
-
issue_id INTEGER NOT NULL REFERENCES issues(id) ON DELETE CASCADE,
|
|
72
|
-
author TEXT NOT NULL REFERENCES users(login),
|
|
71
|
+
issue_id INTEGER NOT NULL REFERENCES {{issues}}(id) ON DELETE CASCADE,
|
|
72
|
+
author TEXT NOT NULL REFERENCES {{users}}(login),
|
|
73
73
|
body TEXT NOT NULL,
|
|
74
74
|
created_at TEXT NOT NULL,
|
|
75
75
|
updated_at TEXT NOT NULL DEFAULT ''
|
|
76
76
|
);
|
|
77
77
|
CREATE INDEX IF NOT EXISTS comments_issue_created
|
|
78
|
-
ON comments (issue_id, created_at);
|
|
78
|
+
ON {{comments}} (issue_id, created_at);
|
|
79
79
|
|
|
80
|
-
CREATE TABLE IF NOT EXISTS labels (
|
|
80
|
+
CREATE TABLE IF NOT EXISTS {{labels}} (
|
|
81
81
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
82
|
-
project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
82
|
+
project_id INTEGER NOT NULL REFERENCES {{projects}}(id) ON DELETE CASCADE,
|
|
83
83
|
name TEXT NOT NULL,
|
|
84
84
|
color TEXT NOT NULL DEFAULT '#888888',
|
|
85
85
|
UNIQUE (project_id, name)
|
|
86
86
|
);
|
|
87
87
|
|
|
88
|
-
CREATE TABLE IF NOT EXISTS issue_labels (
|
|
89
|
-
issue_id INTEGER NOT NULL REFERENCES issues(id) ON DELETE CASCADE,
|
|
90
|
-
label_id INTEGER NOT NULL REFERENCES labels(id) ON DELETE CASCADE,
|
|
88
|
+
CREATE TABLE IF NOT EXISTS {{issue_labels}} (
|
|
89
|
+
issue_id INTEGER NOT NULL REFERENCES {{issues}}(id) ON DELETE CASCADE,
|
|
90
|
+
label_id INTEGER NOT NULL REFERENCES {{labels}}(id) ON DELETE CASCADE,
|
|
91
91
|
PRIMARY KEY (issue_id, label_id)
|
|
92
92
|
);
|
|
93
93
|
|
|
94
|
-
CREATE TABLE IF NOT EXISTS reactions (
|
|
95
|
-
comment_id INTEGER NOT NULL REFERENCES comments(id) ON DELETE CASCADE,
|
|
96
|
-
user_login TEXT NOT NULL REFERENCES users(login),
|
|
94
|
+
CREATE TABLE IF NOT EXISTS {{reactions}} (
|
|
95
|
+
comment_id INTEGER NOT NULL REFERENCES {{comments}}(id) ON DELETE CASCADE,
|
|
96
|
+
user_login TEXT NOT NULL REFERENCES {{users}}(login),
|
|
97
97
|
content TEXT NOT NULL,
|
|
98
98
|
PRIMARY KEY (comment_id, user_login, content)
|
|
99
99
|
);
|
|
100
100
|
CREATE INDEX IF NOT EXISTS reactions_comment
|
|
101
|
-
ON reactions (comment_id);
|
|
101
|
+
ON {{reactions}} (comment_id);
|
|
102
102
|
|
|
103
|
-
CREATE TABLE IF NOT EXISTS attachments (
|
|
103
|
+
CREATE TABLE IF NOT EXISTS {{attachments}} (
|
|
104
104
|
uuid TEXT PRIMARY KEY,
|
|
105
|
-
issue_id INTEGER NOT NULL REFERENCES issues(id) ON DELETE CASCADE,
|
|
105
|
+
issue_id INTEGER NOT NULL REFERENCES {{issues}}(id) ON DELETE CASCADE,
|
|
106
106
|
filename TEXT NOT NULL,
|
|
107
107
|
content_type TEXT NOT NULL DEFAULT 'application/octet-stream',
|
|
108
108
|
size INTEGER NOT NULL,
|
|
109
109
|
blob_path TEXT NOT NULL,
|
|
110
|
-
uploaded_by TEXT NOT NULL REFERENCES users(login),
|
|
110
|
+
uploaded_by TEXT NOT NULL REFERENCES {{users}}(login),
|
|
111
111
|
created_at TEXT NOT NULL
|
|
112
112
|
);
|
|
113
113
|
CREATE INDEX IF NOT EXISTS attachments_issue
|
|
114
|
-
ON attachments (issue_id);
|
|
114
|
+
ON {{attachments}} (issue_id);
|
|
115
115
|
|
|
116
116
|
-- Webhooks (Gitea-compatible). Scoped per-project so different repos can fan out
|
|
117
117
|
-- to different downstream consumers. `events` is a JSON array of event types
|
|
118
118
|
-- ('issues', 'issue_comment', 'push', ...). ework v1 emits only the first two.
|
|
119
|
-
CREATE TABLE IF NOT EXISTS webhooks (
|
|
119
|
+
CREATE TABLE IF NOT EXISTS {{webhooks}} (
|
|
120
120
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
121
|
-
project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
121
|
+
project_id INTEGER NOT NULL REFERENCES {{projects}}(id) ON DELETE CASCADE,
|
|
122
122
|
url TEXT NOT NULL,
|
|
123
123
|
secret TEXT NOT NULL DEFAULT '',
|
|
124
124
|
content_type TEXT NOT NULL DEFAULT 'application/json',
|
|
@@ -129,13 +129,13 @@ CREATE TABLE IF NOT EXISTS webhooks (
|
|
|
129
129
|
updated_at TEXT NOT NULL
|
|
130
130
|
);
|
|
131
131
|
CREATE INDEX IF NOT EXISTS webhooks_project
|
|
132
|
-
ON webhooks (project_id);
|
|
132
|
+
ON {{webhooks}} (project_id);
|
|
133
133
|
|
|
134
134
|
-- Delivery history. One row per attempt. Retries append new rows (don't overwrite),
|
|
135
135
|
-- so a failed webhook shows the full retry trail.
|
|
136
|
-
CREATE TABLE IF NOT EXISTS webhook_deliveries (
|
|
136
|
+
CREATE TABLE IF NOT EXISTS {{webhook_deliveries}} (
|
|
137
137
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
138
|
-
webhook_id INTEGER NOT NULL REFERENCES webhooks(id) ON DELETE CASCADE,
|
|
138
|
+
webhook_id INTEGER NOT NULL REFERENCES {{webhooks}}(id) ON DELETE CASCADE,
|
|
139
139
|
event TEXT NOT NULL,
|
|
140
140
|
delivery_uuid TEXT NOT NULL,
|
|
141
141
|
payload TEXT NOT NULL,
|
|
@@ -146,17 +146,17 @@ CREATE TABLE IF NOT EXISTS webhook_deliveries (
|
|
|
146
146
|
created_at TEXT NOT NULL
|
|
147
147
|
);
|
|
148
148
|
CREATE INDEX IF NOT EXISTS deliveries_webhook
|
|
149
|
-
ON webhook_deliveries (webhook_id);
|
|
149
|
+
ON {{webhook_deliveries}} (webhook_id);
|
|
150
150
|
CREATE INDEX IF NOT EXISTS deliveries_created
|
|
151
|
-
ON webhook_deliveries (created_at DESC);
|
|
151
|
+
ON {{webhook_deliveries}} (created_at DESC);
|
|
152
152
|
|
|
153
153
|
-- Personal Access Tokens (Gitea-aligned). Hashed with per-token salt so the
|
|
154
154
|
-- DB leak doesn't reveal tokens; last_eight enables indexed lookup without
|
|
155
155
|
-- storing the plaintext. `scopes` is stored but not yet enforced — every PAT
|
|
156
156
|
-- inherits the user's full perms in v1; granularity lands with project_members.
|
|
157
|
-
CREATE TABLE IF NOT EXISTS personal_access_tokens (
|
|
157
|
+
CREATE TABLE IF NOT EXISTS {{personal_access_tokens}} (
|
|
158
158
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
159
|
-
user_login TEXT NOT NULL REFERENCES users(login) ON DELETE CASCADE,
|
|
159
|
+
user_login TEXT NOT NULL REFERENCES {{users}}(login) ON DELETE CASCADE,
|
|
160
160
|
name TEXT NOT NULL,
|
|
161
161
|
salt TEXT NOT NULL,
|
|
162
162
|
token_hash TEXT NOT NULL,
|
|
@@ -171,9 +171,9 @@ CREATE TABLE IF NOT EXISTS personal_access_tokens (
|
|
|
171
171
|
revoked_at TEXT
|
|
172
172
|
);
|
|
173
173
|
CREATE INDEX IF NOT EXISTS pat_user
|
|
174
|
-
ON personal_access_tokens (user_login);
|
|
174
|
+
ON {{personal_access_tokens}} (user_login);
|
|
175
175
|
CREATE INDEX IF NOT EXISTS pat_last_eight
|
|
176
|
-
ON personal_access_tokens (token_last_eight);
|
|
176
|
+
ON {{personal_access_tokens}} (token_last_eight);
|
|
177
177
|
|
|
178
178
|
-- Per-project RBAC. Roles follow Gitea semantics:
|
|
179
179
|
-- reader: can read issues + comments (currently no-op since all authed users
|
|
@@ -183,13 +183,13 @@ CREATE INDEX IF NOT EXISTS pat_last_eight
|
|
|
183
183
|
-- Site-admins (users.is_admin=1) bypass all checks. PAT scope enforcement also
|
|
184
184
|
-- routes through here: a write-scoped PAT can only write where the owning user
|
|
185
185
|
-- has writer+ role on the target project.
|
|
186
|
-
CREATE TABLE IF NOT EXISTS project_members (
|
|
187
|
-
project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
188
|
-
user_login TEXT NOT NULL REFERENCES users(login) ON DELETE CASCADE,
|
|
186
|
+
CREATE TABLE IF NOT EXISTS {{project_members}} (
|
|
187
|
+
project_id INTEGER NOT NULL REFERENCES {{projects}}(id) ON DELETE CASCADE,
|
|
188
|
+
user_login TEXT NOT NULL REFERENCES {{users}}(login) ON DELETE CASCADE,
|
|
189
189
|
role TEXT NOT NULL DEFAULT 'writer'
|
|
190
190
|
CHECK (role IN ('reader','writer','admin')),
|
|
191
191
|
created_at TEXT NOT NULL,
|
|
192
192
|
PRIMARY KEY (project_id, user_login)
|
|
193
193
|
);
|
|
194
194
|
CREATE INDEX IF NOT EXISTS project_members_user
|
|
195
|
-
ON project_members (user_login);
|
|
195
|
+
ON {{project_members}} (user_login);
|