Skip to content
File

Blob: src/worker/db/d1/schema/patNamespaceGrants.ts

typescript34 lines
1import { sql } from "drizzle-orm";
2import { check, index, primaryKey, sqliteTable, text } from "drizzle-orm/sqlite-core";
3 
4import { namespaces } from "./namespaces";
5import { personalAccessTokens } from "./personalAccessTokens";
6 
7// Permission level granted by a PAT to a namespace or repository. `push`
8// includes everything `pull` allows; absence of a grant row encodes
9// no-access. The DB CHECK constraint is the structural guard so callers
10// (DAL, verifier, API, UI) can trust the value without defensive code.
11export type PatGrantLevel = "pull" | "push";
12 
13// PAT scoped to an entire namespace.
14export const patNamespaceGrants = sqliteTable(
15 "pat_namespace_grants",
16 {
17 patId: text("pat_id")
18 .notNull()
19 .references(() => personalAccessTokens.id, { onDelete: "cascade" }),
20 namespaceId: text("namespace_id")
21 .notNull()
22 .references(() => namespaces.id, { onDelete: "cascade" }),
23 level: text("level").$type<PatGrantLevel>().notNull(),
24 },
25 (table) => [
26 primaryKey({ columns: [table.patId, table.namespaceId] }),
27 index("idx_pat_namespace_grants_namespace").on(table.namespaceId),
28 check("chk_pat_namespace_grants_level", sql`"level" IN ('pull','push')`),
29 ]
30);
31 
32export type PatNamespaceGrantRow = typeof patNamespaceGrants.$inferSelect;
33export type NewPatNamespaceGrantRow = typeof patNamespaceGrants.$inferInsert;