feat(schema): commits collection and project ingest fields

This commit is contained in:
Dave 2026-09-16 11:46:57 +02:00
parent b8cd766c89
commit a05c1b8ae0
2 changed files with 143 additions and 0 deletions

View file

@ -516,6 +516,81 @@ async function main(): Promise<void> {
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<void> {
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<Record<string, unknown>> = [];
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.");
}

View file

@ -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<BaseRecord, "updated"> {
project: string;
card: string;