pierre-review 0.1.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.
Files changed (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +88 -0
  3. package/dist/api/plugins/error-handler.js +40 -0
  4. package/dist/api/routes/health.js +7 -0
  5. package/dist/api/routes/me.js +34 -0
  6. package/dist/api/routes/mergers.js +7 -0
  7. package/dist/api/routes/open-prs.js +21 -0
  8. package/dist/api/routes/prs.js +50 -0
  9. package/dist/api/routes/repos.js +188 -0
  10. package/dist/api/routes/threads.js +20 -0
  11. package/dist/api/routes/timeline.js +73 -0
  12. package/dist/api/routes/users.js +28 -0
  13. package/dist/app.js +48 -0
  14. package/dist/ascii.js +12 -0
  15. package/dist/cli.js +138 -0
  16. package/dist/config.js +41 -0
  17. package/dist/db/cleanup.js +22 -0
  18. package/dist/db/client.js +13 -0
  19. package/dist/db/migrate.js +15 -0
  20. package/dist/db/migrations/0000_purple_ben_grimm.sql +155 -0
  21. package/dist/db/migrations/0001_colorful_ozymandias.sql +31 -0
  22. package/dist/db/migrations/0002_famous_sersi.sql +9 -0
  23. package/dist/db/migrations/0003_clever_shinobi_shaw.sql +3 -0
  24. package/dist/db/migrations/0004_pale_scalphunter.sql +1 -0
  25. package/dist/db/migrations/0005_daffy_guardian.sql +2 -0
  26. package/dist/db/migrations/meta/0000_snapshot.json +1116 -0
  27. package/dist/db/migrations/meta/0001_snapshot.json +1321 -0
  28. package/dist/db/migrations/meta/0002_snapshot.json +1375 -0
  29. package/dist/db/migrations/meta/0003_snapshot.json +1396 -0
  30. package/dist/db/migrations/meta/0004_snapshot.json +1416 -0
  31. package/dist/db/migrations/meta/0005_snapshot.json +1430 -0
  32. package/dist/db/migrations/meta/_journal.json +48 -0
  33. package/dist/db/queries.js +837 -0
  34. package/dist/db/run-migrations.js +10 -0
  35. package/dist/db/schema.js +248 -0
  36. package/dist/db/triage.js +168 -0
  37. package/dist/github/auth.js +19 -0
  38. package/dist/github/client.js +30 -0
  39. package/dist/github/local-user.js +92 -0
  40. package/dist/github/queries.js +249 -0
  41. package/dist/index.js +49 -0
  42. package/dist/sync/bot-detection.js +24 -0
  43. package/dist/sync/commit-files.js +50 -0
  44. package/dist/sync/derive-thread-state.js +38 -0
  45. package/dist/sync/scheduler.js +28 -0
  46. package/dist/sync/sync-manager.js +150 -0
  47. package/dist/sync/sync-repo.js +122 -0
  48. package/dist/sync/upsert.js +528 -0
  49. package/package.json +46 -0
  50. package/public/assets/index-6p3C9xk7.css +10 -0
  51. package/public/assets/index-C-CZcLLq.js +1360 -0
  52. package/public/index.html +25 -0
package/dist/cli.js ADDED
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/env node
2
+ import { execFile, execFileSync } from 'node:child_process';
3
+ import { mkdirSync } from 'node:fs';
4
+ import { homedir } from 'node:os';
5
+ import { dirname, join } from 'node:path';
6
+ // ── tiny ANSI helpers (degrade gracefully when not a TTY) ──────────────────
7
+ const useColor = process.stdout.isTTY && process.env.NO_COLOR === undefined;
8
+ const paint = (code, s) => useColor ? `[${code}m${s}` : s;
9
+ const cyan = (s) => paint('36', s);
10
+ const dim = (s) => paint('2', s);
11
+ const bold = (s) => paint('1', s);
12
+ function parseArgs(argv) {
13
+ const opts = { open: true, help: false };
14
+ for (let i = 0; i < argv.length; i++) {
15
+ const arg = argv[i];
16
+ switch (arg) {
17
+ case '--no-open':
18
+ opts.open = false;
19
+ break;
20
+ case '--port': {
21
+ const v = argv[++i];
22
+ const n = v ? Number.parseInt(v, 10) : NaN;
23
+ if (!Number.isFinite(n)) {
24
+ console.error('--port requires a number');
25
+ process.exit(1);
26
+ }
27
+ opts.port = n;
28
+ break;
29
+ }
30
+ case '--db': {
31
+ const v = argv[++i];
32
+ if (!v) {
33
+ console.error('--db requires a path');
34
+ process.exit(1);
35
+ }
36
+ opts.db = v;
37
+ break;
38
+ }
39
+ case '--help':
40
+ case '-h':
41
+ opts.help = true;
42
+ break;
43
+ default:
44
+ console.error(`Unknown argument: ${arg}`);
45
+ console.error('Run `pierre --help` for usage.');
46
+ process.exit(1);
47
+ }
48
+ }
49
+ return opts;
50
+ }
51
+ function printUsage() {
52
+ console.log(`pierre — ${'local-only GitHub PR activity dashboard'}
53
+
54
+ Usage:
55
+ pierre [options]
56
+ pierre-review [options]
57
+
58
+ Options:
59
+ --no-open Don't open the browser (also honours NO_OPEN env)
60
+ --port <n> Port to listen on (also PORT env, default 4000)
61
+ --db <path> SQLite DB path (also DATABASE_URL env)
62
+ -h, --help Show this help
63
+
64
+ Prerequisite:
65
+ Requires the GitHub CLI (https://cli.github.com), authenticated via
66
+ \`gh auth login\`. The dashboard reads your activity using your gh token.
67
+ `);
68
+ }
69
+ // Cross-platform browser open — no extra dependency.
70
+ function openBrowser(url) {
71
+ const platform = process.platform;
72
+ const cmd = platform === 'darwin' ? 'open' : platform === 'win32' ? 'cmd' : 'xdg-open';
73
+ const args = platform === 'win32' ? ['/c', 'start', '""', url] : [url];
74
+ // Swallow failures — headless / no-DE environments are fine.
75
+ execFile(cmd, args, () => {
76
+ /* ignore */
77
+ });
78
+ }
79
+ async function main() {
80
+ const opts = parseArgs(process.argv.slice(2));
81
+ if (opts.help) {
82
+ printUsage();
83
+ process.exit(0);
84
+ }
85
+ // ── map flags → env BEFORE importing config/app (config reads these) ──────
86
+ if (opts.port !== undefined)
87
+ process.env.PORT = String(opts.port);
88
+ if (opts.db !== undefined)
89
+ process.env.DATABASE_URL = opts.db;
90
+ if (opts.open === false)
91
+ process.env.NO_OPEN = '1';
92
+ // Production mode: skip pino-pretty (not shipped) and enable static serving.
93
+ process.env.NODE_ENV ??= 'production';
94
+ // ── default the DB to a user-writable home location (mkdir -p) ────────────
95
+ // The package dir is read-only for global installs, so never write there.
96
+ if (!process.env.DATABASE_URL) {
97
+ const dbPath = join(homedir(), '.pierre-review', 'pierre-review.sqlite');
98
+ process.env.DATABASE_URL = dbPath;
99
+ }
100
+ try {
101
+ mkdirSync(dirname(process.env.DATABASE_URL), { recursive: true });
102
+ }
103
+ catch {
104
+ /* best-effort; client.ts also mkdirs */
105
+ }
106
+ // ── pre-check gh auth with a friendly message (contract §6) ───────────────
107
+ try {
108
+ execFileSync('gh', ['auth', 'token'], { stdio: 'ignore' });
109
+ }
110
+ catch {
111
+ console.error('');
112
+ console.error(bold('GitHub CLI not found or not authenticated.'));
113
+ console.error('Install the GitHub CLI (https://cli.github.com) and run `gh auth login`.');
114
+ console.error('');
115
+ process.exit(1);
116
+ }
117
+ const port = process.env.PORT ? Number.parseInt(process.env.PORT, 10) : 4000;
118
+ const url = `http://localhost:${port}`;
119
+ // ── banner ────────────────────────────────────────────────────────────────
120
+ const { PIERRE_ASCII, TAGLINE } = await import('./ascii.js');
121
+ console.log(cyan(PIERRE_ASCII));
122
+ console.log(` ${dim(TAGLINE)}`);
123
+ console.log('');
124
+ console.log(` ${cyan('▸')} ${bold(url)}`);
125
+ console.log('');
126
+ // ── boot the server (migrate → user → app → scheduler → listen) ───────────
127
+ const { start } = await import('./index.js');
128
+ await start();
129
+ // ── open the browser once we're listening ─────────────────────────────────
130
+ const skipOpen = opts.open === false || process.env.NO_OPEN !== undefined;
131
+ if (!skipOpen)
132
+ openBrowser(url);
133
+ }
134
+ main().catch((err) => {
135
+ console.error('Failed to start pierre:', err);
136
+ process.exit(1);
137
+ });
138
+ //# sourceMappingURL=cli.js.map
package/dist/config.js ADDED
@@ -0,0 +1,41 @@
1
+ import { homedir } from 'node:os';
2
+ import { isAbsolute, join, resolve } from 'node:path';
3
+ // apps/backend as the base for relative paths regardless of cwd.
4
+ const backendRoot = resolve(import.meta.dirname, '..');
5
+ // Load .env from the repo root and (optionally) apps/backend before reading
6
+ // any config. Node's loader no-ops politely if a file is missing.
7
+ for (const envPath of [
8
+ resolve(backendRoot, '../../.env'),
9
+ resolve(backendRoot, '.env'),
10
+ ]) {
11
+ try {
12
+ process.loadEnvFile(envPath);
13
+ }
14
+ catch {
15
+ /* no .env at this location */
16
+ }
17
+ }
18
+ function intFromEnv(key, fallback) {
19
+ const raw = process.env[key];
20
+ if (!raw)
21
+ return fallback;
22
+ const n = Number.parseInt(raw, 10);
23
+ return Number.isFinite(n) ? n : fallback;
24
+ }
25
+ // Default the SQLite DB to a user-writable location in the home dir so the app
26
+ // works when installed globally (the package dir is read-only). DATABASE_URL /
27
+ // --db override this; a relative override resolves under apps/backend (dev).
28
+ const defaultDbPath = join(homedir(), '.pierre-review', 'pierre-review.sqlite');
29
+ const rawDbUrl = process.env.DATABASE_URL ?? defaultDbPath;
30
+ export const config = {
31
+ port: intFromEnv('PORT', 4000),
32
+ host: process.env.HOST ?? '127.0.0.1',
33
+ dbPath: isAbsolute(rawDbUrl) ? rawDbUrl : resolve(backendRoot, rawDbUrl),
34
+ backfillDays: intFromEnv('BACKFILL_DAYS', 90),
35
+ syncCron: process.env.SYNC_CRON ?? '*/5 * * * *',
36
+ syncOverlapMinutes: intFromEnv('SYNC_OVERLAP_MINUTES', 20),
37
+ stallThresholdDays: intFromEnv('STALL_THRESHOLD_DAYS', 3),
38
+ // Disable the periodic scheduler (used by scripts/tests).
39
+ disableScheduler: process.env.DISABLE_SCHEDULER === 'true',
40
+ };
41
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1,22 @@
1
+ import { sqlite } from './client.js';
2
+ // One-time / idempotent maintenance run at startup.
3
+ //
4
+ // GitHub wraps inline-only reviews in an empty "commented" review, which the
5
+ // sync used to record as a `review_submitted` event. Those wrappers duplicate
6
+ // the inline `review_comment` markers on the timeline. New syncs no longer emit
7
+ // them (see sync/upsert.ts), but pre-existing rows linger because upserts only
8
+ // update. This removes them; it also catches reviews whose summary body was
9
+ // later cleared on GitHub. Cheap and safe to run every boot.
10
+ export function cleanupRedundantReviewEvents() {
11
+ const res = sqlite
12
+ .prepare(`DELETE FROM events
13
+ WHERE type = 'review_submitted'
14
+ AND ref_table = 'reviews'
15
+ AND ref_id IN (
16
+ SELECT id FROM reviews
17
+ WHERE state = 'commented' AND (body IS NULL OR trim(body) = '')
18
+ )`)
19
+ .run();
20
+ return res.changes;
21
+ }
22
+ //# sourceMappingURL=cleanup.js.map
@@ -0,0 +1,13 @@
1
+ import { mkdirSync } from 'node:fs';
2
+ import { dirname } from 'node:path';
3
+ import Database from 'better-sqlite3';
4
+ import { drizzle } from 'drizzle-orm/better-sqlite3';
5
+ import { config } from '../config.js';
6
+ import * as schema from './schema.js';
7
+ mkdirSync(dirname(config.dbPath), { recursive: true });
8
+ export const sqlite = new Database(config.dbPath);
9
+ sqlite.pragma('journal_mode = WAL');
10
+ sqlite.pragma('foreign_keys = ON');
11
+ export const db = drizzle(sqlite, { schema });
12
+ export { schema };
13
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1,15 @@
1
+ // Applies pending drizzle migrations, then exits. Run via `pnpm db:migrate`.
2
+ import { sqlite } from './client.js';
3
+ import { runMigrations } from './run-migrations.js';
4
+ try {
5
+ runMigrations();
6
+ console.log('Migrations applied.');
7
+ }
8
+ catch (err) {
9
+ console.error('Migration failed:', err);
10
+ process.exitCode = 1;
11
+ }
12
+ finally {
13
+ sqlite.close();
14
+ }
15
+ //# sourceMappingURL=migrate.js.map
@@ -0,0 +1,155 @@
1
+ CREATE TABLE `commit_files` (
2
+ `sha` text PRIMARY KEY NOT NULL,
3
+ `paths` text NOT NULL,
4
+ `fetched_at` integer DEFAULT (unixepoch()) NOT NULL
5
+ );
6
+ --> statement-breakpoint
7
+ CREATE TABLE `commits` (
8
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
9
+ `sha` text NOT NULL,
10
+ `pr_id` integer NOT NULL,
11
+ `author_id` integer,
12
+ `committer_id` integer,
13
+ `message` text,
14
+ `committed_at` integer NOT NULL,
15
+ FOREIGN KEY (`pr_id`) REFERENCES `pull_requests`(`id`) ON UPDATE no action ON DELETE no action,
16
+ FOREIGN KEY (`author_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action,
17
+ FOREIGN KEY (`committer_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action
18
+ );
19
+ --> statement-breakpoint
20
+ CREATE INDEX `commit_pr_idx` ON `commits` (`pr_id`);--> statement-breakpoint
21
+ CREATE UNIQUE INDEX `commit_sha_pr_ux` ON `commits` (`sha`,`pr_id`);--> statement-breakpoint
22
+ CREATE TABLE `events` (
23
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
24
+ `repo_id` integer NOT NULL,
25
+ `actor_id` integer,
26
+ `pr_id` integer,
27
+ `type` text NOT NULL,
28
+ `occurred_at` integer NOT NULL,
29
+ `ref_table` text,
30
+ `ref_id` integer,
31
+ `dedupe_key` text NOT NULL,
32
+ FOREIGN KEY (`repo_id`) REFERENCES `repos`(`id`) ON UPDATE no action ON DELETE no action,
33
+ FOREIGN KEY (`actor_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action,
34
+ FOREIGN KEY (`pr_id`) REFERENCES `pull_requests`(`id`) ON UPDATE no action ON DELETE no action
35
+ );
36
+ --> statement-breakpoint
37
+ CREATE UNIQUE INDEX `events_dedupe_key_unique` ON `events` (`dedupe_key`);--> statement-breakpoint
38
+ CREATE INDEX `events_time_idx` ON `events` (`occurred_at`);--> statement-breakpoint
39
+ CREATE INDEX `events_repo_time_idx` ON `events` (`repo_id`,`occurred_at`);--> statement-breakpoint
40
+ CREATE INDEX `events_actor_idx` ON `events` (`actor_id`);--> statement-breakpoint
41
+ CREATE TABLE `pr_comments` (
42
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
43
+ `github_node_id` text NOT NULL,
44
+ `pr_id` integer NOT NULL,
45
+ `author_id` integer,
46
+ `body` text NOT NULL,
47
+ `created_at` integer NOT NULL,
48
+ FOREIGN KEY (`pr_id`) REFERENCES `pull_requests`(`id`) ON UPDATE no action ON DELETE no action,
49
+ FOREIGN KEY (`author_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action
50
+ );
51
+ --> statement-breakpoint
52
+ CREATE UNIQUE INDEX `pr_comments_github_node_id_unique` ON `pr_comments` (`github_node_id`);--> statement-breakpoint
53
+ CREATE INDEX `prc_pr_idx` ON `pr_comments` (`pr_id`);--> statement-breakpoint
54
+ CREATE TABLE `pull_requests` (
55
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
56
+ `github_node_id` text NOT NULL,
57
+ `repo_id` integer NOT NULL,
58
+ `number` integer NOT NULL,
59
+ `title` text NOT NULL,
60
+ `body` text,
61
+ `author_id` integer,
62
+ `state` text NOT NULL,
63
+ `is_draft` integer DEFAULT false NOT NULL,
64
+ `opened_at` integer NOT NULL,
65
+ `first_review_at` integer,
66
+ `last_commit_at` integer,
67
+ `merged_at` integer,
68
+ `closed_at` integer,
69
+ `updated_at` integer NOT NULL,
70
+ FOREIGN KEY (`repo_id`) REFERENCES `repos`(`id`) ON UPDATE no action ON DELETE no action,
71
+ FOREIGN KEY (`author_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action
72
+ );
73
+ --> statement-breakpoint
74
+ CREATE UNIQUE INDEX `pull_requests_github_node_id_unique` ON `pull_requests` (`github_node_id`);--> statement-breakpoint
75
+ CREATE INDEX `pr_repo_idx` ON `pull_requests` (`repo_id`);--> statement-breakpoint
76
+ CREATE INDEX `pr_opened_idx` ON `pull_requests` (`opened_at`);--> statement-breakpoint
77
+ CREATE TABLE `repos` (
78
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
79
+ `owner` text NOT NULL,
80
+ `name` text NOT NULL,
81
+ `github_node_id` text NOT NULL,
82
+ `backfill_until` integer,
83
+ `created_at` integer DEFAULT (unixepoch()) NOT NULL
84
+ );
85
+ --> statement-breakpoint
86
+ CREATE UNIQUE INDEX `repos_github_node_id_unique` ON `repos` (`github_node_id`);--> statement-breakpoint
87
+ CREATE UNIQUE INDEX `repos_owner_name` ON `repos` (`owner`,`name`);--> statement-breakpoint
88
+ CREATE TABLE `review_comments` (
89
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
90
+ `github_node_id` text NOT NULL,
91
+ `thread_id` integer NOT NULL,
92
+ `pr_id` integer NOT NULL,
93
+ `author_id` integer,
94
+ `body` text NOT NULL,
95
+ `diff_hunk` text,
96
+ `created_at` integer NOT NULL,
97
+ FOREIGN KEY (`thread_id`) REFERENCES `review_threads`(`id`) ON UPDATE no action ON DELETE no action,
98
+ FOREIGN KEY (`pr_id`) REFERENCES `pull_requests`(`id`) ON UPDATE no action ON DELETE no action,
99
+ FOREIGN KEY (`author_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action
100
+ );
101
+ --> statement-breakpoint
102
+ CREATE UNIQUE INDEX `review_comments_github_node_id_unique` ON `review_comments` (`github_node_id`);--> statement-breakpoint
103
+ CREATE INDEX `rc_thread_idx` ON `review_comments` (`thread_id`);--> statement-breakpoint
104
+ CREATE TABLE `review_threads` (
105
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
106
+ `github_node_id` text NOT NULL,
107
+ `pr_id` integer NOT NULL,
108
+ `path` text NOT NULL,
109
+ `line` integer,
110
+ `is_resolved` integer NOT NULL,
111
+ `is_outdated` integer DEFAULT false NOT NULL,
112
+ `derived_state` text NOT NULL,
113
+ `original_commenter_id` integer,
114
+ `created_at` integer NOT NULL,
115
+ FOREIGN KEY (`pr_id`) REFERENCES `pull_requests`(`id`) ON UPDATE no action ON DELETE no action,
116
+ FOREIGN KEY (`original_commenter_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action
117
+ );
118
+ --> statement-breakpoint
119
+ CREATE UNIQUE INDEX `review_threads_github_node_id_unique` ON `review_threads` (`github_node_id`);--> statement-breakpoint
120
+ CREATE INDEX `thread_pr_idx` ON `review_threads` (`pr_id`);--> statement-breakpoint
121
+ CREATE TABLE `reviews` (
122
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
123
+ `github_node_id` text NOT NULL,
124
+ `pr_id` integer NOT NULL,
125
+ `author_id` integer,
126
+ `state` text NOT NULL,
127
+ `body` text,
128
+ `submitted_at` integer NOT NULL,
129
+ FOREIGN KEY (`pr_id`) REFERENCES `pull_requests`(`id`) ON UPDATE no action ON DELETE no action,
130
+ FOREIGN KEY (`author_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action
131
+ );
132
+ --> statement-breakpoint
133
+ CREATE UNIQUE INDEX `reviews_github_node_id_unique` ON `reviews` (`github_node_id`);--> statement-breakpoint
134
+ CREATE INDEX `rv_pr_idx` ON `reviews` (`pr_id`);--> statement-breakpoint
135
+ CREATE TABLE `sync_state` (
136
+ `repo_id` integer PRIMARY KEY NOT NULL,
137
+ `last_full_sync_at` integer,
138
+ `last_incremental_sync_at` integer,
139
+ `last_sync_status` text,
140
+ `last_sync_error` text,
141
+ FOREIGN KEY (`repo_id`) REFERENCES `repos`(`id`) ON UPDATE no action ON DELETE no action
142
+ );
143
+ --> statement-breakpoint
144
+ CREATE TABLE `users` (
145
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
146
+ `github_login` text NOT NULL,
147
+ `github_node_id` text,
148
+ `display_name` text,
149
+ `avatar_url` text,
150
+ `is_bot` integer DEFAULT false NOT NULL,
151
+ `is_bot_overridden` integer DEFAULT false NOT NULL
152
+ );
153
+ --> statement-breakpoint
154
+ CREATE UNIQUE INDEX `users_github_login_unique` ON `users` (`github_login`);--> statement-breakpoint
155
+ CREATE UNIQUE INDEX `users_github_node_id_unique` ON `users` (`github_node_id`);
@@ -0,0 +1,31 @@
1
+ CREATE TABLE `local_user` (
2
+ `id` integer PRIMARY KEY NOT NULL,
3
+ `github_login` text NOT NULL,
4
+ `github_id` text NOT NULL,
5
+ `avatar_url` text,
6
+ `cached_at` integer NOT NULL
7
+ );
8
+ --> statement-breakpoint
9
+ CREATE TABLE `pr_views` (
10
+ `pr_id` integer PRIMARY KEY NOT NULL,
11
+ `last_viewed_sha` text,
12
+ `last_viewed_at` integer NOT NULL,
13
+ FOREIGN KEY (`pr_id`) REFERENCES `pull_requests`(`id`) ON UPDATE no action ON DELETE no action
14
+ );
15
+ --> statement-breakpoint
16
+ CREATE TABLE `review_requests` (
17
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
18
+ `pr_id` integer NOT NULL,
19
+ `user_id` integer,
20
+ `team_name` text,
21
+ FOREIGN KEY (`pr_id`) REFERENCES `pull_requests`(`id`) ON UPDATE no action ON DELETE no action,
22
+ FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action
23
+ );
24
+ --> statement-breakpoint
25
+ CREATE INDEX `rr_pr_idx` ON `review_requests` (`pr_id`);--> statement-breakpoint
26
+ CREATE INDEX `rr_user_idx` ON `review_requests` (`user_id`);--> statement-breakpoint
27
+ ALTER TABLE `pull_requests` ADD `head_sha` text;--> statement-breakpoint
28
+ ALTER TABLE `pull_requests` ADD `ci_status` text;--> statement-breakpoint
29
+ ALTER TABLE `pull_requests` ADD `mergeable` text;--> statement-breakpoint
30
+ ALTER TABLE `pull_requests` ADD `merge_state_status` text;--> statement-breakpoint
31
+ ALTER TABLE `pull_requests` ADD `labels` text;
@@ -0,0 +1,9 @@
1
+ CREATE TABLE `my_turn_dismissals` (
2
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
3
+ `kind` text NOT NULL,
4
+ `ref_id` integer NOT NULL,
5
+ `dismissed_at` integer NOT NULL
6
+ );
7
+ --> statement-breakpoint
8
+ CREATE UNIQUE INDEX `mtd_kind_ref_ux` ON `my_turn_dismissals` (`kind`,`ref_id`);--> statement-breakpoint
9
+ ALTER TABLE `pull_requests` ADD `check_runs` text;
@@ -0,0 +1,3 @@
1
+ ALTER TABLE `pr_comments` ADD `database_id` text;--> statement-breakpoint
2
+ ALTER TABLE `review_comments` ADD `database_id` text;--> statement-breakpoint
3
+ ALTER TABLE `reviews` ADD `database_id` text;
@@ -0,0 +1 @@
1
+ ALTER TABLE `pull_requests` ADD `merged_by_id` integer REFERENCES users(id);
@@ -0,0 +1,2 @@
1
+ ALTER TABLE `pull_requests` ADD `base_ref_name` text;--> statement-breakpoint
2
+ ALTER TABLE `repos` ADD `default_branch` text;