From a05c1b8ae08e067573f00f4316763e0995d6c787 Mon Sep 17 00:00:00 2001 From: Dave Date: Wed, 16 Sep 2026 11:46:57 +0200 Subject: [PATCH] feat(schema): commits collection and project ingest fields --- scripts/setup-remote.ts | 118 ++++++++++++++++++++++++++++++++++++++++ src/lib/pb/types.ts | 25 +++++++++ 2 files changed, 143 insertions(+) diff --git a/scripts/setup-remote.ts b/scripts/setup-remote.ts index f6135cb..1957705 100644 --- a/scripts/setup-remote.ts +++ b/scripts/setup-remote.ts @@ -516,6 +516,81 @@ async function main(): Promise { deleteRule: null, }); + // 9. commits — ingest target. Created via webhook/poll/backfill only; never + // from a browser. + await getOrCreateCollection(pb, { + name: "commits", + type: "base", + listRule: AUTHED, + viewRule: AUTHED, + createRule: null, + updateRule: null, + deleteRule: null, + fields: [ + { + name: "project", + type: "relation", + required: true, + collectionId: (await pb.collections.getOne("projects")).id, + cascadeDelete: true, + minSelect: 0, + maxSelect: 1, + }, + { name: "sha", type: "text", required: true, max: 64 }, + { name: "short_sha", type: "text", required: false, max: 12 }, + { name: "message", type: "text", required: false, max: 50000 }, + { + name: "subject", + type: "text", + required: false, + max: 300, + presentable: true, + }, + { name: "type", type: "text", required: false, max: 30 }, + { name: "scope", type: "text", required: false, max: 60 }, + { name: "author_name", type: "text", required: false, max: 200 }, + { name: "author_email", type: "text", required: false, max: 200 }, + { name: "authored_at", type: "date", required: true }, + { name: "is_merge", type: "bool", required: false }, + { name: "additions", type: "number", required: false }, + { name: "deletions", type: "number", required: false }, + { + name: "card", + type: "relation", + required: false, + collectionId: (await pb.collections.getOne("cards")).id, + cascadeDelete: false, + minSelect: 0, + maxSelect: 1, + }, + { + name: "link_source", + type: "select", + required: false, + maxSelect: 1, + values: ["explicit", "scope", "manual", "none"], + }, + { name: "url", type: "url", required: false }, + { + name: "created", + type: "autodate", + onCreate: true, + onUpdate: false, + }, + { + name: "updated", + type: "autodate", + onCreate: true, + onUpdate: true, + }, + ], + indexes: [ + "CREATE UNIQUE INDEX idx_commits_project_sha ON commits (project, sha)", + "CREATE INDEX idx_commits_project_date ON commits (project, authored_at)", + "CREATE INDEX idx_commits_card ON commits (card)", + ], + }); + /** * The users collection. Do not leave this on PocketBase's defaults. * @@ -542,6 +617,49 @@ async function main(): Promise { deleteRule: null, }); + await applyRules(pb, "commits", { + listRule: scopedRead("project.client"), + viewRule: scopedRead("project.client"), + createRule: null, + updateRule: null, + deleteRule: null, + }); + + // Add ingest-related fields to projects (only if missing — the projects + // collection already exists from earlier migrations). + const projects = await pb.collections.getOne("projects"); + const haveProjectFields = new Set( + projects.fields.map((f: { name: string }) => f.name) + ); + const projectFieldAdditions: Array> = []; + if (!haveProjectFields.has("webhook_secret")) { + projectFieldAdditions.push({ + name: "webhook_secret", + type: "text", + required: false, + max: 80, + }); + } + if (!haveProjectFields.has("last_ingest_at")) { + projectFieldAdditions.push({ + name: "last_ingest_at", + type: "date", + required: false, + }); + } + if (projectFieldAdditions.length > 0) { + await pb.collections.update(projects.id, { + fields: [...(projects.fields as unknown[]), ...projectFieldAdditions], + }); + console.log( + ` + projects fields: ${projectFieldAdditions + .map((f) => (f as { name: string }).name) + .join(", ")}` + ); + } else { + console.log(" = projects ingest fields already present"); + } + console.log("Done."); } diff --git a/src/lib/pb/types.ts b/src/lib/pb/types.ts index f16256c..59cdd0c 100644 --- a/src/lib/pb/types.ts +++ b/src/lib/pb/types.ts @@ -49,6 +49,9 @@ export interface ProjectRecord extends BaseRecord { repo_owner: string; repo_name: string; repo_url: string; + /** Server-only. Must never appear in a browser payload. */ + webhook_secret: string; + last_ingest_at: string; } export interface ColumnRecord extends BaseRecord { @@ -89,6 +92,28 @@ export interface CommentRecord extends BaseRecord { body: string; } +export type CommitLinkSource = "explicit" | "scope" | "manual" | "none"; + +export interface CommitRecord extends BaseRecord { + project: string; + sha: string; + short_sha: string; + message: string; + subject: string; + type: string; + scope: string; + author_name: string; + author_email: string; + /** Authoring time, not commit or ingest time. See the API notes. */ + authored_at: string; + is_merge: boolean; + additions: number; + deletions: number; + card: string; + link_source: CommitLinkSource; + url: string; +} + export interface ActivityRecord extends Omit { project: string; card: string;