@defrex/autobuild-postgres-store 0.12.0 → 0.14.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/README.md +3 -3
- package/package.json +9 -1
- package/src/schema.ts +153 -9
- package/src/store.ts +263 -72
- package/src/ticket-grants.ts +86 -0
- package/src/ticket-migration.ts +96 -35
- package/src/ticket-policy.ts +60 -0
- package/src/ticket-states.ts +15 -0
- package/src/tickets.ts +217 -82
package/README.md
CHANGED
|
@@ -119,9 +119,9 @@ Only an object-store 404 is treated as absent; authorization and service errors
|
|
|
119
119
|
are propagated. Vercel supports either a Blob read-write token or a Vercel OIDC
|
|
120
120
|
token paired with its Blob store ID.
|
|
121
121
|
|
|
122
|
-
`PostgresTicketDatabase.source({ teamKey, claimedState?, createState? })`
|
|
123
|
-
a request-bound TicketSource view. The deployment supplies
|
|
124
|
-
|
|
122
|
+
`PostgresTicketDatabase.source({ repo, teamKey, lifecycle, claimedState?, createState? })`
|
|
123
|
+
creates a request-bound TicketSource view. The deployment supplies the project
|
|
124
|
+
identity, readable-id prefix, and lifecycle names. Ticket bodies
|
|
125
125
|
are stored as PostgreSQL `text` and returned unchanged.
|
|
126
126
|
|
|
127
127
|
For an authenticated HTTP deployment of this adapter, see the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@defrex/autobuild-postgres-store",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"engines": {
|
|
@@ -34,6 +34,14 @@
|
|
|
34
34
|
"./connections": {
|
|
35
35
|
"types": "./src/connections.ts",
|
|
36
36
|
"import": "./src/connections.ts"
|
|
37
|
+
},
|
|
38
|
+
"./ticket-policy": {
|
|
39
|
+
"types": "./src/ticket-policy.ts",
|
|
40
|
+
"import": "./src/ticket-policy.ts"
|
|
41
|
+
},
|
|
42
|
+
"./ticket-grants": {
|
|
43
|
+
"types": "./src/ticket-grants.ts",
|
|
44
|
+
"import": "./src/ticket-grants.ts"
|
|
37
45
|
}
|
|
38
46
|
},
|
|
39
47
|
"bin": {
|
package/src/schema.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { PostgresProjectRegistry } from './projects'
|
|
2
2
|
import type { PostgresEnv } from './env'
|
|
3
3
|
import type { BlobStore } from '@defrex/autobuild/plugin-sdk'
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
migrateLegacyTickets,
|
|
6
|
+
migrateReadableTickets,
|
|
7
|
+
READABLE_TICKET_CONSTRAINTS,
|
|
8
|
+
} from './ticket-migration'
|
|
5
9
|
import { SQL } from 'bun'
|
|
6
10
|
import {
|
|
7
11
|
AUTH_SCHEMA_CHECKSUM,
|
|
@@ -12,7 +16,7 @@ import {
|
|
|
12
16
|
assertAuthSchema,
|
|
13
17
|
} from './auth-schema'
|
|
14
18
|
|
|
15
|
-
export const SCHEMA_VERSION =
|
|
19
|
+
export const SCHEMA_VERSION = 14
|
|
16
20
|
export const MIGRATE_COMMAND = 'bun run postgres:migrate (from a pinned Autobuild release checkout)'
|
|
17
21
|
|
|
18
22
|
/** The frozen v3 DDL, kept verbatim so a deployed v3 marker's checksum can be
|
|
@@ -817,12 +821,31 @@ CREATE TABLE IF NOT EXISTS project_connections (
|
|
|
817
821
|
CREATE TABLE IF NOT EXISTS connection_lookup_limits (
|
|
818
822
|
actor text PRIMARY KEY, started_at timestamptz NOT NULL, attempts integer NOT NULL
|
|
819
823
|
);`.trim()
|
|
820
|
-
export const
|
|
824
|
+
export const SCHEMA_V12_DDL = `${SCHEMA_V11_DDL}\n${CONNECTION_SCHEMA_DDL}`
|
|
825
|
+
export const SCHEMA_V12_CHECKSUM = new Bun.CryptoHasher('sha256')
|
|
826
|
+
.update(SCHEMA_V12_DDL)
|
|
827
|
+
.digest('hex')
|
|
828
|
+
export const TICKET_POLICY_SCHEMA_DDL = `
|
|
829
|
+
CREATE TABLE IF NOT EXISTS project_ticket_policy (
|
|
830
|
+
repo text PRIMARY KEY, registration bigint NOT NULL, policy jsonb NOT NULL,
|
|
831
|
+
writer text NOT NULL, updated_at timestamptz NOT NULL
|
|
832
|
+
);`
|
|
833
|
+
export const TICKET_GRANT_SCHEMA_DDL = `
|
|
834
|
+
CREATE TABLE IF NOT EXISTS ticket_grants (
|
|
835
|
+
id text PRIMARY KEY, digest text NOT NULL UNIQUE, repo text NOT NULL, registration bigint NOT NULL,
|
|
836
|
+
execution text NOT NULL, kind text NOT NULL CHECK (kind IN ('runner','phase')),
|
|
837
|
+
parent text REFERENCES ticket_grants(id), expires_at timestamptz NOT NULL, revoked_at timestamptz
|
|
838
|
+
);`
|
|
839
|
+
export const SCHEMA_V13_DDL = `${SCHEMA_V12_DDL}\n${TICKET_POLICY_SCHEMA_DDL}\n${TICKET_GRANT_SCHEMA_DDL}`
|
|
840
|
+
export const SCHEMA_V13_CHECKSUM = new Bun.CryptoHasher('sha256')
|
|
841
|
+
.update(SCHEMA_V13_DDL)
|
|
842
|
+
.digest('hex')
|
|
843
|
+
export const SCHEMA_DDL = `${SCHEMA_V13_DDL}\nALTER TABLE repo_streams ADD COLUMN IF NOT EXISTS tick jsonb;`
|
|
821
844
|
export const SCHEMA_CHECKSUM = new Bun.CryptoHasher('sha256').update(SCHEMA_DDL).digest('hex')
|
|
822
845
|
|
|
823
846
|
/** Ticket persistence evolves independently so deployed v1 BuildStore markers
|
|
824
847
|
* remain valid while the hosted ticket tables are added. */
|
|
825
|
-
export const TICKET_SCHEMA_VERSION =
|
|
848
|
+
export const TICKET_SCHEMA_VERSION = 5
|
|
826
849
|
export const TICKET_SCHEMA_V1_DDL = `
|
|
827
850
|
CREATE TABLE IF NOT EXISTS ab_ticket_schema_migrations (
|
|
828
851
|
singleton boolean PRIMARY KEY DEFAULT true CHECK (singleton),
|
|
@@ -851,7 +874,35 @@ CREATE TABLE IF NOT EXISTS ab_ticket_blockers (
|
|
|
851
874
|
export const TICKET_SCHEMA_V1_CHECKSUM = new Bun.CryptoHasher('sha256')
|
|
852
875
|
.update(TICKET_SCHEMA_V1_DDL)
|
|
853
876
|
.digest('hex')
|
|
854
|
-
export const
|
|
877
|
+
export const TICKET_SCHEMA_V2_DDL = TICKET_SCHEMA_V1_DDL.replaceAll('team', 'repo')
|
|
878
|
+
export const TICKET_SCHEMA_V2_CHECKSUM = new Bun.CryptoHasher('sha256')
|
|
879
|
+
.update(TICKET_SCHEMA_V2_DDL)
|
|
880
|
+
.digest('hex')
|
|
881
|
+
export const TICKET_SCHEMA_V3_DDL = TICKET_SCHEMA_V2_DDL.replace(
|
|
882
|
+
'updated_at timestamptz NOT NULL,',
|
|
883
|
+
'updated_at timestamptz NOT NULL, revision bigint NOT NULL DEFAULT 1,',
|
|
884
|
+
)
|
|
885
|
+
export const TICKET_SCHEMA_V3_CHECKSUM = new Bun.CryptoHasher('sha256')
|
|
886
|
+
.update(TICKET_SCHEMA_V3_DDL)
|
|
887
|
+
.digest('hex')
|
|
888
|
+
export const TICKET_STATES_DDL = `CREATE TABLE IF NOT EXISTS ab_ticket_states (
|
|
889
|
+
repo text NOT NULL, name text NOT NULL, about text,
|
|
890
|
+
PRIMARY KEY (repo, name),
|
|
891
|
+
CHECK (length(btrim(name)) > 0),
|
|
892
|
+
CHECK (about IS NULL OR (length(btrim(about)) > 0 AND position(chr(10) in about) = 0 AND position(chr(13) in about) = 0))
|
|
893
|
+
);`
|
|
894
|
+
export const TICKET_SCHEMA_V4_DDL = `${TICKET_SCHEMA_V3_DDL}\n${TICKET_STATES_DDL}`
|
|
895
|
+
export const TICKET_SCHEMA_V4_CHECKSUM = new Bun.CryptoHasher('sha256')
|
|
896
|
+
.update(TICKET_SCHEMA_V4_DDL)
|
|
897
|
+
.digest('hex')
|
|
898
|
+
export const TICKET_SCHEMA_DDL =
|
|
899
|
+
TICKET_SCHEMA_V4_DDL +
|
|
900
|
+
`
|
|
901
|
+
ALTER TABLE ab_tickets ADD COLUMN IF NOT EXISTS readable_id text;
|
|
902
|
+
ALTER TABLE ab_tickets ADD COLUMN IF NOT EXISTS ticket_number bigint;
|
|
903
|
+
CREATE TABLE IF NOT EXISTS ab_ticket_counters (repo text PRIMARY KEY, last_number bigint NOT NULL CHECK (last_number >= 0));
|
|
904
|
+
` +
|
|
905
|
+
READABLE_TICKET_CONSTRAINTS.trim()
|
|
855
906
|
export const TICKET_SCHEMA_CHECKSUM = new Bun.CryptoHasher('sha256')
|
|
856
907
|
.update(TICKET_SCHEMA_DDL)
|
|
857
908
|
.digest('hex')
|
|
@@ -893,6 +944,24 @@ const EXPECTED_COLUMNS: Record<string, readonly ExpectedColumn[]> = {
|
|
|
893
944
|
['started_at', 'timestamp with time zone', true],
|
|
894
945
|
['attempts', 'integer', true],
|
|
895
946
|
],
|
|
947
|
+
project_ticket_policy: [
|
|
948
|
+
['repo', 'text', true],
|
|
949
|
+
['registration', 'bigint', true],
|
|
950
|
+
['policy', 'jsonb', true],
|
|
951
|
+
['writer', 'text', true],
|
|
952
|
+
['updated_at', 'timestamp with time zone', true],
|
|
953
|
+
],
|
|
954
|
+
ticket_grants: [
|
|
955
|
+
['id', 'text', true],
|
|
956
|
+
['digest', 'text', true],
|
|
957
|
+
['repo', 'text', true],
|
|
958
|
+
['registration', 'bigint', true],
|
|
959
|
+
['execution', 'text', true],
|
|
960
|
+
['kind', 'text', true],
|
|
961
|
+
['parent', 'text', false],
|
|
962
|
+
['expires_at', 'timestamp with time zone', true],
|
|
963
|
+
['revoked_at', 'timestamp with time zone', false],
|
|
964
|
+
],
|
|
896
965
|
project_credentials: [
|
|
897
966
|
['id', 'text', true],
|
|
898
967
|
['digest', 'text', true],
|
|
@@ -973,6 +1042,7 @@ const EXPECTED_COLUMNS: Record<string, readonly ExpectedColumn[]> = {
|
|
|
973
1042
|
['lease_expires_at', 'timestamp with time zone', false],
|
|
974
1043
|
['lease_ttl_ms', 'bigint', false],
|
|
975
1044
|
['heartbeat_at', 'timestamp with time zone', false],
|
|
1045
|
+
['tick', 'jsonb', false],
|
|
976
1046
|
],
|
|
977
1047
|
repo_events: [
|
|
978
1048
|
['repo', 'text', true],
|
|
@@ -1048,6 +1118,10 @@ const EXPECTED_COLUMNS: Record<string, readonly ExpectedColumn[]> = {
|
|
|
1048
1118
|
}
|
|
1049
1119
|
|
|
1050
1120
|
const EXPECTED_CONSTRAINTS = [
|
|
1121
|
+
'project_ticket_policy|p|repo||||',
|
|
1122
|
+
'ticket_grants|p|id||||',
|
|
1123
|
+
'ticket_grants|c|||||',
|
|
1124
|
+
'ticket_grants|f|parent|ticket_grants|id|a|',
|
|
1051
1125
|
'project_connections|p|id||||',
|
|
1052
1126
|
'project_connections|c|||||',
|
|
1053
1127
|
'connection_lookup_limits|p|actor||||',
|
|
@@ -1279,6 +1353,18 @@ export async function assertTicketSchema(sql: SQL): Promise<void> {
|
|
|
1279
1353
|
['labels', 'text[]', true],
|
|
1280
1354
|
['created_at', 'timestamp with time zone', true],
|
|
1281
1355
|
['updated_at', 'timestamp with time zone', true],
|
|
1356
|
+
['revision', 'bigint', true],
|
|
1357
|
+
['readable_id', 'text', true],
|
|
1358
|
+
['ticket_number', 'bigint', true],
|
|
1359
|
+
],
|
|
1360
|
+
ab_ticket_counters: [
|
|
1361
|
+
['repo', 'text', true],
|
|
1362
|
+
['last_number', 'bigint', true],
|
|
1363
|
+
],
|
|
1364
|
+
ab_ticket_states: [
|
|
1365
|
+
['repo', 'text', true],
|
|
1366
|
+
['name', 'text', true],
|
|
1367
|
+
['about', 'text', false],
|
|
1282
1368
|
],
|
|
1283
1369
|
ab_ticket_comments: [
|
|
1284
1370
|
['repo', 'text', true],
|
|
@@ -1303,7 +1389,7 @@ export async function assertTicketSchema(sql: SQL): Promise<void> {
|
|
|
1303
1389
|
WHERE n.nspname = current_schema() AND c.relkind IN ('r', 'p')
|
|
1304
1390
|
AND a.attnum > 0 AND NOT a.attisdropped
|
|
1305
1391
|
AND c.relname = ANY(ARRAY['ab_ticket_schema_migrations', 'ab_tickets',
|
|
1306
|
-
'ab_ticket_comments', 'ab_ticket_blockers'])
|
|
1392
|
+
'ab_ticket_comments', 'ab_ticket_blockers', 'ab_ticket_counters', 'ab_ticket_states'])
|
|
1307
1393
|
ORDER BY c.relname, a.attnum`
|
|
1308
1394
|
for (const [table, shape] of Object.entries(expected)) {
|
|
1309
1395
|
const actual = columns
|
|
@@ -1313,13 +1399,32 @@ export async function assertTicketSchema(sql: SQL): Promise<void> {
|
|
|
1313
1399
|
throw schemaError(`ticket table ${table} is missing or mismatched`)
|
|
1314
1400
|
}
|
|
1315
1401
|
}
|
|
1402
|
+
const indexes =
|
|
1403
|
+
await sql`SELECT indexdef FROM pg_indexes WHERE schemaname = current_schema() AND tablename = 'ab_tickets' AND indexname = 'ab_tickets_readable_id_key'`
|
|
1404
|
+
if (
|
|
1405
|
+
!indexes[0] ||
|
|
1406
|
+
!String(indexes[0].indexdef).includes('UNIQUE INDEX') ||
|
|
1407
|
+
!String(indexes[0].indexdef).endsWith('(repo, lower(readable_id))')
|
|
1408
|
+
)
|
|
1409
|
+
throw schemaError('ticket readable id unique index is missing or mismatched')
|
|
1316
1410
|
const constraints: { table_name: string; definition: string }[] = await sql`
|
|
1317
1411
|
SELECT c.relname AS table_name, pg_get_constraintdef(k.oid) AS definition
|
|
1318
1412
|
FROM pg_constraint k JOIN pg_class c ON c.oid = k.conrelid
|
|
1319
1413
|
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
1320
|
-
WHERE n.nspname = current_schema() AND k.contype IN ('p', 'u', 'f', 'c') AND c.relname IN ('ab_tickets', 'ab_ticket_comments', 'ab_ticket_blockers')`
|
|
1414
|
+
WHERE n.nspname = current_schema() AND k.contype IN ('p', 'u', 'f', 'c') AND c.relname IN ('ab_tickets', 'ab_ticket_comments', 'ab_ticket_blockers', 'ab_ticket_counters', 'ab_ticket_states')`
|
|
1321
1415
|
const expectedConstraints: Record<string, string[]> = {
|
|
1322
|
-
|
|
1416
|
+
ab_ticket_states: [
|
|
1417
|
+
'PRIMARY KEY (repo, name)',
|
|
1418
|
+
'CHECK ((length(btrim(name)) > 0))',
|
|
1419
|
+
'CHECK (((about IS NULL) OR ((length(btrim(about)) > 0) AND (POSITION((chr(10)) IN (about)) = 0) AND (POSITION((chr(13)) IN (about)) = 0))))',
|
|
1420
|
+
],
|
|
1421
|
+
ab_tickets: [
|
|
1422
|
+
'PRIMARY KEY (repo, id)',
|
|
1423
|
+
'UNIQUE (repo, creation_key)',
|
|
1424
|
+
'UNIQUE (repo, ticket_number)',
|
|
1425
|
+
'CHECK ((ticket_number > 0))',
|
|
1426
|
+
],
|
|
1427
|
+
ab_ticket_counters: ['PRIMARY KEY (repo)', 'CHECK ((last_number >= 0))'],
|
|
1323
1428
|
ab_ticket_comments: [
|
|
1324
1429
|
'PRIMARY KEY (repo, ticket_id, seq)',
|
|
1325
1430
|
'FOREIGN KEY (repo, ticket_id) REFERENCES ab_tickets(repo, id) ON DELETE CASCADE',
|
|
@@ -1381,7 +1486,8 @@ export async function migratePostgres(
|
|
|
1381
1486
|
await sql.begin(async (tx) => {
|
|
1382
1487
|
await tx`SELECT pg_advisory_xact_lock(470281941)`
|
|
1383
1488
|
await tx.unsafe(SCHEMA_DDL)
|
|
1384
|
-
await tx.unsafe(
|
|
1489
|
+
await tx.unsafe(TICKET_SCHEMA_V2_DDL)
|
|
1490
|
+
await tx.unsafe(TICKET_STATES_DDL)
|
|
1385
1491
|
await tx.unsafe(SNAPSHOT_SCHEMA_DDL)
|
|
1386
1492
|
await tx.unsafe(AUTH_SCHEMA_DDL)
|
|
1387
1493
|
const rows: { version: number; checksum: string }[] =
|
|
@@ -1559,6 +1665,11 @@ export async function migratePostgres(
|
|
|
1559
1665
|
SET version = ${SCHEMA_VERSION}, checksum = ${SCHEMA_CHECKSUM},
|
|
1560
1666
|
applied_at = ${new Date().toISOString()}
|
|
1561
1667
|
WHERE singleton = true`
|
|
1668
|
+
} else if (version === 13 && marker.checksum === SCHEMA_V13_CHECKSUM) {
|
|
1669
|
+
await tx`UPDATE ab_schema_migrations SET version = ${SCHEMA_VERSION}, checksum = ${SCHEMA_CHECKSUM}, applied_at = ${new Date().toISOString()} WHERE singleton = true`
|
|
1670
|
+
} else if (version === 12 && marker.checksum === SCHEMA_V12_CHECKSUM) {
|
|
1671
|
+
await tx`UPDATE ab_schema_migrations SET version = ${SCHEMA_VERSION}, checksum = ${SCHEMA_CHECKSUM},
|
|
1672
|
+
applied_at = ${new Date().toISOString()} WHERE singleton = true`
|
|
1562
1673
|
} else if (version === 11 && marker.checksum === SCHEMA_V11_CHECKSUM) {
|
|
1563
1674
|
await tx`UPDATE ab_schema_migrations SET version = ${SCHEMA_VERSION}, checksum = ${SCHEMA_CHECKSUM},
|
|
1564
1675
|
applied_at = ${new Date().toISOString()} WHERE singleton = true`
|
|
@@ -1600,8 +1711,32 @@ export async function migratePostgres(
|
|
|
1600
1711
|
ticketMarker.checksum === TICKET_SCHEMA_V1_CHECKSUM
|
|
1601
1712
|
) {
|
|
1602
1713
|
await migrateLegacyTickets(tx as SQL, options.openBlobs)
|
|
1714
|
+
await tx`ALTER TABLE ab_tickets ADD COLUMN IF NOT EXISTS revision bigint NOT NULL DEFAULT 1`
|
|
1715
|
+
await migrateReadableTickets(tx as SQL, options.openBlobs)
|
|
1603
1716
|
await tx`UPDATE ab_ticket_schema_migrations SET version = ${TICKET_SCHEMA_VERSION},
|
|
1604
1717
|
checksum = ${TICKET_SCHEMA_CHECKSUM}, applied_at = ${new Date().toISOString()} WHERE singleton = true`
|
|
1718
|
+
} else if (
|
|
1719
|
+
ticketMarker &&
|
|
1720
|
+
Number(ticketMarker.version) === 2 &&
|
|
1721
|
+
ticketMarker.checksum === TICKET_SCHEMA_V2_CHECKSUM
|
|
1722
|
+
) {
|
|
1723
|
+
await tx`ALTER TABLE ab_tickets ADD COLUMN revision bigint NOT NULL DEFAULT 1`
|
|
1724
|
+
await migrateReadableTickets(tx as SQL, options.openBlobs)
|
|
1725
|
+
await tx`UPDATE ab_ticket_schema_migrations SET version = ${TICKET_SCHEMA_VERSION}, checksum = ${TICKET_SCHEMA_CHECKSUM}, applied_at = ${new Date().toISOString()} WHERE singleton = true`
|
|
1726
|
+
} else if (
|
|
1727
|
+
ticketMarker &&
|
|
1728
|
+
Number(ticketMarker.version) === 3 &&
|
|
1729
|
+
ticketMarker.checksum === TICKET_SCHEMA_V3_CHECKSUM
|
|
1730
|
+
) {
|
|
1731
|
+
await migrateReadableTickets(tx as SQL, options.openBlobs)
|
|
1732
|
+
await tx`UPDATE ab_ticket_schema_migrations SET version = ${TICKET_SCHEMA_VERSION}, checksum = ${TICKET_SCHEMA_CHECKSUM}, applied_at = ${new Date().toISOString()} WHERE singleton = true`
|
|
1733
|
+
} else if (
|
|
1734
|
+
ticketMarker &&
|
|
1735
|
+
Number(ticketMarker.version) === 4 &&
|
|
1736
|
+
ticketMarker.checksum === TICKET_SCHEMA_V4_CHECKSUM
|
|
1737
|
+
) {
|
|
1738
|
+
await migrateReadableTickets(tx as SQL, options.openBlobs)
|
|
1739
|
+
await tx`UPDATE ab_ticket_schema_migrations SET version = ${TICKET_SCHEMA_VERSION}, checksum = ${TICKET_SCHEMA_CHECKSUM}, applied_at = ${new Date().toISOString()} WHERE singleton = true`
|
|
1605
1740
|
} else if (ticketMarker) {
|
|
1606
1741
|
if (Number(ticketMarker.version) !== TICKET_SCHEMA_VERSION) {
|
|
1607
1742
|
throw schemaError(
|
|
@@ -1615,10 +1750,19 @@ export async function migratePostgres(
|
|
|
1615
1750
|
)
|
|
1616
1751
|
}
|
|
1617
1752
|
} else {
|
|
1753
|
+
await tx`ALTER TABLE ab_tickets ADD COLUMN IF NOT EXISTS revision bigint NOT NULL DEFAULT 1`
|
|
1754
|
+
await migrateReadableTickets(tx as SQL, options.openBlobs)
|
|
1618
1755
|
await tx`INSERT INTO ab_ticket_schema_migrations
|
|
1619
1756
|
(singleton, version, checksum, applied_at)
|
|
1620
1757
|
VALUES (true, ${TICKET_SCHEMA_VERSION}, ${TICKET_SCHEMA_CHECKSUM}, ${new Date().toISOString()})`
|
|
1621
1758
|
}
|
|
1759
|
+
await tx`INSERT INTO ab_ticket_states (repo, name)
|
|
1760
|
+
SELECT DISTINCT repo, state FROM ab_tickets ON CONFLICT DO NOTHING`
|
|
1761
|
+
await tx`INSERT INTO ab_ticket_states (repo, name)
|
|
1762
|
+
SELECT p.repo, value FROM project_ticket_policy p,
|
|
1763
|
+
LATERAL jsonb_each_text(p.policy->'tickets') AS field(key, value)
|
|
1764
|
+
WHERE key IN ('triageState', 'readyState', 'claimedState', 'doneState', 'createState', 'proposalState')
|
|
1765
|
+
ON CONFLICT DO NOTHING`
|
|
1622
1766
|
const authRows: { version: number; checksum: string }[] =
|
|
1623
1767
|
await tx`SELECT version, checksum FROM ab_auth_schema_migrations WHERE singleton = true FOR UPDATE`
|
|
1624
1768
|
const authMarker = authRows[0]
|