From cbc76b03b1aea7676a26ebc9f5db58237e7b72f6 Mon Sep 17 00:00:00 2001 From: Amruth Pillai Date: Tue, 29 Sep 2026 08:34:27 +0200 Subject: [PATCH] refactor!: contract the redesign's legacy fields The expand steps of the redesign kept older app versions and API clients working. This removes those compatibility paths: - Entry date text (period/date) is written from the structured dates on every save; an edit to the text alone is overwritten. - application.archived is dropped; archived rows close first. CSV import still reads the flag from older exports. - resume_version.label is dropped; versions are named by kind and name. - rejected is no longer accepted as a stage; remaining rows and history close first. CSV import still maps it to closed. BREAKING CHANGE: older app versions and API clients that read or write archived, version labels, the rejected stage or date text alone no longer work. migrations/20260929063245_contract_redesign_legacy_fields has a rollback.sql that restores the dropped columns. --- REDESIGN_PLAN.md | 8 +- .../features/applications/csv-export.test.ts | 6 +- apps/web/src/features/applications/csv.ts | 11 +- apps/web/src/features/applications/queries.ts | 5 +- .../command-palette/pages/resumes.test.tsx | 18 +- apps/web/src/features/resume/builder/draft.ts | 6 +- docs/guides/json-resume-schema.mdx | 32 +- docs/spec.json | 312 +- .../migration.sql | 18 + .../rollback.sql | 15 + .../snapshot.json | 7143 +++++++++++++++++ packages/api/src/dto/application.ts | 15 +- packages/api/src/dto/resume.ts | 1 - .../api/src/features/applications/crud.ts | 3 +- .../src/features/applications/service.test.ts | 2 +- .../api/src/features/applications/service.ts | 16 +- .../features/resume/resume-data-validation.ts | 10 +- .../api/src/features/resume/service.test.ts | 1 - packages/api/src/features/resume/service.ts | 8 +- .../features/resume/version-history.test.ts | 11 +- .../src/features/resume/version-history.ts | 16 +- packages/db/src/schema/applications.ts | 2 - packages/db/src/schema/resume.ts | 2 - packages/mcp/src/mcp-server-card.test.ts | 4 +- packages/mcp/src/tool-meta.ts | 5 +- packages/mcp/src/tools.test.ts | 4 +- packages/schema/src/applications/data.ts | 9 +- packages/schema/src/resume/data.ts | 20 +- packages/schema/src/resume/dates.test.ts | 14 +- packages/schema/src/resume/dates.ts | 38 +- skills/resume-builder/references/schema.md | 32 +- tests/e2e/specs/applications-export.spec.ts | 20 +- 32 files changed, 7412 insertions(+), 395 deletions(-) create mode 100644 migrations/20260929063245_contract_redesign_legacy_fields/migration.sql create mode 100644 migrations/20260929063245_contract_redesign_legacy_fields/rollback.sql create mode 100644 migrations/20260929063245_contract_redesign_legacy_fields/snapshot.json diff --git a/REDESIGN_PLAN.md b/REDESIGN_PLAN.md index 4c14ae0fa..6db8aaed5 100644 --- a/REDESIGN_PLAN.md +++ b/REDESIGN_PLAN.md @@ -235,7 +235,13 @@ Today `cover_letter` has name, recipient (rich-text HTML), content (HTML), `styl | M8 | `application.closed_reason`, `cover_letter_id`, `sent_*`, `requirements` | `rejected`/`archived` → `closed` | Reverse script | | M9 | `cover_letter.sender_linked`, `design_linked`, `recipient_name`, `recipient_company`, `letter_date`, `layout`; `cover_letter_version` | Existing letters → freeform, unlinked | Additive | -Contract steps, not done without your approval: stop dual-writing `period`/`date`; drop `application.archived`; drop `resume_version.label`; drop `rejected` from the stage enum. +Contract steps (approved on 29 Sep 2026, migration `20260929063245_contract_redesign_legacy_fields`, with `rollback.sql`): + +- **`period`/`date` are written from `dates` only.** The text stays in the data as printed output, rewritten from the dates on every save; an edit to the text alone is overwritten. Entries without dates (imports, older data) still get dates from their text. +- **`application.archived` is dropped.** Rows still archived are closed first. The list, bulk update, MCP tools and CSV export lose the flag; CSV import still reads it from older exports as closed. +- **`resume_version.label` is dropped.** Versions are named by `kind` and `name`. +- **`rejected` is no longer accepted as a stage.** Remaining rows and history close first; CSV import still reads it from older exports. +- Older app versions and API clients that relied on these stop working against this schema. --- diff --git a/apps/web/src/features/applications/csv-export.test.ts b/apps/web/src/features/applications/csv-export.test.ts index ffeaf6ee5..3828ca6b8 100644 --- a/apps/web/src/features/applications/csv-export.test.ts +++ b/apps/web/src/features/applications/csv-export.test.ts @@ -7,7 +7,6 @@ const application: Application = { company: 'Müller, "Partners"', role: "Engineer", status: "interview", - archived: false, closedReason: null, coverLetterId: null, sentResumeVersionId: null, @@ -75,7 +74,6 @@ describe("application CSV export", () => { "Stage History": "Applied (2026-08-03) → Interview (2026-08-12)", Timeline: "2026-08-03: Applied\n2026-08-08: Called recruiter\n2026-08-12: Interview", Contacts: "Ada (Recruiter, Referral)", - Archived: "false", }); expect(application.activity[0]?.id).toBe("interview"); }); @@ -138,10 +136,10 @@ describe("application CSV export", () => { describe("application export selection", () => { const early = { ...application, id: "early", appliedAt: new Date("2026-08-02T23:59:59Z") }; - const late = { ...application, id: "late", archived: true, appliedAt: new Date("2026-08-03T23:59:59Z") }; + const late = { ...application, id: "late", status: "closed" as const, appliedAt: new Date("2026-08-03T23:59:59Z") }; const all = [early, application, late]; - it("exports exactly current filtered rows, or all rows including archived", () => { + it("exports exactly current filtered rows, or all rows including closed ones", () => { expect(selectApplicationsForExport(all, [application], { scope: "filtered" })).toEqual([application]); expect(selectApplicationsForExport(all, [application], { scope: "all" })).toEqual(all); }); diff --git a/apps/web/src/features/applications/csv.ts b/apps/web/src/features/applications/csv.ts index dcd87337a..22d48ac1e 100644 --- a/apps/web/src/features/applications/csv.ts +++ b/apps/web/src/features/applications/csv.ts @@ -1,7 +1,7 @@ import type { ApplicationStatus, Contact } from "@reactive-resume/schema/applications/data"; import type { Application } from "./types"; import { - applicationStatusInputSchema, + applicationStatusSchema, contactSchema, INTERVIEW_KINDS, STAGES, @@ -207,7 +207,8 @@ export function mapCsvToApplications(table: string[][], mapping?: readonly (CsvF // The confirmed match, else the automatic one. const fieldFor = mapping ?? autoMapHeaders(headers); const recognized = [...new Set(fieldFor.filter((f): f is CsvField => !!f))]; - const isReactiveResumeExport = ["Stage History", "Timeline", "Archived", "Created At", "Updated At"].every((header) => + // Older exports also carry an Archived column. + const isReactiveResumeExport = ["Stage History", "Timeline", "Created At", "Updated At"].every((header) => headers.includes(header), ); @@ -224,7 +225,9 @@ export function mapCsvToApplications(table: string[][], mapping?: readonly (CsvF if (!value) return; if (field === "tags") record.tags = parseTags(value); else if (field === "status") { - const parsed = applicationStatusInputSchema.safeParse(value.toLowerCase()); + // Older exports may still say `rejected`, the stage `closed` replaced. + const stage = value.toLowerCase(); + const parsed = applicationStatusSchema.safeParse(stage === "rejected" ? "closed" : stage); if (parsed.success) record.status = parsed.data; } else if (field === "stageEnteredAt") { record.stageEnteredAt = dateOnly(value); @@ -297,7 +300,6 @@ export function exportApplicationsCsv(applications: readonly Application[]): str "Closed Reason", "Stage History", "Timeline", - "Archived", "Created At", "Updated At", ]; @@ -334,7 +336,6 @@ export function exportApplicationsCsv(applications: readonly Application[]): str application.closedReason ?? "", stages.map((entry) => `${stageLabel(entry.stage)} (${dateOnly(entry.at)})`).join(" → "), timeline.map((entry) => `${dateOnly(entry.at)}: ${timelineText(entry)}`).join("\n"), - String(application.archived), new Date(application.createdAt).toISOString(), new Date(application.updatedAt).toISOString(), ]; diff --git a/apps/web/src/features/applications/queries.ts b/apps/web/src/features/applications/queries.ts index b55a0b57f..a2ccdfd04 100644 --- a/apps/web/src/features/applications/queries.ts +++ b/apps/web/src/features/applications/queries.ts @@ -1,9 +1,8 @@ import { orpc } from "@/libs/orpc/client"; // A single source of truth for the applications list query so the query key stays identical -// across the board (optimistic drag), the detail panel, and the route. We always fetch archived -// rows too and filter them per-view client-side, so "unarchive" has something to act on. -const LIST_INPUT = { includeArchived: true } as const; +// across the board (optimistic drag), the detail panel, and the route. +const LIST_INPUT = {} as const; export const applicationsListQueryOptions = () => orpc.applications.list.queryOptions({ input: LIST_INPUT }); export const applicationsListQueryKey = () => orpc.applications.list.queryKey({ input: LIST_INPUT }); diff --git a/apps/web/src/features/command-palette/pages/resumes.test.tsx b/apps/web/src/features/command-palette/pages/resumes.test.tsx index 7bedac606..a4585ccee 100644 --- a/apps/web/src/features/command-palette/pages/resumes.test.tsx +++ b/apps/web/src/features/command-palette/pages/resumes.test.tsx @@ -110,8 +110,7 @@ describe("ResumesCommandGroup", () => { ])("opens the %s list page from the root palette with Enter", async (page, keys, createLabel) => { mockUseQueryData((entity) => { if (entity === "resumes") return [{ id: "resume-1", name: "Evil Apricot Pike", slug: "apricot" }]; - if (entity === "applications") - return [{ id: "application-1", company: "Umbrella", role: "Staff Engineer", archived: false }]; + if (entity === "applications") return [{ id: "application-1", company: "Umbrella", role: "Staff Engineer" }]; if (entity === "threads") return [{ id: "thread-1", title: "Cover letter rewrite", resumeName: "Product Resume" }]; return []; @@ -133,8 +132,7 @@ describe("ResumesCommandGroup", () => { ])("keeps arrow-key navigation active on the %s list page", async (_page, keys, createLabel, itemLabel) => { mockUseQueryData((entity) => { if (entity === "resumes") return [{ id: "resume-1", name: "Evil Apricot Pike", slug: "apricot" }]; - if (entity === "applications") - return [{ id: "application-1", company: "Umbrella", role: "Staff Engineer", archived: false }]; + if (entity === "applications") return [{ id: "application-1", company: "Umbrella", role: "Staff Engineer" }]; if (entity === "threads") return [{ id: "thread-1", title: "Cover letter rewrite", resumeName: "Product Resume" }]; return []; @@ -201,9 +199,7 @@ describe("ResumesCommandGroup", () => { it("loads applications on the applications page", () => { useCommandPaletteStore.setState({ pages: ["applications"] }); mockUseQueryData((entity) => - entity === "applications" - ? [{ id: "application-1", company: "Umbrella", role: "Staff Engineer", archived: false }] - : [], + entity === "applications" ? [{ id: "application-1", company: "Umbrella", role: "Staff Engineer" }] : [], ); renderGroup(); @@ -217,8 +213,8 @@ describe("ResumesCommandGroup", () => { mockUseQueryData((entity) => entity === "applications" ? [ - { id: "application-1", company: "Umbrella", role: "Staff Engineer", archived: false }, - { id: "application-2", company: "Wayne Enterprises", role: "Product Engineer", archived: false }, + { id: "application-1", company: "Umbrella", role: "Staff Engineer" }, + { id: "application-2", company: "Wayne Enterprises", role: "Product Engineer" }, ] : [], ); @@ -232,9 +228,7 @@ describe("ResumesCommandGroup", () => { it("opens the selected application by id", () => { useCommandPaletteStore.setState({ pages: ["applications"] }); mockUseQueryData((entity) => - entity === "applications" - ? [{ id: "application-1", company: "Umbrella", role: "Staff Engineer", archived: false }] - : [], + entity === "applications" ? [{ id: "application-1", company: "Umbrella", role: "Staff Engineer" }] : [], ); renderGroup(); diff --git a/apps/web/src/features/resume/builder/draft.ts b/apps/web/src/features/resume/builder/draft.ts index b895d77b5..08f30beb1 100644 --- a/apps/web/src/features/resume/builder/draft.ts +++ b/apps/web/src/features/resume/builder/draft.ts @@ -565,9 +565,9 @@ export const useResumeStore = create()( } fn(state.resume.data as WritableDraft); - // The server keeps dates and their legacy text in step on save; doing the same here keeps its - // echo identical to the draft, so an autosave never reads as an outside change. - syncResumeDates(state.resume.data as ResumeData, currentResume.data); + // The server writes the date text from the dates on save; doing the same here keeps its echo + // identical to the draft, so an autosave never reads as an outside change. + syncResumeDates(state.resume.data as ResumeData); state.saveStatus = "saving"; state.canUndo = state.undoStack.length > 0; state.canRedo = state.redoStack.length > 0; diff --git a/docs/guides/json-resume-schema.mdx b/docs/guides/json-resume-schema.mdx index 96c2d0a91..dfdcb8ae4 100644 --- a/docs/guides/json-resume-schema.mdx +++ b/docs/guides/json-resume-schema.mdx @@ -559,7 +559,7 @@ The full JSON Schema for Reactive Resume follows. You can also fetch the latest }, "period": { "type": "string", - "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Kept in sync from `dates`; prefer writing `dates`." + "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -659,7 +659,7 @@ The full JSON Schema for Reactive Resume follows. You can also fetch the latest }, "period": { "type": "string", - "description": "The period of time this role was held, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time this role was held, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -822,7 +822,7 @@ The full JSON Schema for Reactive Resume follows. You can also fetch the latest }, "period": { "type": "string", - "description": "The period of time the education was obtained over, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the education was obtained over, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -990,7 +990,7 @@ The full JSON Schema for Reactive Resume follows. You can also fetch the latest }, "period": { "type": "string", - "description": "The period of time the project was worked on, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the project was worked on, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -1470,7 +1470,7 @@ The full JSON Schema for Reactive Resume follows. You can also fetch the latest }, "date": { "type": "string", - "description": "The date when the award was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the award was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -1639,7 +1639,7 @@ The full JSON Schema for Reactive Resume follows. You can also fetch the latest }, "date": { "type": "string", - "description": "The date when the certification was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the certification was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -1808,7 +1808,7 @@ The full JSON Schema for Reactive Resume follows. You can also fetch the latest }, "date": { "type": "string", - "description": "The date when the publication was published, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the publication was published, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -1977,7 +1977,7 @@ The full JSON Schema for Reactive Resume follows. You can also fetch the latest }, "period": { "type": "string", - "description": "The period of time the author was volunteered at the organization or company, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the author was volunteered at the organization or company, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -2617,7 +2617,7 @@ The full JSON Schema for Reactive Resume follows. You can also fetch the latest }, "period": { "type": "string", - "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Kept in sync from `dates`; prefer writing `dates`." + "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -2717,7 +2717,7 @@ The full JSON Schema for Reactive Resume follows. You can also fetch the latest }, "period": { "type": "string", - "description": "The period of time this role was held, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time this role was held, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -2892,7 +2892,7 @@ The full JSON Schema for Reactive Resume follows. You can also fetch the latest }, "period": { "type": "string", - "description": "The period of time the education was obtained over, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the education was obtained over, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -3072,7 +3072,7 @@ The full JSON Schema for Reactive Resume follows. You can also fetch the latest }, "period": { "type": "string", - "description": "The period of time the project was worked on, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the project was worked on, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -3590,7 +3590,7 @@ The full JSON Schema for Reactive Resume follows. You can also fetch the latest }, "date": { "type": "string", - "description": "The date when the award was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the award was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -3771,7 +3771,7 @@ The full JSON Schema for Reactive Resume follows. You can also fetch the latest }, "date": { "type": "string", - "description": "The date when the certification was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the certification was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -3952,7 +3952,7 @@ The full JSON Schema for Reactive Resume follows. You can also fetch the latest }, "date": { "type": "string", - "description": "The date when the publication was published, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the publication was published, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -4133,7 +4133,7 @@ The full JSON Schema for Reactive Resume follows. You can also fetch the latest }, "period": { "type": "string", - "description": "The period of time the author was volunteered at the organization or company, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the author was volunteered at the organization or company, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", diff --git a/docs/spec.json b/docs/spec.json index d76add484..0d7d0bde5 100644 --- a/docs/spec.json +++ b/docs/spec.json @@ -2523,7 +2523,7 @@ "get": { "operationId": "listApplications", "summary": "List job applications", - "description": "Returns all job applications belonging to the authenticated user, most recently updated first. Archived applications are excluded unless includeArchived is set. Optionally filter by pipeline stage. Requires authentication.", + "description": "Returns all job applications belonging to the authenticated user, most recently updated first. Optionally filter by pipeline stage. Requires authentication.", "tags": [ "Applications" ], @@ -2558,16 +2558,6 @@ "explode": true, "allowEmptyValue": true, "allowReserved": true - }, - { - "name": "includeArchived", - "in": "query", - "schema": { - "type": "boolean", - "default": false - }, - "allowEmptyValue": true, - "allowReserved": true } ], "responses": { @@ -2643,10 +2633,6 @@ ], "description": "Why a closed application ended: not-selected, withdrew, accepted-other or no-response." }, - "archived": { - "type": "boolean", - "description": "Deprecated: the closed stage replaced it. Kept in step for older clients." - }, "resumeId": { "anyOf": [ { @@ -3019,7 +3005,6 @@ "salary", "status", "closedReason", - "archived", "resumeId", "coverLetterId", "sentResumeVersionId", @@ -3410,10 +3395,6 @@ ], "description": "Why a closed application ended: not-selected, withdrew, accepted-other or no-response." }, - "archived": { - "type": "boolean", - "description": "Deprecated: the closed stage replaced it. Kept in step for older clients." - }, "resumeId": { "anyOf": [ { @@ -3786,7 +3767,6 @@ "salary", "status", "closedReason", - "archived", "resumeId", "coverLetterId", "sentResumeVersionId", @@ -4068,9 +4048,6 @@ } ], "description": "Why the application closed; kept when status stays closed, cleared by any other stage." - }, - "archived": { - "type": "boolean" } } } @@ -4148,10 +4125,6 @@ ], "description": "Why a closed application ended: not-selected, withdrew, accepted-other or no-response." }, - "archived": { - "type": "boolean", - "description": "Deprecated: the closed stage replaced it. Kept in step for older clients." - }, "resumeId": { "anyOf": [ { @@ -4524,7 +4497,6 @@ "salary", "status", "closedReason", - "archived", "resumeId", "coverLetterId", "sentResumeVersionId", @@ -5004,10 +4976,6 @@ ], "description": "Why a closed application ended: not-selected, withdrew, accepted-other or no-response." }, - "archived": { - "type": "boolean", - "description": "Deprecated: the closed stage replaced it. Kept in step for older clients." - }, "resumeId": { "anyOf": [ { @@ -5380,7 +5348,6 @@ "salary", "status", "closedReason", - "archived", "resumeId", "coverLetterId", "sentResumeVersionId", @@ -5512,10 +5479,6 @@ ], "description": "Why a closed application ended: not-selected, withdrew, accepted-other or no-response." }, - "archived": { - "type": "boolean", - "description": "Deprecated: the closed stage replaced it. Kept in step for older clients." - }, "resumeId": { "anyOf": [ { @@ -5888,7 +5851,6 @@ "salary", "status", "closedReason", - "archived", "resumeId", "coverLetterId", "sentResumeVersionId", @@ -6033,10 +5995,6 @@ ], "description": "Why a closed application ended: not-selected, withdrew, accepted-other or no-response." }, - "archived": { - "type": "boolean", - "description": "Deprecated: the closed stage replaced it. Kept in step for older clients." - }, "resumeId": { "anyOf": [ { @@ -6409,7 +6367,6 @@ "salary", "status", "closedReason", - "archived", "resumeId", "coverLetterId", "sentResumeVersionId", @@ -6578,10 +6535,6 @@ ], "description": "Why a closed application ended: not-selected, withdrew, accepted-other or no-response." }, - "archived": { - "type": "boolean", - "description": "Deprecated: the closed stage replaced it. Kept in step for older clients." - }, "resumeId": { "anyOf": [ { @@ -6954,7 +6907,6 @@ "salary", "status", "closedReason", - "archived", "resumeId", "coverLetterId", "sentResumeVersionId", @@ -7124,10 +7076,6 @@ ], "description": "Why a closed application ended: not-selected, withdrew, accepted-other or no-response." }, - "archived": { - "type": "boolean", - "description": "Deprecated: the closed stage replaced it. Kept in step for older clients." - }, "resumeId": { "anyOf": [ { @@ -7500,7 +7448,6 @@ "salary", "status", "closedReason", - "archived", "resumeId", "coverLetterId", "sentResumeVersionId", @@ -7650,10 +7597,6 @@ ], "description": "Why a closed application ended: not-selected, withdrew, accepted-other or no-response." }, - "archived": { - "type": "boolean", - "description": "Deprecated: the closed stage replaced it. Kept in step for older clients." - }, "resumeId": { "anyOf": [ { @@ -8026,7 +7969,6 @@ "salary", "status", "closedReason", - "archived", "resumeId", "coverLetterId", "sentResumeVersionId", @@ -8154,10 +8096,6 @@ ], "description": "Why a closed application ended: not-selected, withdrew, accepted-other or no-response." }, - "archived": { - "type": "boolean", - "description": "Deprecated: the closed stage replaced it. Kept in step for older clients." - }, "resumeId": { "anyOf": [ { @@ -8530,7 +8468,6 @@ "salary", "status", "closedReason", - "archived", "resumeId", "coverLetterId", "sentResumeVersionId", @@ -8613,9 +8550,6 @@ } ] }, - "archived": { - "type": "boolean" - }, "addTags": { "type": "array", "items": { @@ -20307,7 +20241,7 @@ }, "period": { "type": "string", - "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Kept in sync from `dates`; prefer writing `dates`." + "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -20396,7 +20330,7 @@ }, "period": { "type": "string", - "description": "The period of time this role was held, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time this role was held, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -20552,7 +20486,7 @@ }, "period": { "type": "string", - "description": "The period of time the education was obtained over, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the education was obtained over, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -20706,7 +20640,7 @@ }, "period": { "type": "string", - "description": "The period of time the project was worked on, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the project was worked on, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -21035,7 +20969,7 @@ }, "date": { "type": "string", - "description": "The date when the award was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the award was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -21190,7 +21124,7 @@ }, "date": { "type": "string", - "description": "The date when the certification was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the certification was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -21345,7 +21279,7 @@ }, "date": { "type": "string", - "description": "The date when the publication was published, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the publication was published, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -21500,7 +21434,7 @@ }, "period": { "type": "string", - "description": "The period of time the author was volunteered at the organization or company, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the author was volunteered at the organization or company, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -22096,7 +22030,7 @@ }, "period": { "type": "string", - "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Kept in sync from `dates`; prefer writing `dates`." + "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -22185,7 +22119,7 @@ }, "period": { "type": "string", - "description": "The period of time this role was held, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time this role was held, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -22354,7 +22288,7 @@ }, "period": { "type": "string", - "description": "The period of time the education was obtained over, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the education was obtained over, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -22521,7 +22455,7 @@ }, "period": { "type": "string", - "description": "The period of time the project was worked on, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the project was worked on, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -23006,7 +22940,7 @@ }, "date": { "type": "string", - "description": "The date when the award was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the award was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -23174,7 +23108,7 @@ }, "date": { "type": "string", - "description": "The date when the certification was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the certification was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -23342,7 +23276,7 @@ }, "date": { "type": "string", - "description": "The date when the publication was published, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the publication was published, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -23510,7 +23444,7 @@ }, "period": { "type": "string", - "description": "The period of time the author was volunteered at the organization or company, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the author was volunteered at the organization or company, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -24674,7 +24608,7 @@ }, "period": { "type": "string", - "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Kept in sync from `dates`; prefer writing `dates`." + "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -24763,7 +24697,7 @@ }, "period": { "type": "string", - "description": "The period of time this role was held, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time this role was held, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -24919,7 +24853,7 @@ }, "period": { "type": "string", - "description": "The period of time the education was obtained over, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the education was obtained over, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -25073,7 +25007,7 @@ }, "period": { "type": "string", - "description": "The period of time the project was worked on, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the project was worked on, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -25402,7 +25336,7 @@ }, "date": { "type": "string", - "description": "The date when the award was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the award was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -25557,7 +25491,7 @@ }, "date": { "type": "string", - "description": "The date when the certification was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the certification was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -25712,7 +25646,7 @@ }, "date": { "type": "string", - "description": "The date when the publication was published, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the publication was published, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -25867,7 +25801,7 @@ }, "period": { "type": "string", - "description": "The period of time the author was volunteered at the organization or company, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the author was volunteered at the organization or company, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -26463,7 +26397,7 @@ }, "period": { "type": "string", - "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Kept in sync from `dates`; prefer writing `dates`." + "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -26552,7 +26486,7 @@ }, "period": { "type": "string", - "description": "The period of time this role was held, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time this role was held, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -26721,7 +26655,7 @@ }, "period": { "type": "string", - "description": "The period of time the education was obtained over, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the education was obtained over, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -26888,7 +26822,7 @@ }, "period": { "type": "string", - "description": "The period of time the project was worked on, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the project was worked on, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -27373,7 +27307,7 @@ }, "date": { "type": "string", - "description": "The date when the award was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the award was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -27541,7 +27475,7 @@ }, "date": { "type": "string", - "description": "The date when the certification was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the certification was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -27709,7 +27643,7 @@ }, "date": { "type": "string", - "description": "The date when the publication was published, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the publication was published, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -27877,7 +27811,7 @@ }, "period": { "type": "string", - "description": "The period of time the author was volunteered at the organization or company, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the author was volunteered at the organization or company, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -29176,7 +29110,7 @@ }, "period": { "type": "string", - "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Kept in sync from `dates`; prefer writing `dates`." + "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -29265,7 +29199,7 @@ }, "period": { "type": "string", - "description": "The period of time this role was held, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time this role was held, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -29421,7 +29355,7 @@ }, "period": { "type": "string", - "description": "The period of time the education was obtained over, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the education was obtained over, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -29575,7 +29509,7 @@ }, "period": { "type": "string", - "description": "The period of time the project was worked on, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the project was worked on, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -29904,7 +29838,7 @@ }, "date": { "type": "string", - "description": "The date when the award was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the award was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -30059,7 +29993,7 @@ }, "date": { "type": "string", - "description": "The date when the certification was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the certification was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -30214,7 +30148,7 @@ }, "date": { "type": "string", - "description": "The date when the publication was published, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the publication was published, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -30369,7 +30303,7 @@ }, "period": { "type": "string", - "description": "The period of time the author was volunteered at the organization or company, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the author was volunteered at the organization or company, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -30965,7 +30899,7 @@ }, "period": { "type": "string", - "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Kept in sync from `dates`; prefer writing `dates`." + "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -31054,7 +30988,7 @@ }, "period": { "type": "string", - "description": "The period of time this role was held, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time this role was held, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -31223,7 +31157,7 @@ }, "period": { "type": "string", - "description": "The period of time the education was obtained over, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the education was obtained over, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -31390,7 +31324,7 @@ }, "period": { "type": "string", - "description": "The period of time the project was worked on, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the project was worked on, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -31875,7 +31809,7 @@ }, "date": { "type": "string", - "description": "The date when the award was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the award was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -32043,7 +31977,7 @@ }, "date": { "type": "string", - "description": "The date when the certification was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the certification was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -32211,7 +32145,7 @@ }, "date": { "type": "string", - "description": "The date when the publication was published, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the publication was published, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -32379,7 +32313,7 @@ }, "period": { "type": "string", - "description": "The period of time the author was volunteered at the organization or company, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the author was volunteered at the organization or company, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -33649,7 +33583,7 @@ }, "period": { "type": "string", - "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Kept in sync from `dates`; prefer writing `dates`." + "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -33738,7 +33672,7 @@ }, "period": { "type": "string", - "description": "The period of time this role was held, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time this role was held, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -33894,7 +33828,7 @@ }, "period": { "type": "string", - "description": "The period of time the education was obtained over, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the education was obtained over, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -34048,7 +33982,7 @@ }, "period": { "type": "string", - "description": "The period of time the project was worked on, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the project was worked on, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -34377,7 +34311,7 @@ }, "date": { "type": "string", - "description": "The date when the award was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the award was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -34532,7 +34466,7 @@ }, "date": { "type": "string", - "description": "The date when the certification was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the certification was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -34687,7 +34621,7 @@ }, "date": { "type": "string", - "description": "The date when the publication was published, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the publication was published, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -34842,7 +34776,7 @@ }, "period": { "type": "string", - "description": "The period of time the author was volunteered at the organization or company, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the author was volunteered at the organization or company, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -35438,7 +35372,7 @@ }, "period": { "type": "string", - "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Kept in sync from `dates`; prefer writing `dates`." + "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -35527,7 +35461,7 @@ }, "period": { "type": "string", - "description": "The period of time this role was held, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time this role was held, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -35696,7 +35630,7 @@ }, "period": { "type": "string", - "description": "The period of time the education was obtained over, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the education was obtained over, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -35863,7 +35797,7 @@ }, "period": { "type": "string", - "description": "The period of time the project was worked on, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the project was worked on, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -36348,7 +36282,7 @@ }, "date": { "type": "string", - "description": "The date when the award was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the award was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -36516,7 +36450,7 @@ }, "date": { "type": "string", - "description": "The date when the certification was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the certification was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -36684,7 +36618,7 @@ }, "date": { "type": "string", - "description": "The date when the publication was published, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the publication was published, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -36852,7 +36786,7 @@ }, "period": { "type": "string", - "description": "The period of time the author was volunteered at the organization or company, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the author was volunteered at the organization or company, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -38023,10 +37957,6 @@ ], "description": "The user's name for a named version." }, - "label": { - "type": "string", - "description": "A short English description of the version." - }, "createdAt": { "type": "string", "format": "date-time", @@ -38038,7 +37968,6 @@ "id", "kind", "name", - "label", "createdAt" ] } @@ -38124,10 +38053,6 @@ ], "description": "The user's name for a named version." }, - "label": { - "type": "string", - "description": "A short English description of the version." - }, "createdAt": { "type": "string", "format": "date-time", @@ -38139,7 +38064,6 @@ "id", "kind", "name", - "label", "createdAt" ] } @@ -38214,10 +38138,6 @@ ], "description": "The user's name for a named version." }, - "label": { - "type": "string", - "description": "A short English description of the version." - }, "createdAt": { "type": "string", "format": "date-time", @@ -38610,7 +38530,7 @@ }, "period": { "type": "string", - "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Kept in sync from `dates`; prefer writing `dates`." + "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -38699,7 +38619,7 @@ }, "period": { "type": "string", - "description": "The period of time this role was held, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time this role was held, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -38855,7 +38775,7 @@ }, "period": { "type": "string", - "description": "The period of time the education was obtained over, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the education was obtained over, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -39009,7 +38929,7 @@ }, "period": { "type": "string", - "description": "The period of time the project was worked on, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the project was worked on, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -39338,7 +39258,7 @@ }, "date": { "type": "string", - "description": "The date when the award was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the award was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -39493,7 +39413,7 @@ }, "date": { "type": "string", - "description": "The date when the certification was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the certification was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -39648,7 +39568,7 @@ }, "date": { "type": "string", - "description": "The date when the publication was published, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the publication was published, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -39803,7 +39723,7 @@ }, "period": { "type": "string", - "description": "The period of time the author was volunteered at the organization or company, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the author was volunteered at the organization or company, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -40399,7 +40319,7 @@ }, "period": { "type": "string", - "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Kept in sync from `dates`; prefer writing `dates`." + "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -40488,7 +40408,7 @@ }, "period": { "type": "string", - "description": "The period of time this role was held, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time this role was held, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -40657,7 +40577,7 @@ }, "period": { "type": "string", - "description": "The period of time the education was obtained over, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the education was obtained over, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -40824,7 +40744,7 @@ }, "period": { "type": "string", - "description": "The period of time the project was worked on, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the project was worked on, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -41309,7 +41229,7 @@ }, "date": { "type": "string", - "description": "The date when the award was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the award was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -41477,7 +41397,7 @@ }, "date": { "type": "string", - "description": "The date when the certification was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the certification was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -41645,7 +41565,7 @@ }, "date": { "type": "string", - "description": "The date when the publication was published, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the publication was published, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -41813,7 +41733,7 @@ }, "period": { "type": "string", - "description": "The period of time the author was volunteered at the organization or company, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the author was volunteered at the organization or company, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -42453,7 +42373,6 @@ "id", "kind", "name", - "label", "createdAt", "data" ] @@ -42548,10 +42467,6 @@ ], "description": "The user's name for a named version." }, - "label": { - "type": "string", - "description": "A short English description of the version." - }, "createdAt": { "type": "string", "format": "date-time", @@ -42563,7 +42478,6 @@ "id", "kind", "name", - "label", "createdAt" ] } @@ -43075,7 +42989,7 @@ }, "period": { "type": "string", - "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Kept in sync from `dates`; prefer writing `dates`." + "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -43164,7 +43078,7 @@ }, "period": { "type": "string", - "description": "The period of time this role was held, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time this role was held, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -43320,7 +43234,7 @@ }, "period": { "type": "string", - "description": "The period of time the education was obtained over, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the education was obtained over, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -43474,7 +43388,7 @@ }, "period": { "type": "string", - "description": "The period of time the project was worked on, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the project was worked on, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -43803,7 +43717,7 @@ }, "date": { "type": "string", - "description": "The date when the award was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the award was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -43958,7 +43872,7 @@ }, "date": { "type": "string", - "description": "The date when the certification was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the certification was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -44113,7 +44027,7 @@ }, "date": { "type": "string", - "description": "The date when the publication was published, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the publication was published, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -44268,7 +44182,7 @@ }, "period": { "type": "string", - "description": "The period of time the author was volunteered at the organization or company, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the author was volunteered at the organization or company, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -44864,7 +44778,7 @@ }, "period": { "type": "string", - "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Kept in sync from `dates`; prefer writing `dates`." + "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -44953,7 +44867,7 @@ }, "period": { "type": "string", - "description": "The period of time this role was held, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time this role was held, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -45122,7 +45036,7 @@ }, "period": { "type": "string", - "description": "The period of time the education was obtained over, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the education was obtained over, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -45289,7 +45203,7 @@ }, "period": { "type": "string", - "description": "The period of time the project was worked on, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the project was worked on, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -45774,7 +45688,7 @@ }, "date": { "type": "string", - "description": "The date when the award was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the award was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -45942,7 +45856,7 @@ }, "date": { "type": "string", - "description": "The date when the certification was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the certification was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -46110,7 +46024,7 @@ }, "date": { "type": "string", - "description": "The date when the publication was published, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the publication was published, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -46278,7 +46192,7 @@ }, "period": { "type": "string", - "description": "The period of time the author was volunteered at the organization or company, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the author was volunteered at the organization or company, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -47490,7 +47404,7 @@ }, "period": { "type": "string", - "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Kept in sync from `dates`; prefer writing `dates`." + "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -47590,7 +47504,7 @@ }, "period": { "type": "string", - "description": "The period of time this role was held, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time this role was held, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -47753,7 +47667,7 @@ }, "period": { "type": "string", - "description": "The period of time the education was obtained over, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the education was obtained over, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -47921,7 +47835,7 @@ }, "period": { "type": "string", - "description": "The period of time the project was worked on, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the project was worked on, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -48401,7 +48315,7 @@ }, "date": { "type": "string", - "description": "The date when the award was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the award was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -48570,7 +48484,7 @@ }, "date": { "type": "string", - "description": "The date when the certification was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the certification was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -48739,7 +48653,7 @@ }, "date": { "type": "string", - "description": "The date when the publication was published, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the publication was published, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -48908,7 +48822,7 @@ }, "period": { "type": "string", - "description": "The period of time the author was volunteered at the organization or company, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the author was volunteered at the organization or company, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -49548,7 +49462,7 @@ }, "period": { "type": "string", - "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Kept in sync from `dates`; prefer writing `dates`." + "description": "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -49648,7 +49562,7 @@ }, "period": { "type": "string", - "description": "The period of time this role was held, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time this role was held, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -49823,7 +49737,7 @@ }, "period": { "type": "string", - "description": "The period of time the education was obtained over, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the education was obtained over, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -50003,7 +49917,7 @@ }, "period": { "type": "string", - "description": "The period of time the project was worked on, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the project was worked on, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -50521,7 +50435,7 @@ }, "date": { "type": "string", - "description": "The date when the award was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the award was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -50702,7 +50616,7 @@ }, "date": { "type": "string", - "description": "The date when the certification was received, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the certification was received, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -50883,7 +50797,7 @@ }, "date": { "type": "string", - "description": "The date when the publication was published, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The date when the publication was published, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", @@ -51064,7 +50978,7 @@ }, "period": { "type": "string", - "description": "The period of time the author was volunteered at the organization or company, as text. Kept in sync from `dates`; prefer writing `dates`." + "description": "The period of time the author was volunteered at the organization or company, as text. Written from `dates` on every save; write `dates` instead." }, "dates": { "type": "object", diff --git a/migrations/20260929063245_contract_redesign_legacy_fields/migration.sql b/migrations/20260929063245_contract_redesign_legacy_fields/migration.sql new file mode 100644 index 000000000..894dd22df --- /dev/null +++ b/migrations/20260929063245_contract_redesign_legacy_fields/migration.sql @@ -0,0 +1,18 @@ +-- Contract steps for the redesign (§3.10): the closed stage replaced `archived` and `rejected`, and versions are +-- labelled by `kind`. Older app versions stop working against this schema. rollback.sql restores the columns. +-- Anything still marked archived or rejected closes first, so no application reopens when the flag goes. +UPDATE "application" SET "status" = 'closed', "closed_reason" = 'not-selected' WHERE "status" = 'rejected';--> statement-breakpoint +UPDATE "application" SET "status" = 'closed' WHERE "archived" = true AND "status" <> 'closed';--> statement-breakpoint +UPDATE "application" SET "activity" = ( + SELECT jsonb_agg( + CASE WHEN entry->>'type' = 'stage' AND entry->>'stage' = 'rejected' + THEN jsonb_set(entry, '{stage}', '"closed"') + ELSE entry + END + ORDER BY position + ) + FROM jsonb_array_elements("activity") WITH ORDINALITY AS items(entry, position) +) +WHERE "activity" @> '[{"type": "stage", "stage": "rejected"}]';--> statement-breakpoint +ALTER TABLE "application" DROP COLUMN "archived";--> statement-breakpoint +ALTER TABLE "resume_version" DROP COLUMN "label"; diff --git a/migrations/20260929063245_contract_redesign_legacy_fields/rollback.sql b/migrations/20260929063245_contract_redesign_legacy_fields/rollback.sql new file mode 100644 index 000000000..cbd508785 --- /dev/null +++ b/migrations/20260929063245_contract_redesign_legacy_fields/rollback.sql @@ -0,0 +1,15 @@ +-- Restores the columns the contract step dropped, for older app versions. Closed applications without a reason +-- were archived ones; version labels come back from their kind. +ALTER TABLE "application" ADD COLUMN "archived" boolean DEFAULT false NOT NULL; +UPDATE "application" SET "archived" = true WHERE "status" = 'closed' AND "closed_reason" IS NULL; +ALTER TABLE "resume_version" ADD COLUMN "label" text DEFAULT '' NOT NULL; +UPDATE "resume_version" SET "label" = CASE "kind" + WHEN 'created' THEN 'Created' + WHEN 'import' THEN 'Imported' + WHEN 'auto' THEN 'Manual save' + WHEN 'before-restore' THEN 'Before restore' + WHEN 'restored' THEN 'Restored version' + WHEN 'ai' THEN 'AI edit' + WHEN 'sent' THEN 'Sent' + ELSE coalesce("name", '') +END; diff --git a/migrations/20260929063245_contract_redesign_legacy_fields/snapshot.json b/migrations/20260929063245_contract_redesign_legacy_fields/snapshot.json new file mode 100644 index 000000000..c2b827ff3 --- /dev/null +++ b/migrations/20260929063245_contract_redesign_legacy_fields/snapshot.json @@ -0,0 +1,7143 @@ +{ + "version": "8", + "dialect": "postgres", + "id": "dafcffd5-b465-45f1-a86c-ee1e53f772b1", + "prevIds": ["81945bec-7bf7-4671-b3cd-0fe39afef83d"], + "ddl": [ + { + "isRlsEnabled": false, + "name": "agent_actions", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "agent_attachments", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "agent_messages", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "agent_threads", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "ai_providers", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "application", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "account", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "apikey", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "jwks", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "oauth_access_token", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "oauth_client", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "oauth_client_assertion", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "oauth_client_resource", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "oauth_consent", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "oauth_refresh_token", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "oauth_resource", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "passkey", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "session", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "two_factor", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "user", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "verification", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "cover_letter", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "cover_letter_version", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "resume", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "resume_slug_redirect", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "resume_statistics", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "resume_statistics_daily", + "entityType": "tables", + "schema": "public" + }, + { + "isRlsEnabled": false, + "name": "resume_version", + "entityType": "tables", + "schema": "public" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "agent_actions" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_id", + "entityType": "columns", + "schema": "public", + "table": "agent_actions" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "thread_id", + "entityType": "columns", + "schema": "public", + "table": "agent_actions" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "message_id", + "entityType": "columns", + "schema": "public", + "table": "agent_actions" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "resume_id", + "entityType": "columns", + "schema": "public", + "table": "agent_actions" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "kind", + "entityType": "columns", + "schema": "public", + "table": "agent_actions" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "'applied'", + "generated": null, + "identity": null, + "name": "status", + "entityType": "columns", + "schema": "public", + "table": "agent_actions" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "title", + "entityType": "columns", + "schema": "public", + "table": "agent_actions" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "summary", + "entityType": "columns", + "schema": "public", + "table": "agent_actions" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "operations", + "entityType": "columns", + "schema": "public", + "table": "agent_actions" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "snapshot_data", + "entityType": "columns", + "schema": "public", + "table": "agent_actions" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "base_updated_at", + "entityType": "columns", + "schema": "public", + "table": "agent_actions" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "applied_updated_at", + "entityType": "columns", + "schema": "public", + "table": "agent_actions" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "reverted_at", + "entityType": "columns", + "schema": "public", + "table": "agent_actions" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "revert_message", + "entityType": "columns", + "schema": "public", + "table": "agent_actions" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "agent_actions" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "agent_actions" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "agent_attachments" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_id", + "entityType": "columns", + "schema": "public", + "table": "agent_attachments" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "thread_id", + "entityType": "columns", + "schema": "public", + "table": "agent_attachments" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "message_id", + "entityType": "columns", + "schema": "public", + "table": "agent_attachments" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "storage_key", + "entityType": "columns", + "schema": "public", + "table": "agent_attachments" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "filename", + "entityType": "columns", + "schema": "public", + "table": "agent_attachments" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "media_type", + "entityType": "columns", + "schema": "public", + "table": "agent_attachments" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "size", + "entityType": "columns", + "schema": "public", + "table": "agent_attachments" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "agent_attachments" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "agent_messages" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_id", + "entityType": "columns", + "schema": "public", + "table": "agent_messages" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "thread_id", + "entityType": "columns", + "schema": "public", + "table": "agent_messages" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "role", + "entityType": "columns", + "schema": "public", + "table": "agent_messages" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "'completed'", + "generated": null, + "identity": null, + "name": "status", + "entityType": "columns", + "schema": "public", + "table": "agent_messages" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "sequence", + "entityType": "columns", + "schema": "public", + "table": "agent_messages" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "ui_message", + "entityType": "columns", + "schema": "public", + "table": "agent_messages" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "error", + "entityType": "columns", + "schema": "public", + "table": "agent_messages" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "agent_messages" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "agent_messages" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "agent_threads" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_id", + "entityType": "columns", + "schema": "public", + "table": "agent_threads" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "ai_provider_id", + "entityType": "columns", + "schema": "public", + "table": "agent_threads" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "source_resume_id", + "entityType": "columns", + "schema": "public", + "table": "agent_threads" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "working_resume_id", + "entityType": "columns", + "schema": "public", + "table": "agent_threads" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "cover_letter_id", + "entityType": "columns", + "schema": "public", + "table": "agent_threads" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "title", + "entityType": "columns", + "schema": "public", + "table": "agent_threads" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "0", + "generated": null, + "identity": null, + "name": "edits_proposed", + "entityType": "columns", + "schema": "public", + "table": "agent_threads" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "0", + "generated": null, + "identity": null, + "name": "edits_accepted", + "entityType": "columns", + "schema": "public", + "table": "agent_threads" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "'active'", + "generated": null, + "identity": null, + "name": "status", + "entityType": "columns", + "schema": "public", + "table": "agent_threads" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "false", + "generated": null, + "identity": null, + "name": "review_patches", + "entityType": "columns", + "schema": "public", + "table": "agent_threads" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "active_run_id", + "entityType": "columns", + "schema": "public", + "table": "agent_threads" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "active_stream_id", + "entityType": "columns", + "schema": "public", + "table": "agent_threads" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "active_run_started_at", + "entityType": "columns", + "schema": "public", + "table": "agent_threads" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "last_message_at", + "entityType": "columns", + "schema": "public", + "table": "agent_threads" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "archived_at", + "entityType": "columns", + "schema": "public", + "table": "agent_threads" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "deleted_at", + "entityType": "columns", + "schema": "public", + "table": "agent_threads" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "agent_threads" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "agent_threads" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "ai_providers" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_id", + "entityType": "columns", + "schema": "public", + "table": "ai_providers" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "label", + "entityType": "columns", + "schema": "public", + "table": "ai_providers" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "provider", + "entityType": "columns", + "schema": "public", + "table": "ai_providers" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "model", + "entityType": "columns", + "schema": "public", + "table": "ai_providers" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "base_url", + "entityType": "columns", + "schema": "public", + "table": "ai_providers" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "encrypted_api_key", + "entityType": "columns", + "schema": "public", + "table": "ai_providers" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "api_key_salt", + "entityType": "columns", + "schema": "public", + "table": "ai_providers" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "api_key_hash", + "entityType": "columns", + "schema": "public", + "table": "ai_providers" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "api_key_preview", + "entityType": "columns", + "schema": "public", + "table": "ai_providers" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "'untested'", + "generated": null, + "identity": null, + "name": "test_status", + "entityType": "columns", + "schema": "public", + "table": "ai_providers" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "test_error", + "entityType": "columns", + "schema": "public", + "table": "ai_providers" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "last_tested_at", + "entityType": "columns", + "schema": "public", + "table": "ai_providers" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "last_used_at", + "entityType": "columns", + "schema": "public", + "table": "ai_providers" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "false", + "generated": null, + "identity": null, + "name": "enabled", + "entityType": "columns", + "schema": "public", + "table": "ai_providers" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "ai_providers" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "ai_providers" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_id", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "company", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "role", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "location", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "salary", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "'saved'", + "generated": null, + "identity": null, + "name": "status", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "closed_reason", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "resume_id", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "cover_letter_id", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "sent_resume_version_id", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "smallint", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "sent_check_score", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "sent_cover_letter_version_id", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "source", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 1, + "default": "'{}'", + "generated": null, + "identity": null, + "name": "tags", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "source_url", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "job_description", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "'[]'", + "generated": null, + "identity": null, + "name": "requirements", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "match_score", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "ai_metadata", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "notes", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "resume_file_url", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "resume_file_name", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "cover_letter_url", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "cover_letter_name", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "follow_up_at", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "follow_up_note", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "'[]'", + "generated": null, + "identity": null, + "name": "contacts", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "'[]'", + "generated": null, + "identity": null, + "name": "activity", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "applied_at", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "application" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "account_id", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "'credential'", + "generated": null, + "identity": null, + "name": "provider_id", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "issuer", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_id", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "scope", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id_token", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "password", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "access_token", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "refresh_token", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "access_token_expires_at", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "refresh_token_expires_at", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "account" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "apikey" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "name", + "entityType": "columns", + "schema": "public", + "table": "apikey" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "start", + "entityType": "columns", + "schema": "public", + "table": "apikey" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "prefix", + "entityType": "columns", + "schema": "public", + "table": "apikey" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "key", + "entityType": "columns", + "schema": "public", + "table": "apikey" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "'default'", + "generated": null, + "identity": null, + "name": "config_id", + "entityType": "columns", + "schema": "public", + "table": "apikey" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "reference_id", + "entityType": "columns", + "schema": "public", + "table": "apikey" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "refill_interval", + "entityType": "columns", + "schema": "public", + "table": "apikey" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "refill_amount", + "entityType": "columns", + "schema": "public", + "table": "apikey" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "last_refill_at", + "entityType": "columns", + "schema": "public", + "table": "apikey" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "true", + "generated": null, + "identity": null, + "name": "enabled", + "entityType": "columns", + "schema": "public", + "table": "apikey" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "false", + "generated": null, + "identity": null, + "name": "rate_limit_enabled", + "entityType": "columns", + "schema": "public", + "table": "apikey" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": "86400000", + "generated": null, + "identity": null, + "name": "rate_limit_time_window", + "entityType": "columns", + "schema": "public", + "table": "apikey" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": "10", + "generated": null, + "identity": null, + "name": "rate_limit_max", + "entityType": "columns", + "schema": "public", + "table": "apikey" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "0", + "generated": null, + "identity": null, + "name": "request_count", + "entityType": "columns", + "schema": "public", + "table": "apikey" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "remaining", + "entityType": "columns", + "schema": "public", + "table": "apikey" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "last_request", + "entityType": "columns", + "schema": "public", + "table": "apikey" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "expires_at", + "entityType": "columns", + "schema": "public", + "table": "apikey" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "apikey" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "apikey" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "permissions", + "entityType": "columns", + "schema": "public", + "table": "apikey" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "metadata", + "entityType": "columns", + "schema": "public", + "table": "apikey" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "jwks" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "public_key", + "entityType": "columns", + "schema": "public", + "table": "jwks" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "private_key", + "entityType": "columns", + "schema": "public", + "table": "jwks" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "jwks" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "expires_at", + "entityType": "columns", + "schema": "public", + "table": "jwks" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "alg", + "entityType": "columns", + "schema": "public", + "table": "jwks" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "crv", + "entityType": "columns", + "schema": "public", + "table": "jwks" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "authorization_code_id", + "entityType": "columns", + "schema": "public", + "table": "oauth_access_token" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 1, + "default": null, + "generated": null, + "identity": null, + "name": "resources", + "entityType": "columns", + "schema": "public", + "table": "oauth_access_token" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 1, + "default": null, + "generated": null, + "identity": null, + "name": "requested_user_info_claims", + "entityType": "columns", + "schema": "public", + "table": "oauth_access_token" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "revoked", + "entityType": "columns", + "schema": "public", + "table": "oauth_access_token" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "confirmation", + "entityType": "columns", + "schema": "public", + "table": "oauth_access_token" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "oauth_access_token" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "token", + "entityType": "columns", + "schema": "public", + "table": "oauth_access_token" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "client_id", + "entityType": "columns", + "schema": "public", + "table": "oauth_access_token" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "session_id", + "entityType": "columns", + "schema": "public", + "table": "oauth_access_token" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_id", + "entityType": "columns", + "schema": "public", + "table": "oauth_access_token" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "reference_id", + "entityType": "columns", + "schema": "public", + "table": "oauth_access_token" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "refresh_id", + "entityType": "columns", + "schema": "public", + "table": "oauth_access_token" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "expires_at", + "entityType": "columns", + "schema": "public", + "table": "oauth_access_token" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "oauth_access_token" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 1, + "default": null, + "generated": null, + "identity": null, + "name": "scopes", + "entityType": "columns", + "schema": "public", + "table": "oauth_access_token" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "client_discovery_id", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 1, + "default": "'{}'", + "generated": null, + "identity": null, + "name": "client_credentials_scopes", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "backchannel_logout_uri", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "backchannel_logout_session_required", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "application_type", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "jwks", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "jwks_uri", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": "false", + "generated": null, + "identity": null, + "name": "dpop_bound_access_tokens", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "client_id", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "client_secret", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": "false", + "generated": null, + "identity": null, + "name": "disabled", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "skip_consent", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "enable_end_session", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "subject_type", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 1, + "default": null, + "generated": null, + "identity": null, + "name": "scopes", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_id", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "name", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "uri", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "icon", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 1, + "default": null, + "generated": null, + "identity": null, + "name": "contacts", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "tos", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "policy", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "software_id", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "software_version", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "software_statement", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 1, + "default": null, + "generated": null, + "identity": null, + "name": "redirect_uris", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 1, + "default": null, + "generated": null, + "identity": null, + "name": "post_logout_redirect_uris", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "token_endpoint_auth_method", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 1, + "default": null, + "generated": null, + "identity": null, + "name": "grant_types", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 1, + "default": null, + "generated": null, + "identity": null, + "name": "response_types", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "public", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "type", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "require_pkce", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "reference_id", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "metadata", + "entityType": "columns", + "schema": "public", + "table": "oauth_client" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "oauth_client_assertion" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "expires_at", + "entityType": "columns", + "schema": "public", + "table": "oauth_client_assertion" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "oauth_client_resource" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "client_id", + "entityType": "columns", + "schema": "public", + "table": "oauth_client_resource" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "resource_id", + "entityType": "columns", + "schema": "public", + "table": "oauth_client_resource" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "metadata", + "entityType": "columns", + "schema": "public", + "table": "oauth_client_resource" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "oauth_client_resource" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 1, + "default": null, + "generated": null, + "identity": null, + "name": "resources", + "entityType": "columns", + "schema": "public", + "table": "oauth_consent" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 1, + "default": null, + "generated": null, + "identity": null, + "name": "requested_user_info_claims", + "entityType": "columns", + "schema": "public", + "table": "oauth_consent" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "oauth_consent" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "client_id", + "entityType": "columns", + "schema": "public", + "table": "oauth_consent" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_id", + "entityType": "columns", + "schema": "public", + "table": "oauth_consent" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "reference_id", + "entityType": "columns", + "schema": "public", + "table": "oauth_consent" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 1, + "default": null, + "generated": null, + "identity": null, + "name": "scopes", + "entityType": "columns", + "schema": "public", + "table": "oauth_consent" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "oauth_consent" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "oauth_consent" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "authorization_code_id", + "entityType": "columns", + "schema": "public", + "table": "oauth_refresh_token" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 1, + "default": null, + "generated": null, + "identity": null, + "name": "resources", + "entityType": "columns", + "schema": "public", + "table": "oauth_refresh_token" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 1, + "default": null, + "generated": null, + "identity": null, + "name": "requested_user_info_claims", + "entityType": "columns", + "schema": "public", + "table": "oauth_refresh_token" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "rotated_at", + "entityType": "columns", + "schema": "public", + "table": "oauth_refresh_token" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "rotation_replay_response", + "entityType": "columns", + "schema": "public", + "table": "oauth_refresh_token" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "rotation_replay_expires_at", + "entityType": "columns", + "schema": "public", + "table": "oauth_refresh_token" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "confirmation", + "entityType": "columns", + "schema": "public", + "table": "oauth_refresh_token" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "oauth_refresh_token" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "token", + "entityType": "columns", + "schema": "public", + "table": "oauth_refresh_token" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "client_id", + "entityType": "columns", + "schema": "public", + "table": "oauth_refresh_token" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "session_id", + "entityType": "columns", + "schema": "public", + "table": "oauth_refresh_token" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_id", + "entityType": "columns", + "schema": "public", + "table": "oauth_refresh_token" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "reference_id", + "entityType": "columns", + "schema": "public", + "table": "oauth_refresh_token" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "expires_at", + "entityType": "columns", + "schema": "public", + "table": "oauth_refresh_token" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "oauth_refresh_token" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "revoked", + "entityType": "columns", + "schema": "public", + "table": "oauth_refresh_token" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "auth_time", + "entityType": "columns", + "schema": "public", + "table": "oauth_refresh_token" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 1, + "default": null, + "generated": null, + "identity": null, + "name": "scopes", + "entityType": "columns", + "schema": "public", + "table": "oauth_refresh_token" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "oauth_resource" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "identifier", + "entityType": "columns", + "schema": "public", + "table": "oauth_resource" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "name", + "entityType": "columns", + "schema": "public", + "table": "oauth_resource" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "access_token_ttl", + "entityType": "columns", + "schema": "public", + "table": "oauth_resource" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "refresh_token_ttl", + "entityType": "columns", + "schema": "public", + "table": "oauth_resource" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "signing_algorithm", + "entityType": "columns", + "schema": "public", + "table": "oauth_resource" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "signing_key_id", + "entityType": "columns", + "schema": "public", + "table": "oauth_resource" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 1, + "default": null, + "generated": null, + "identity": null, + "name": "allowed_scopes", + "entityType": "columns", + "schema": "public", + "table": "oauth_resource" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "custom_claims", + "entityType": "columns", + "schema": "public", + "table": "oauth_resource" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": "false", + "generated": null, + "identity": null, + "name": "dpop_bound_access_tokens_required", + "entityType": "columns", + "schema": "public", + "table": "oauth_resource" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": "false", + "generated": null, + "identity": null, + "name": "disabled", + "entityType": "columns", + "schema": "public", + "table": "oauth_resource" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "oauth_resource" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "oauth_resource" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": "1", + "generated": null, + "identity": null, + "name": "policy_version", + "entityType": "columns", + "schema": "public", + "table": "oauth_resource" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "metadata", + "entityType": "columns", + "schema": "public", + "table": "oauth_resource" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "passkey" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "name", + "entityType": "columns", + "schema": "public", + "table": "passkey" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "aaguid", + "entityType": "columns", + "schema": "public", + "table": "passkey" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "public_key", + "entityType": "columns", + "schema": "public", + "table": "passkey" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "credential_id", + "entityType": "columns", + "schema": "public", + "table": "passkey" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "counter", + "entityType": "columns", + "schema": "public", + "table": "passkey" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "device_type", + "entityType": "columns", + "schema": "public", + "table": "passkey" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "false", + "generated": null, + "identity": null, + "name": "backed_up", + "entityType": "columns", + "schema": "public", + "table": "passkey" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "transports", + "entityType": "columns", + "schema": "public", + "table": "passkey" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_id", + "entityType": "columns", + "schema": "public", + "table": "passkey" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "passkey" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "passkey" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "session" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "token", + "entityType": "columns", + "schema": "public", + "table": "session" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "ip_address", + "entityType": "columns", + "schema": "public", + "table": "session" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_agent", + "entityType": "columns", + "schema": "public", + "table": "session" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "impersonated_by", + "entityType": "columns", + "schema": "public", + "table": "session" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_id", + "entityType": "columns", + "schema": "public", + "table": "session" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "expires_at", + "entityType": "columns", + "schema": "public", + "table": "session" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "session" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "session" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "two_factor" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_id", + "entityType": "columns", + "schema": "public", + "table": "two_factor" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "secret", + "entityType": "columns", + "schema": "public", + "table": "two_factor" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "backup_codes", + "entityType": "columns", + "schema": "public", + "table": "two_factor" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "true", + "generated": null, + "identity": null, + "name": "verified", + "entityType": "columns", + "schema": "public", + "table": "two_factor" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": "0", + "generated": null, + "identity": null, + "name": "failed_verification_count", + "entityType": "columns", + "schema": "public", + "table": "two_factor" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "locked_until", + "entityType": "columns", + "schema": "public", + "table": "two_factor" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "two_factor" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "two_factor" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "user" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "image", + "entityType": "columns", + "schema": "public", + "table": "user" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "name", + "entityType": "columns", + "schema": "public", + "table": "user" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "email", + "entityType": "columns", + "schema": "public", + "table": "user" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "false", + "generated": null, + "identity": null, + "name": "email_verified", + "entityType": "columns", + "schema": "public", + "table": "user" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "username", + "entityType": "columns", + "schema": "public", + "table": "user" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "display_username", + "entityType": "columns", + "schema": "public", + "table": "user" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "false", + "generated": null, + "identity": null, + "name": "two_factor_enabled", + "entityType": "columns", + "schema": "public", + "table": "user" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "last_active_at", + "entityType": "columns", + "schema": "public", + "table": "user" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": "'user'", + "generated": null, + "identity": null, + "name": "role", + "entityType": "columns", + "schema": "public", + "table": "user" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": "false", + "generated": null, + "identity": null, + "name": "banned", + "entityType": "columns", + "schema": "public", + "table": "user" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "ban_reason", + "entityType": "columns", + "schema": "public", + "table": "user" + }, + { + "type": "timestamp(6) with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "ban_expires", + "entityType": "columns", + "schema": "public", + "table": "user" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "user" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "user" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "verification" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "identifier", + "entityType": "columns", + "schema": "public", + "table": "verification" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "value", + "entityType": "columns", + "schema": "public", + "table": "verification" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "expires_at", + "entityType": "columns", + "schema": "public", + "table": "verification" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "verification" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "verification" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "cover_letter" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_id", + "entityType": "columns", + "schema": "public", + "table": "cover_letter" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "name", + "entityType": "columns", + "schema": "public", + "table": "cover_letter" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "''", + "generated": null, + "identity": null, + "name": "recipient", + "entityType": "columns", + "schema": "public", + "table": "cover_letter" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "''", + "generated": null, + "identity": null, + "name": "content", + "entityType": "columns", + "schema": "public", + "table": "cover_letter" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "style", + "entityType": "columns", + "schema": "public", + "table": "cover_letter" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "'freeform'", + "generated": null, + "identity": null, + "name": "layout", + "entityType": "columns", + "schema": "public", + "table": "cover_letter" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "''", + "generated": null, + "identity": null, + "name": "recipient_name", + "entityType": "columns", + "schema": "public", + "table": "cover_letter" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "''", + "generated": null, + "identity": null, + "name": "recipient_company", + "entityType": "columns", + "schema": "public", + "table": "cover_letter" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "letter_date", + "entityType": "columns", + "schema": "public", + "table": "cover_letter" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "false", + "generated": null, + "identity": null, + "name": "sender_linked", + "entityType": "columns", + "schema": "public", + "table": "cover_letter" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "false", + "generated": null, + "identity": null, + "name": "design_linked", + "entityType": "columns", + "schema": "public", + "table": "cover_letter" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "source_resume_id", + "entityType": "columns", + "schema": "public", + "table": "cover_letter" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "source_application_id", + "entityType": "columns", + "schema": "public", + "table": "cover_letter" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 1, + "default": "'{}'", + "generated": null, + "identity": null, + "name": "tags", + "entityType": "columns", + "schema": "public", + "table": "cover_letter" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "false", + "generated": null, + "identity": null, + "name": "is_locked", + "entityType": "columns", + "schema": "public", + "table": "cover_letter" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "trashed_at", + "entityType": "columns", + "schema": "public", + "table": "cover_letter" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "1", + "generated": null, + "identity": null, + "name": "revision", + "entityType": "columns", + "schema": "public", + "table": "cover_letter" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "cover_letter" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "cover_letter" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "cover_letter_version" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "cover_letter_id", + "entityType": "columns", + "schema": "public", + "table": "cover_letter_version" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_id", + "entityType": "columns", + "schema": "public", + "table": "cover_letter_version" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "data", + "entityType": "columns", + "schema": "public", + "table": "cover_letter_version" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "'auto'", + "generated": null, + "identity": null, + "name": "kind", + "entityType": "columns", + "schema": "public", + "table": "cover_letter_version" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "name", + "entityType": "columns", + "schema": "public", + "table": "cover_letter_version" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "session_id", + "entityType": "columns", + "schema": "public", + "table": "cover_letter_version" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "cover_letter_version" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "resume" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "name", + "entityType": "columns", + "schema": "public", + "table": "resume" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "slug", + "entityType": "columns", + "schema": "public", + "table": "resume" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 1, + "default": "'{}'", + "generated": null, + "identity": null, + "name": "tags", + "entityType": "columns", + "schema": "public", + "table": "resume" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "false", + "generated": null, + "identity": null, + "name": "is_public", + "entityType": "columns", + "schema": "public", + "table": "resume" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "true", + "generated": null, + "identity": null, + "name": "show_download_buttons", + "entityType": "columns", + "schema": "public", + "table": "resume" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "false", + "generated": null, + "identity": null, + "name": "is_locked", + "entityType": "columns", + "schema": "public", + "table": "resume" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "password", + "entityType": "columns", + "schema": "public", + "table": "resume" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "application_id", + "entityType": "columns", + "schema": "public", + "table": "resume" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "trashed_at", + "entityType": "columns", + "schema": "public", + "table": "resume" + }, + { + "type": "boolean", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "false", + "generated": null, + "identity": null, + "name": "auto_name", + "entityType": "columns", + "schema": "public", + "table": "resume" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "data", + "entityType": "columns", + "schema": "public", + "table": "resume" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_id", + "entityType": "columns", + "schema": "public", + "table": "resume" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "resume" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "resume" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "resume_slug_redirect" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "slug", + "entityType": "columns", + "schema": "public", + "table": "resume_slug_redirect" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "resume_id", + "entityType": "columns", + "schema": "public", + "table": "resume_slug_redirect" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_id", + "entityType": "columns", + "schema": "public", + "table": "resume_slug_redirect" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "expires_at", + "entityType": "columns", + "schema": "public", + "table": "resume_slug_redirect" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "resume_slug_redirect" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "resume_statistics" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "0", + "generated": null, + "identity": null, + "name": "views", + "entityType": "columns", + "schema": "public", + "table": "resume_statistics" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "0", + "generated": null, + "identity": null, + "name": "downloads", + "entityType": "columns", + "schema": "public", + "table": "resume_statistics" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "last_viewed_at", + "entityType": "columns", + "schema": "public", + "table": "resume_statistics" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "last_downloaded_at", + "entityType": "columns", + "schema": "public", + "table": "resume_statistics" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "resume_id", + "entityType": "columns", + "schema": "public", + "table": "resume_statistics" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "resume_statistics" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "resume_statistics" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "resume_statistics_daily" + }, + { + "type": "date", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "date", + "entityType": "columns", + "schema": "public", + "table": "resume_statistics_daily" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "0", + "generated": null, + "identity": null, + "name": "views", + "entityType": "columns", + "schema": "public", + "table": "resume_statistics_daily" + }, + { + "type": "integer", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "0", + "generated": null, + "identity": null, + "name": "downloads", + "entityType": "columns", + "schema": "public", + "table": "resume_statistics_daily" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "resume_id", + "entityType": "columns", + "schema": "public", + "table": "resume_statistics_daily" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "resume_statistics_daily" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "updated_at", + "entityType": "columns", + "schema": "public", + "table": "resume_statistics_daily" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "id", + "entityType": "columns", + "schema": "public", + "table": "resume_version" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "resume_id", + "entityType": "columns", + "schema": "public", + "table": "resume_version" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "user_id", + "entityType": "columns", + "schema": "public", + "table": "resume_version" + }, + { + "type": "jsonb", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "data", + "entityType": "columns", + "schema": "public", + "table": "resume_version" + }, + { + "type": "text", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "'auto'", + "generated": null, + "identity": null, + "name": "kind", + "entityType": "columns", + "schema": "public", + "table": "resume_version" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "name", + "entityType": "columns", + "schema": "public", + "table": "resume_version" + }, + { + "type": "text", + "typeSchema": null, + "notNull": false, + "dimensions": 0, + "default": null, + "generated": null, + "identity": null, + "name": "session_id", + "entityType": "columns", + "schema": "public", + "table": "resume_version" + }, + { + "type": "timestamp with time zone", + "typeSchema": null, + "notNull": true, + "dimensions": 0, + "default": "now()", + "generated": null, + "identity": null, + "name": "created_at", + "entityType": "columns", + "schema": "public", + "table": "resume_version" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "thread_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "created_at", + "isExpression": false, + "asc": false, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "agent_actions_thread_id_created_at_index", + "entityType": "indexes", + "schema": "public", + "table": "agent_actions" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "resume_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "agent_actions_resume_id_index", + "entityType": "indexes", + "schema": "public", + "table": "agent_actions" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "message_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "agent_actions_message_id_index", + "entityType": "indexes", + "schema": "public", + "table": "agent_actions" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "thread_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "agent_attachments_thread_id_index", + "entityType": "indexes", + "schema": "public", + "table": "agent_attachments" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "message_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "agent_attachments_message_id_index", + "entityType": "indexes", + "schema": "public", + "table": "agent_attachments" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "user_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "agent_attachments_user_id_index", + "entityType": "indexes", + "schema": "public", + "table": "agent_attachments" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "thread_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "sequence", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": true, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "agent_messages_thread_id_sequence_index", + "entityType": "indexes", + "schema": "public", + "table": "agent_messages" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "user_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "created_at", + "isExpression": false, + "asc": false, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "agent_messages_user_id_created_at_index", + "entityType": "indexes", + "schema": "public", + "table": "agent_messages" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "user_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "status", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "last_message_at", + "isExpression": false, + "asc": false, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "agent_threads_user_id_status_last_message_at_index", + "entityType": "indexes", + "schema": "public", + "table": "agent_threads" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "working_resume_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "agent_threads_working_resume_id_index", + "entityType": "indexes", + "schema": "public", + "table": "agent_threads" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "cover_letter_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "agent_threads_cover_letter_id_index", + "entityType": "indexes", + "schema": "public", + "table": "agent_threads" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "ai_provider_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "agent_threads_ai_provider_id_index", + "entityType": "indexes", + "schema": "public", + "table": "agent_threads" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "user_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "enabled", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "ai_providers_user_id_enabled_index", + "entityType": "indexes", + "schema": "public", + "table": "ai_providers" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "user_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "last_used_at", + "isExpression": false, + "asc": false, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "ai_providers_user_id_last_used_at_index", + "entityType": "indexes", + "schema": "public", + "table": "ai_providers" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "user_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "created_at", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "ai_providers_user_id_created_at_index", + "entityType": "indexes", + "schema": "public", + "table": "ai_providers" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "user_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "application_user_id_index", + "entityType": "indexes", + "schema": "public", + "table": "application" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "user_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "updated_at", + "isExpression": false, + "asc": false, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "application_user_id_updated_at_index", + "entityType": "indexes", + "schema": "public", + "table": "application" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "user_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "account_user_id_index", + "entityType": "indexes", + "schema": "public", + "table": "account" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "reference_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "apikey_user_id_index", + "entityType": "indexes", + "schema": "public", + "table": "apikey" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "key", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "apikey_key_index", + "entityType": "indexes", + "schema": "public", + "table": "apikey" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "config_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "apikey_config_id_index", + "entityType": "indexes", + "schema": "public", + "table": "apikey" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "enabled", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "reference_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "apikey_enabled_user_id_index", + "entityType": "indexes", + "schema": "public", + "table": "apikey" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "token", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "oauth_access_token_token_index", + "entityType": "indexes", + "schema": "public", + "table": "oauth_access_token" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "client_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "oauth_client_client_id_index", + "entityType": "indexes", + "schema": "public", + "table": "oauth_client" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "client_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "oauth_client_resource_client_id_index", + "entityType": "indexes", + "schema": "public", + "table": "oauth_client_resource" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "resource_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "oauth_client_resource_resource_id_index", + "entityType": "indexes", + "schema": "public", + "table": "oauth_client_resource" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "client_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "resource_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": true, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "oauth_client_resource_client_id_resource_id_index", + "entityType": "indexes", + "schema": "public", + "table": "oauth_client_resource" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "user_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "client_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "oauth_consent_user_id_client_id_index", + "entityType": "indexes", + "schema": "public", + "table": "oauth_consent" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "token", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "oauth_refresh_token_token_index", + "entityType": "indexes", + "schema": "public", + "table": "oauth_refresh_token" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "user_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "passkey_user_id_index", + "entityType": "indexes", + "schema": "public", + "table": "passkey" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "token", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "user_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "session_token_user_id_index", + "entityType": "indexes", + "schema": "public", + "table": "session" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "expires_at", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "session_expires_at_index", + "entityType": "indexes", + "schema": "public", + "table": "session" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "user_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "two_factor_user_id_index", + "entityType": "indexes", + "schema": "public", + "table": "two_factor" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "secret", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "two_factor_secret_index", + "entityType": "indexes", + "schema": "public", + "table": "two_factor" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "created_at", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "user_created_at_index", + "entityType": "indexes", + "schema": "public", + "table": "user" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "lower(\"email\")", + "isExpression": true, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": true, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "user_email_lower_unique_idx", + "entityType": "indexes", + "schema": "public", + "table": "user" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "identifier", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "verification_identifier_index", + "entityType": "indexes", + "schema": "public", + "table": "verification" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "user_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "updated_at", + "isExpression": false, + "asc": false, + "nullsFirst": false, + "opclass": null + }, + { + "value": "id", + "isExpression": false, + "asc": false, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "cover_letter_user_id_updated_at_id_index", + "entityType": "indexes", + "schema": "public", + "table": "cover_letter" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "cover_letter_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "created_at", + "isExpression": false, + "asc": false, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "cover_letter_version_cover_letter_id_created_at_index", + "entityType": "indexes", + "schema": "public", + "table": "cover_letter_version" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "cover_letter_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "session_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": true, + "where": "\"kind\" = 'auto'", + "with": "", + "method": "btree", + "concurrently": false, + "name": "cover_letter_version_session_unique", + "entityType": "indexes", + "schema": "public", + "table": "cover_letter_version" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "created_at", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "resume_created_at_index", + "entityType": "indexes", + "schema": "public", + "table": "resume" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "user_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "updated_at", + "isExpression": false, + "asc": false, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "resume_user_id_updated_at_index", + "entityType": "indexes", + "schema": "public", + "table": "resume" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "is_public", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "slug", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "user_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "resume_is_public_slug_user_id_index", + "entityType": "indexes", + "schema": "public", + "table": "resume" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "resume_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "resume_slug_redirect_resume_id_index", + "entityType": "indexes", + "schema": "public", + "table": "resume_slug_redirect" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "resume_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "date", + "isExpression": false, + "asc": false, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "resume_statistics_daily_resume_id_date_index", + "entityType": "indexes", + "schema": "public", + "table": "resume_statistics_daily" + }, + { + "nameExplicit": false, + "columns": [ + { + "value": "resume_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "created_at", + "isExpression": false, + "asc": false, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": false, + "where": null, + "with": "", + "method": "btree", + "concurrently": false, + "name": "resume_version_resume_id_created_at_index", + "entityType": "indexes", + "schema": "public", + "table": "resume_version" + }, + { + "nameExplicit": true, + "columns": [ + { + "value": "resume_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + }, + { + "value": "session_id", + "isExpression": false, + "asc": true, + "nullsFirst": false, + "opclass": null + } + ], + "isUnique": true, + "where": "\"kind\" = 'auto'", + "with": "", + "method": "btree", + "concurrently": false, + "name": "resume_version_session_unique", + "entityType": "indexes", + "schema": "public", + "table": "resume_version" + }, + { + "nameExplicit": false, + "columns": ["user_id"], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "agent_actions_user_id_user_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "agent_actions" + }, + { + "nameExplicit": false, + "columns": ["thread_id"], + "schemaTo": "public", + "tableTo": "agent_threads", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "agent_actions_thread_id_agent_threads_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "agent_actions" + }, + { + "nameExplicit": false, + "columns": ["message_id"], + "schemaTo": "public", + "tableTo": "agent_messages", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "SET NULL", + "name": "agent_actions_message_id_agent_messages_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "agent_actions" + }, + { + "nameExplicit": false, + "columns": ["resume_id"], + "schemaTo": "public", + "tableTo": "resume", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "SET NULL", + "name": "agent_actions_resume_id_resume_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "agent_actions" + }, + { + "nameExplicit": false, + "columns": ["user_id"], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "agent_attachments_user_id_user_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "agent_attachments" + }, + { + "nameExplicit": false, + "columns": ["thread_id"], + "schemaTo": "public", + "tableTo": "agent_threads", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "agent_attachments_thread_id_agent_threads_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "agent_attachments" + }, + { + "nameExplicit": false, + "columns": ["message_id"], + "schemaTo": "public", + "tableTo": "agent_messages", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "SET NULL", + "name": "agent_attachments_message_id_agent_messages_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "agent_attachments" + }, + { + "nameExplicit": false, + "columns": ["user_id"], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "agent_messages_user_id_user_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "agent_messages" + }, + { + "nameExplicit": false, + "columns": ["thread_id"], + "schemaTo": "public", + "tableTo": "agent_threads", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "agent_messages_thread_id_agent_threads_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "agent_messages" + }, + { + "nameExplicit": false, + "columns": ["user_id"], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "agent_threads_user_id_user_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "agent_threads" + }, + { + "nameExplicit": false, + "columns": ["ai_provider_id"], + "schemaTo": "public", + "tableTo": "ai_providers", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "SET NULL", + "name": "agent_threads_ai_provider_id_ai_providers_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "agent_threads" + }, + { + "nameExplicit": false, + "columns": ["source_resume_id"], + "schemaTo": "public", + "tableTo": "resume", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "SET NULL", + "name": "agent_threads_source_resume_id_resume_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "agent_threads" + }, + { + "nameExplicit": false, + "columns": ["working_resume_id"], + "schemaTo": "public", + "tableTo": "resume", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "SET NULL", + "name": "agent_threads_working_resume_id_resume_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "agent_threads" + }, + { + "nameExplicit": false, + "columns": ["cover_letter_id"], + "schemaTo": "public", + "tableTo": "cover_letter", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "SET NULL", + "name": "agent_threads_cover_letter_id_cover_letter_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "agent_threads" + }, + { + "nameExplicit": false, + "columns": ["user_id"], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "ai_providers_user_id_user_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "ai_providers" + }, + { + "nameExplicit": false, + "columns": ["user_id"], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "application_user_id_user_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "application" + }, + { + "nameExplicit": false, + "columns": ["resume_id"], + "schemaTo": "public", + "tableTo": "resume", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "SET NULL", + "name": "application_resume_id_resume_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "application" + }, + { + "nameExplicit": false, + "columns": ["cover_letter_id"], + "schemaTo": "public", + "tableTo": "cover_letter", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "SET NULL", + "name": "application_cover_letter_id_cover_letter_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "application" + }, + { + "nameExplicit": false, + "columns": ["sent_resume_version_id"], + "schemaTo": "public", + "tableTo": "resume_version", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "SET NULL", + "name": "application_sent_resume_version_id_resume_version_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "application" + }, + { + "nameExplicit": false, + "columns": ["sent_cover_letter_version_id"], + "schemaTo": "public", + "tableTo": "cover_letter_version", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "SET NULL", + "name": "application_QJaGmijrxJ0T_fkey", + "entityType": "fks", + "schema": "public", + "table": "application" + }, + { + "nameExplicit": false, + "columns": ["user_id"], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "account_user_id_user_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "account" + }, + { + "nameExplicit": false, + "columns": ["reference_id"], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "apikey_user_id_user_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "apikey" + }, + { + "nameExplicit": false, + "columns": ["client_id"], + "schemaTo": "public", + "tableTo": "oauth_client", + "columnsTo": ["client_id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "oauth_access_token_client_id_oauth_client_client_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "oauth_access_token" + }, + { + "nameExplicit": false, + "columns": ["session_id"], + "schemaTo": "public", + "tableTo": "session", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "SET NULL", + "name": "oauth_access_token_session_id_session_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "oauth_access_token" + }, + { + "nameExplicit": false, + "columns": ["user_id"], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "oauth_access_token_user_id_user_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "oauth_access_token" + }, + { + "nameExplicit": false, + "columns": ["refresh_id"], + "schemaTo": "public", + "tableTo": "oauth_refresh_token", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "oauth_access_token_refresh_id_oauth_refresh_token_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "oauth_access_token" + }, + { + "nameExplicit": false, + "columns": ["user_id"], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "oauth_client_user_id_user_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "oauth_client" + }, + { + "nameExplicit": false, + "columns": ["client_id"], + "schemaTo": "public", + "tableTo": "oauth_client", + "columnsTo": ["client_id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "oauth_client_resource_client_id_oauth_client_client_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "oauth_client_resource" + }, + { + "nameExplicit": false, + "columns": ["resource_id"], + "schemaTo": "public", + "tableTo": "oauth_resource", + "columnsTo": ["identifier"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "oauth_client_resource_dn2L1gs9Dolm_fkey", + "entityType": "fks", + "schema": "public", + "table": "oauth_client_resource" + }, + { + "nameExplicit": false, + "columns": ["client_id"], + "schemaTo": "public", + "tableTo": "oauth_client", + "columnsTo": ["client_id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "oauth_consent_client_id_oauth_client_client_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "oauth_consent" + }, + { + "nameExplicit": false, + "columns": ["user_id"], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "oauth_consent_user_id_user_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "oauth_consent" + }, + { + "nameExplicit": false, + "columns": ["client_id"], + "schemaTo": "public", + "tableTo": "oauth_client", + "columnsTo": ["client_id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "oauth_refresh_token_client_id_oauth_client_client_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "oauth_refresh_token" + }, + { + "nameExplicit": false, + "columns": ["session_id"], + "schemaTo": "public", + "tableTo": "session", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "SET NULL", + "name": "oauth_refresh_token_session_id_session_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "oauth_refresh_token" + }, + { + "nameExplicit": false, + "columns": ["user_id"], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "oauth_refresh_token_user_id_user_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "oauth_refresh_token" + }, + { + "nameExplicit": false, + "columns": ["user_id"], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "passkey_user_id_user_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "passkey" + }, + { + "nameExplicit": false, + "columns": ["user_id"], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "session_user_id_user_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "session" + }, + { + "nameExplicit": false, + "columns": ["user_id"], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "two_factor_user_id_user_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "two_factor" + }, + { + "nameExplicit": false, + "columns": ["user_id"], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "cover_letter_user_id_user_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "cover_letter" + }, + { + "nameExplicit": false, + "columns": ["source_resume_id"], + "schemaTo": "public", + "tableTo": "resume", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "SET NULL", + "name": "cover_letter_source_resume_id_resume_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "cover_letter" + }, + { + "nameExplicit": false, + "columns": ["source_application_id"], + "schemaTo": "public", + "tableTo": "application", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "SET NULL", + "name": "cover_letter_source_application_id_application_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "cover_letter" + }, + { + "nameExplicit": false, + "columns": ["cover_letter_id"], + "schemaTo": "public", + "tableTo": "cover_letter", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "cover_letter_version_cover_letter_id_cover_letter_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "cover_letter_version" + }, + { + "nameExplicit": false, + "columns": ["user_id"], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "cover_letter_version_user_id_user_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "cover_letter_version" + }, + { + "nameExplicit": false, + "columns": ["application_id"], + "schemaTo": "public", + "tableTo": "application", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "SET NULL", + "name": "resume_application_id_application_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "resume" + }, + { + "nameExplicit": false, + "columns": ["user_id"], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "resume_user_id_user_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "resume" + }, + { + "nameExplicit": false, + "columns": ["resume_id"], + "schemaTo": "public", + "tableTo": "resume", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "resume_slug_redirect_resume_id_resume_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "resume_slug_redirect" + }, + { + "nameExplicit": false, + "columns": ["user_id"], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "resume_slug_redirect_user_id_user_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "resume_slug_redirect" + }, + { + "nameExplicit": false, + "columns": ["resume_id"], + "schemaTo": "public", + "tableTo": "resume", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "resume_statistics_resume_id_resume_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "resume_statistics" + }, + { + "nameExplicit": false, + "columns": ["resume_id"], + "schemaTo": "public", + "tableTo": "resume", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "resume_statistics_daily_resume_id_resume_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "resume_statistics_daily" + }, + { + "nameExplicit": false, + "columns": ["resume_id"], + "schemaTo": "public", + "tableTo": "resume", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "resume_version_resume_id_resume_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "resume_version" + }, + { + "nameExplicit": false, + "columns": ["user_id"], + "schemaTo": "public", + "tableTo": "user", + "columnsTo": ["id"], + "onUpdate": "NO ACTION", + "onDelete": "CASCADE", + "name": "resume_version_user_id_user_id_fkey", + "entityType": "fks", + "schema": "public", + "table": "resume_version" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "agent_actions_pkey", + "schema": "public", + "table": "agent_actions", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "agent_attachments_pkey", + "schema": "public", + "table": "agent_attachments", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "agent_messages_pkey", + "schema": "public", + "table": "agent_messages", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "agent_threads_pkey", + "schema": "public", + "table": "agent_threads", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "ai_providers_pkey", + "schema": "public", + "table": "ai_providers", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "application_pkey", + "schema": "public", + "table": "application", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "account_pkey", + "schema": "public", + "table": "account", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "apikey_pkey", + "schema": "public", + "table": "apikey", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "jwks_pkey", + "schema": "public", + "table": "jwks", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "oauth_access_token_pkey", + "schema": "public", + "table": "oauth_access_token", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "oauth_client_pkey", + "schema": "public", + "table": "oauth_client", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "oauth_client_assertion_pkey", + "schema": "public", + "table": "oauth_client_assertion", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "oauth_client_resource_pkey", + "schema": "public", + "table": "oauth_client_resource", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "oauth_consent_pkey", + "schema": "public", + "table": "oauth_consent", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "oauth_refresh_token_pkey", + "schema": "public", + "table": "oauth_refresh_token", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "oauth_resource_pkey", + "schema": "public", + "table": "oauth_resource", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "passkey_pkey", + "schema": "public", + "table": "passkey", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "session_pkey", + "schema": "public", + "table": "session", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "two_factor_pkey", + "schema": "public", + "table": "two_factor", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "user_pkey", + "schema": "public", + "table": "user", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "verification_pkey", + "schema": "public", + "table": "verification", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "cover_letter_pkey", + "schema": "public", + "table": "cover_letter", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "cover_letter_version_pkey", + "schema": "public", + "table": "cover_letter_version", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "resume_pkey", + "schema": "public", + "table": "resume", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "resume_slug_redirect_pkey", + "schema": "public", + "table": "resume_slug_redirect", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "resume_statistics_pkey", + "schema": "public", + "table": "resume_statistics", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "resume_statistics_daily_pkey", + "schema": "public", + "table": "resume_statistics_daily", + "entityType": "pks" + }, + { + "columns": ["id"], + "nameExplicit": false, + "name": "resume_version_pkey", + "schema": "public", + "table": "resume_version", + "entityType": "pks" + }, + { + "nameExplicit": false, + "columns": ["slug", "user_id"], + "nullsNotDistinct": false, + "name": "resume_slug_user_id_unique", + "entityType": "uniques", + "schema": "public", + "table": "resume" + }, + { + "nameExplicit": false, + "columns": ["user_id", "slug"], + "nullsNotDistinct": false, + "name": "resume_slug_redirect_user_id_slug_unique", + "entityType": "uniques", + "schema": "public", + "table": "resume_slug_redirect" + }, + { + "nameExplicit": false, + "columns": ["resume_id", "date"], + "nullsNotDistinct": false, + "name": "resume_statistics_daily_resume_id_date_unique", + "entityType": "uniques", + "schema": "public", + "table": "resume_statistics_daily" + }, + { + "nameExplicit": false, + "columns": ["token"], + "nullsNotDistinct": false, + "name": "oauth_access_token_token_key", + "schema": "public", + "table": "oauth_access_token", + "entityType": "uniques" + }, + { + "nameExplicit": false, + "columns": ["client_id"], + "nullsNotDistinct": false, + "name": "oauth_client_client_id_key", + "schema": "public", + "table": "oauth_client", + "entityType": "uniques" + }, + { + "nameExplicit": false, + "columns": ["identifier"], + "nullsNotDistinct": false, + "name": "oauth_resource_identifier_key", + "schema": "public", + "table": "oauth_resource", + "entityType": "uniques" + }, + { + "nameExplicit": false, + "columns": ["token"], + "nullsNotDistinct": false, + "name": "session_token_key", + "schema": "public", + "table": "session", + "entityType": "uniques" + }, + { + "nameExplicit": false, + "columns": ["email"], + "nullsNotDistinct": false, + "name": "user_email_key", + "schema": "public", + "table": "user", + "entityType": "uniques" + }, + { + "nameExplicit": false, + "columns": ["username"], + "nullsNotDistinct": false, + "name": "user_username_key", + "schema": "public", + "table": "user", + "entityType": "uniques" + }, + { + "nameExplicit": false, + "columns": ["display_username"], + "nullsNotDistinct": false, + "name": "user_display_username_key", + "schema": "public", + "table": "user", + "entityType": "uniques" + }, + { + "nameExplicit": false, + "columns": ["identifier"], + "nullsNotDistinct": false, + "name": "verification_identifier_key", + "schema": "public", + "table": "verification", + "entityType": "uniques" + }, + { + "nameExplicit": false, + "columns": ["resume_id"], + "nullsNotDistinct": false, + "name": "resume_statistics_resume_id_key", + "schema": "public", + "table": "resume_statistics", + "entityType": "uniques" + } + ], + "renames": [] +} diff --git a/packages/api/src/dto/application.ts b/packages/api/src/dto/application.ts index e36e71f70..55981e887 100644 --- a/packages/api/src/dto/application.ts +++ b/packages/api/src/dto/application.ts @@ -4,7 +4,6 @@ import * as schema from "@reactive-resume/db/schema"; import { aiMetadataSchema, applicationClosedReasonSchema, - applicationStatusInputSchema, applicationStatusSchema, applicationTimelineEntrySchema, contactSchema, @@ -40,7 +39,6 @@ const applicationSchema = createSelectSchema(schema.application, { closedReason: applicationClosedReasonSchema .nullable() .describe("Why a closed application ended: not-selected, withdrew, accepted-other or no-response."), - archived: z.boolean().describe("Deprecated: the closed stage replaced it. Kept in step for older clients."), resumeId: z.string().nullable().describe("The linked Reactive Resume, if any."), coverLetterId: z.string().nullable().describe("The linked saved cover letter, if any."), sentResumeVersionId: z @@ -109,7 +107,7 @@ const editableSchema = applicationSchema.pick({ const createInputSchema = editableSchema.partial().extend({ company: applicationSchema.shape.company, role: applicationSchema.shape.role, - status: applicationStatusInputSchema.optional(), + status: applicationStatusSchema.optional(), closedReason: applicationClosedReasonSchema.nullable().optional(), stageEnteredAt: timelineDateSchema.optional(), }); @@ -120,10 +118,9 @@ export const applicationDto = { .object({ status: applicationStatusSchema.optional(), tags: z.array(z.string()).optional(), - includeArchived: z.boolean().optional().default(false), }) .optional() - .default({ includeArchived: false }), + .default({}), output: z.array(applicationSchema.omit({ userId: true })), }, @@ -146,12 +143,11 @@ export const applicationDto = { update: { input: editableSchema.partial().extend({ id: z.string(), - status: applicationStatusInputSchema.optional(), + status: applicationStatusSchema.optional(), closedReason: applicationClosedReasonSchema .nullable() .optional() .describe("Why the application closed; kept when status stays closed, cleared by any other stage."), - archived: z.boolean().optional(), }), output: applicationSchema.omit({ userId: true }), }, @@ -225,13 +221,12 @@ export const applicationDto = { output: z.void(), }, - // Table bulk actions: move stage, archive/unarchive, add tags across a selection. + // Table bulk actions: move stage, close, add tags across a selection. bulkUpdate: { input: z.object({ ids: z.array(z.string()).min(1).max(200, "Too many items in a single bulk operation"), - status: applicationStatusInputSchema.optional(), + status: applicationStatusSchema.optional(), closedReason: applicationClosedReasonSchema.nullable().optional(), - archived: z.boolean().optional(), addTags: z.array(z.string()).optional(), }), output: z.object({ updated: z.number() }), diff --git a/packages/api/src/dto/resume.ts b/packages/api/src/dto/resume.ts index 83624dd34..d66903f39 100644 --- a/packages/api/src/dto/resume.ts +++ b/packages/api/src/dto/resume.ts @@ -31,7 +31,6 @@ const versionSchema = z.object({ "What made the version: created, import, auto (an editing session's autosave), named, before-restore, restored, ai (an AI or API edit) or sent.", ), name: z.string().nullable().describe("The user's name for a named version."), - label: z.string().describe("A short English description of the version."), createdAt: z.date().describe("When this state was saved."), }); diff --git a/packages/api/src/features/applications/crud.ts b/packages/api/src/features/applications/crud.ts index 08d457ee6..e2dc3ae91 100644 --- a/packages/api/src/features/applications/crud.ts +++ b/packages/api/src/features/applications/crud.ts @@ -12,7 +12,7 @@ export const crudRouter = { operationId: "listApplications", summary: "List job applications", description: - "Returns all job applications belonging to the authenticated user, most recently updated first. Archived applications are excluded unless includeArchived is set. Optionally filter by pipeline stage. Requires authentication.", + "Returns all job applications belonging to the authenticated user, most recently updated first. Optionally filter by pipeline stage. Requires authentication.", successDescription: "A list of the user's job applications.", }) .input(applicationDto.list.input) @@ -22,7 +22,6 @@ export const crudRouter = { userId: context.user.id, ...(input.status ? { status: input.status } : {}), ...(input.tags ? { tags: input.tags } : {}), - includeArchived: input.includeArchived, }), ), diff --git a/packages/api/src/features/applications/service.test.ts b/packages/api/src/features/applications/service.test.ts index 741485f6c..d09a34943 100644 --- a/packages/api/src/features/applications/service.test.ts +++ b/packages/api/src/features/applications/service.test.ts @@ -178,7 +178,7 @@ describe("applicationService.update", () => { [Record], ]; expect(closing).toMatchObject({ status: "closed", closedReason: "withdrew" }); - expect(reopening).toMatchObject({ status: "applied", closedReason: null, archived: false }); + expect(reopening).toMatchObject({ status: "applied", closedReason: null }); }); }); diff --git a/packages/api/src/features/applications/service.ts b/packages/api/src/features/applications/service.ts index f1d67dca2..637609d86 100644 --- a/packages/api/src/features/applications/service.ts +++ b/packages/api/src/features/applications/service.ts @@ -187,11 +187,11 @@ async function recordSentResume(row: ApplicationRow): Promise { return updated ?? row; } -/** Closing keeps (or takes) a reason; any other stage clears it, and reopens an application that was archived. */ +/** Closing keeps (or takes) a reason; any other stage clears it. */ function stageFields(status: ApplicationStatus | undefined, closedReason: ApplicationClosedReason | null | undefined) { if (status === undefined) return closedReason !== undefined ? { closedReason } : {}; if (status === "closed") return closedReason !== undefined ? { closedReason } : {}; - return { closedReason: null, archived: false }; + return { closedReason: null }; } async function assertOwnedResumes(userId: string, resumeIds: (string | null | undefined)[]) { @@ -270,7 +270,7 @@ const stripUserId = { + list: async (input: { userId: string; status?: ApplicationStatus; tags?: string[] }) => { const rows = await db .select() .from(schema.application) @@ -283,7 +283,7 @@ export const applicationService = { ) .orderBy(desc(schema.application.updatedAt)); - return rows.filter((row) => input.includeArchived || !row.archived).map(stripUserId); + return rows.map(stripUserId); }, getById: async (input: { id: string; userId: string }) => { @@ -364,12 +364,11 @@ export const applicationService = { userId: string; status?: ApplicationStatus | undefined; closedReason?: ApplicationClosedReason | null | undefined; - archived?: boolean | undefined; }, ) => { await requireOwned(input.id, input.userId); - const { id, userId, status, closedReason, archived, ...fields } = input; + const { id, userId, status, closedReason, ...fields } = input; await assertOwnedResume(userId, fields.resumeId); await assertOwnedCoverLetter(userId, fields.coverLetterId); @@ -394,7 +393,6 @@ export const applicationService = { ...fields, ...(status !== undefined ? { status } : {}), ...(appliedAtExpr ? { appliedAt: appliedAtExpr } : {}), - ...(archived !== undefined ? { archived } : {}), ...stageFields(status, closedReason), ...(activityExpr ? { activity: activityExpr } : {}), }) @@ -675,7 +673,6 @@ export const applicationService = { ids: string[]; status?: ApplicationStatus | undefined; closedReason?: ApplicationClosedReason | null | undefined; - archived?: boolean | undefined; addTags?: string[] | undefined; }) => { const scope = and(inArray(schema.application.id, input.ids), eq(schema.application.userId, input.userId)); @@ -713,7 +710,6 @@ export const applicationService = { ...(input.status !== undefined ? { status: input.status } : {}), ...(appliedAtExpr ? { appliedAt: appliedAtExpr } : {}), ...(activityExpr ? { activity: activityExpr } : {}), - ...(input.archived !== undefined ? { archived: input.archived } : {}), ...stageFields(input.status, input.closedReason), ...(tagsExpr ? { tags: tagsExpr } : {}), }) @@ -742,7 +738,7 @@ export const applicationService = { // Raw counts for Insights; funnel/sankey/tiles are derived client-side from these. stats: async (input: { userId: string }) => { - const scope = and(eq(schema.application.userId, input.userId), eq(schema.application.archived, false)); + const scope = eq(schema.application.userId, input.userId); const byStage = await db .select({ status: schema.application.status, count: sql`count(*)::int` }) diff --git a/packages/api/src/features/resume/resume-data-validation.ts b/packages/api/src/features/resume/resume-data-validation.ts index e5ea476f0..e42bbf45c 100644 --- a/packages/api/src/features/resume/resume-data-validation.ts +++ b/packages/api/src/features/resume/resume-data-validation.ts @@ -22,15 +22,11 @@ function parseApiResumeData(data: unknown, code: "BAD_REQUEST" | "INTERNAL_SERVE } } -/** - * Validates data before it's saved, then keeps structured dates and their legacy text in step. `previous` is - * the stored data being replaced, which tells an edit to the text alone (from a client that doesn't know - * structured dates) from an edit to the dates. - */ -export const parseWritableResumeData = (data: unknown, previous?: ResumeData) => { +/** Validates data before it's saved, then writes each entry's date text from its structured dates. */ +export const parseWritableResumeData = (data: unknown) => { const parsed = parseApiResumeData(data, "BAD_REQUEST", "Resume data does not match the canonical schema."); upgradeResumeDates(parsed); - syncResumeDates(parsed, previous); + syncResumeDates(parsed); return parsed; }; diff --git a/packages/api/src/features/resume/service.test.ts b/packages/api/src/features/resume/service.test.ts index 4c0cef544..4c93e8101 100644 --- a/packages/api/src/features/resume/service.test.ts +++ b/packages/api/src/features/resume/service.test.ts @@ -54,7 +54,6 @@ vi.mock("@reactive-resume/db/schema", () => ({ resumeId: "resume_id", userId: "user_id", data: "data", - label: "label", createdAt: "created_at", }, user: { id: "id", username: "username" }, diff --git a/packages/api/src/features/resume/service.ts b/packages/api/src/features/resume/service.ts index b01570763..e4b9b7bb6 100644 --- a/packages/api/src/features/resume/service.ts +++ b/packages/api/src/features/resume/service.ts @@ -77,7 +77,6 @@ async function applyResumePatchTx( userId: string; operations: JsonPatchOperation[]; expectedUpdatedAt?: Date; - versionLabel?: string; }, ) { const [existing] = await client @@ -118,7 +117,7 @@ async function applyResumePatchTx( }); } - patchedData = parseWritableResumeData(patchedData, storedData); + patchedData = parseWritableResumeData(patchedData); // The version guard is the ms-precision JS check above, under the SELECT ... FOR UPDATE lock. // Never compare expectedUpdatedAt in SQL: rows stamped by Postgres now() (defaultNow() on // insert) carry microseconds, while JS Dates are ms-truncated — SQL equality then matches @@ -154,7 +153,6 @@ async function applyResumePatchTx( userId: input.userId, data: resume.data, kind: "ai", - ...(input.versionLabel ? { label: input.versionLabel } : {}), }); return resume; @@ -609,9 +607,7 @@ export const resumeService = { }); } - const normalizedData = input.data - ? parseWritableResumeData(input.data, parseStoredResumeData(existing.data)) - : undefined; + const normalizedData = input.data ? parseWritableResumeData(input.data) : undefined; // A blank resume is named after its headline until someone names it by hand. const followedName = existing.autoName && input.name === undefined && normalizedData diff --git a/packages/api/src/features/resume/version-history.test.ts b/packages/api/src/features/resume/version-history.test.ts index 27b777151..9011bd611 100644 --- a/packages/api/src/features/resume/version-history.test.ts +++ b/packages/api/src/features/resume/version-history.test.ts @@ -16,7 +16,7 @@ const selectChain = (rows: unknown[]) => ({ const insertValues = () => { const values = vi.fn((_input: Record) => ({ - returning: async () => [{ id: "v1", kind: _input.kind, name: _input.name, label: _input.label }], + returning: async () => [{ id: "v1", kind: _input.kind, name: _input.name }], })); dbMock.insert.mockReturnValue({ values }); return values; @@ -40,26 +40,27 @@ beforeEach(() => { }); describe("writeVersion", () => { - it("stores normalized data with its kind and an English label, then applies retention", async () => { + it("stores normalized data with its kind, then applies retention", async () => { const values = insertValues(); const input = { ...data(), basics: { ...data().basics, name: "Ada" } }; await writeVersion(dbMock as never, { resumeId: "r1", userId: "u1", data: input, kind: "before-restore" }); expect(values).toHaveBeenCalledWith( - expect.objectContaining({ kind: "before-restore", label: "Before restore", name: null, sessionId: null }), + expect.objectContaining({ kind: "before-restore", name: null, sessionId: null }), ); expect(values.mock.calls[0]?.[0]).toHaveProperty("data.basics.name", "Ada"); // Expired versions, then autosaves beyond the cap. expect(dbMock.delete).toHaveBeenCalledTimes(2); }); - it("labels a named version with its name", async () => { + it("keeps a named version's name", async () => { const values = insertValues(); await writeVersion(dbMock as never, { resumeId: "r1", userId: "u1", data: data(), kind: "named", name: "Sent" }); - expect(values).toHaveBeenCalledWith(expect.objectContaining({ kind: "named", name: "Sent", label: "Sent" })); + expect(values).toHaveBeenCalledWith(expect.objectContaining({ kind: "named", name: "Sent" })); + expect(values.mock.calls[0]?.[0]).not.toHaveProperty("label"); }); }); diff --git a/packages/api/src/features/resume/version-history.ts b/packages/api/src/features/resume/version-history.ts index 0434c4ea7..1897ddd98 100644 --- a/packages/api/src/features/resume/version-history.ts +++ b/packages/api/src/features/resume/version-history.ts @@ -19,22 +19,10 @@ const MAX_AUTOSAVES = 500; // History shows at most this many versions, newest first. const LIST_LIMIT = 100; -// `label` keeps an English description for API clients and older rows; the app labels versions by kind. -const LABELS: Record, string> = { - created: "Created", - import: "Imported", - auto: "Manual save", - "before-restore": "Before restore", - restored: "Restored version", - ai: "AI edit", - sent: "Sent", -}; - const summary = { id: schema.resumeVersion.id, kind: schema.resumeVersion.kind, name: schema.resumeVersion.name, - label: schema.resumeVersion.label, createdAt: schema.resumeVersion.createdAt, }; @@ -44,7 +32,6 @@ type VersionInput = { data: ResumeData; kind: ResumeVersionKind; name?: string; - label?: string; sessionId?: string; }; @@ -58,7 +45,6 @@ export async function writeVersion(client: DbOrTx, input: VersionInput) { kind: input.kind, name: input.name ?? null, sessionId: input.sessionId ?? null, - label: input.label ?? (input.kind === "named" ? (input.name ?? "") : LABELS[input.kind]), }) .returning(summary); if (!version) throw new ORPCError("INTERNAL_SERVER_ERROR", { message: "Failed to save the version." }); @@ -180,7 +166,7 @@ export async function getVersion(input: { resumeId: string; userId: string; vers export async function renameVersion(input: { resumeId: string; userId: string; versionId: string; name: string }) { const [version] = await db .update(schema.resumeVersion) - .set({ name: input.name, label: input.name }) + .set({ name: input.name }) .where(and(ownedVersion(input), eq(schema.resumeVersion.kind, "named"))) .returning(summary); diff --git a/packages/db/src/schema/applications.ts b/packages/db/src/schema/applications.ts index 62688813c..e94f126c9 100644 --- a/packages/db/src/schema/applications.ts +++ b/packages/db/src/schema/applications.ts @@ -34,8 +34,6 @@ export const application = pg.pgTable( status: pg.text("status").$type().notNull().default("saved"), // Why a closed application ended (not selected, withdrew, accepted another offer, no response). Insights use it. closedReason: pg.text("closed_reason").$type(), - // Superseded by the closed stage, which absorbed it; kept while older app versions may still read it. - archived: pg.boolean("archived").notNull().default(false), // Live link to one of the user's resumes. Kept on resume delete (set null) so the // application history survives. resumeId: pg.text("resume_id").references(() => resume.id, { onDelete: "set null" }), diff --git a/packages/db/src/schema/resume.ts b/packages/db/src/schema/resume.ts index 0c5528a82..c20700629 100644 --- a/packages/db/src/schema/resume.ts +++ b/packages/db/src/schema/resume.ts @@ -88,8 +88,6 @@ export const resumeVersion = pg.pgTable( .references(() => user.id, { onDelete: "cascade" }), // Snapshot of the resume data. A session's autosave is refreshed while the session lasts; the rest are immutable. data: pg.jsonb("data").notNull().$type(), - // English description kept for API clients and rows written before `kind`; the UI labels versions by `kind`. - label: pg.text("label").notNull(), kind: pg.text("kind", { enum: RESUME_VERSION_KINDS }).notNull().default("auto"), // The user's name for a `named` version. name: pg.text("name"), diff --git a/packages/mcp/src/mcp-server-card.test.ts b/packages/mcp/src/mcp-server-card.test.ts index a4f2a866b..2e5c95760 100644 --- a/packages/mcp/src/mcp-server-card.test.ts +++ b/packages/mcp/src/mcp-server-card.test.ts @@ -102,12 +102,12 @@ describe("buildMcpServerCard", () => { expect(props.apiKey).toBeDefined(); }); - it("matches the create/update application archived contract", () => { + it("closes applications through their stage: no archived flag", () => { const create = TOOL_META[MCP_TOOL_NAME.createApplication].inputSchema; const update = TOOL_META[MCP_TOOL_NAME.updateApplication].inputSchema; expect(create.safeParse({ company: "Acme", role: "Engineer", archived: true }).success).toBe(false); - expect(update.safeParse({ id: "app-1", archived: true }).success).toBe(true); + expect(update.parse({ id: "app-1", archived: true })).not.toHaveProperty("archived"); }); it.each([{ content: "Updated" }, { recipient: "Dear Hiring Manager" }, { template: "onyx" }])( diff --git a/packages/mcp/src/tool-meta.ts b/packages/mcp/src/tool-meta.ts index 0650cbe1d..c5aaeeedb 100644 --- a/packages/mcp/src/tool-meta.ts +++ b/packages/mcp/src/tool-meta.ts @@ -312,7 +312,7 @@ export const TOOL_META = { " year-months ('2022' or '2022-03')", "", "Dates: write `dates`; the text in `period` (or `date` for awards, certifications and", - "publications) is rewritten from it in the resume's locale. Editing only the text still works.", + "publications) is rewritten from it in the resume's locale, so an edit to the text alone is lost.", "Important: HTML content fields (description, summary.content) must use valid HTML.", "New items must include a valid UUID as `id` and `hidden: false`.", `Locked resumes cannot be patched; use \`${T.unlockResume}\` first.`, @@ -542,7 +542,6 @@ export const TOOL_META = { inputSchema: z.object({ status: applicationStatusSchema.optional(), tags: z.array(z.string()).optional().default([]), - includeArchived: z.boolean().optional().default(false), }), annotations: READ_IDEMPOTENT, }, @@ -577,7 +576,6 @@ export const TOOL_META = { inputSchema: z.object({ id: applicationIdSchema, ...applicationMutableFieldsSchema, - archived: z.boolean().optional().describe("Deprecated: close the application instead. Kept for older clients."), }), annotations: WRITE_DESTRUCTIVE, }, @@ -652,7 +650,6 @@ export const TOOL_META = { ids: z.array(z.string()).min(1), status: applicationStatusSchema.optional(), closedReason: applicationClosedReasonSchema.nullable().optional(), - archived: z.boolean().optional().describe("Deprecated: close the applications instead."), addTags: z.array(z.string()).optional(), }), annotations: WRITE_DESTRUCTIVE, diff --git a/packages/mcp/src/tools.test.ts b/packages/mcp/src/tools.test.ts index 4e4286638..8d67c6a01 100644 --- a/packages/mcp/src/tools.test.ts +++ b/packages/mcp/src/tools.test.ts @@ -262,9 +262,9 @@ describe("registerTools", () => { registerTools(server as never, clientMock as never, new Headers()); const tool = registered.find((item) => item.name === "list_applications")!; - const result = await tool.handler({ includeArchived: true, tags: ["remote"] }); + const result = await tool.handler({ tags: ["remote"] }); - expect(clientMock.applications.list).toHaveBeenCalledWith({ includeArchived: true, tags: ["remote"] }); + expect(clientMock.applications.list).toHaveBeenCalledWith({ tags: ["remote"] }); expect(JSON.parse(result.content[0]!.text)).toEqual([{ id: "app-1", company: "Acme", role: "Engineer" }]); }); diff --git a/packages/schema/src/applications/data.ts b/packages/schema/src/applications/data.ts index 90de4b876..7a2f5d400 100644 --- a/packages/schema/src/applications/data.ts +++ b/packages/schema/src/applications/data.ts @@ -8,12 +8,6 @@ export const applicationStatusSchema = z.enum(APPLICATION_STATUSES); export type ApplicationStatus = z.infer; -/** A stage as clients may send it: the retired `rejected` stage still arrives from older clients and means closed. */ -export const applicationStatusInputSchema = z.preprocess( - (value) => (value === "rejected" ? "closed" : value), - applicationStatusSchema, -); - export const applicationClosedReasonSchema = z.enum(["not-selected", "withdrew", "accepted-other", "no-response"]); export type ApplicationClosedReason = z.infer; @@ -79,8 +73,7 @@ export type InterviewDetails = z.infer; export const applicationTimelineEntrySchema = z.discriminatedUnion("type", [ timelineBaseSchema.extend({ type: z.literal("stage"), - // History written before the closed stage may still say `rejected`. - stage: applicationStatusInputSchema, + stage: applicationStatusSchema, }), timelineBaseSchema.extend({ type: z.literal("note"), diff --git a/packages/schema/src/resume/data.ts b/packages/schema/src/resume/data.ts index 16e880f7c..4f3e215d9 100644 --- a/packages/schema/src/resume/data.ts +++ b/packages/schema/src/resume/data.ts @@ -137,7 +137,9 @@ export const awardItemSchema = baseItemSchema.extend({ awarder: z.string().describe("The awarder of the award."), date: z .string() - .describe("The date when the award was received, as text. Kept in sync from `dates`; prefer writing `dates`."), + .describe( + "The date when the award was received, as text. Written from `dates` on every save; write `dates` instead.", + ), dates: resumeDatesSchema.optional(), website: itemWebsiteSchema.describe("The website of the award, if any."), description: z.string().describe("The description of the award. This should be a HTML-formatted string."), @@ -149,7 +151,7 @@ export const certificationItemSchema = baseItemSchema.extend({ date: z .string() .describe( - "The date when the certification was received, as text. Kept in sync from `dates`; prefer writing `dates`.", + "The date when the certification was received, as text. Written from `dates` on every save; write `dates` instead.", ), dates: resumeDatesSchema.optional(), website: itemWebsiteSchema.describe("The website of the certification, if any."), @@ -167,7 +169,7 @@ export const educationItemSchema = baseItemSchema.extend({ period: z .string() .describe( - "The period of time the education was obtained over, as text. Kept in sync from `dates`; prefer writing `dates`.", + "The period of time the education was obtained over, as text. Written from `dates` on every save; write `dates` instead.", ), dates: resumeDatesSchema.optional(), website: itemWebsiteSchema.describe("The website of the school or institution, if any."), @@ -179,7 +181,9 @@ const roleItemSchema = z.object({ position: z.string().describe("The position or job title for this role."), period: z .string() - .describe("The period of time this role was held, as text. Kept in sync from `dates`; prefer writing `dates`."), + .describe( + "The period of time this role was held, as text. Written from `dates` on every save; write `dates` instead.", + ), dates: resumeDatesSchema.optional(), description: z.string().describe("The description of this specific role. This should be a HTML-formatted string."), }); @@ -199,7 +203,7 @@ export const experienceItemSchema = baseItemSchema.extend({ period: z .string() .describe( - "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Kept in sync from `dates`; prefer writing `dates`.", + "The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Written from `dates` on every save; write `dates` instead.", ), dates: resumeDatesSchema.optional(), website: itemWebsiteSchema.describe("The website of the company or organization, if any."), @@ -254,7 +258,7 @@ export const projectItemSchema = baseItemSchema.extend({ period: z .string() .describe( - "The period of time the project was worked on, as text. Kept in sync from `dates`; prefer writing `dates`.", + "The period of time the project was worked on, as text. Written from `dates` on every save; write `dates` instead.", ), dates: resumeDatesSchema.optional(), website: itemWebsiteSchema.describe("The link to the project, if any."), @@ -267,7 +271,7 @@ export const publicationItemSchema = baseItemSchema.extend({ date: z .string() .describe( - "The date when the publication was published, as text. Kept in sync from `dates`; prefer writing `dates`.", + "The date when the publication was published, as text. Written from `dates` on every save; write `dates` instead.", ), dates: resumeDatesSchema.optional(), website: itemWebsiteSchema.describe("The link to the publication, if any."), @@ -321,7 +325,7 @@ export const volunteerItemSchema = baseItemSchema.extend({ period: z .string() .describe( - "The period of time the author was volunteered at the organization or company, as text. Kept in sync from `dates`; prefer writing `dates`.", + "The period of time the author was volunteered at the organization or company, as text. Written from `dates` on every save; write `dates` instead.", ), dates: resumeDatesSchema.optional(), website: itemWebsiteSchema.describe("The link to the organization or company, if any."), diff --git a/packages/schema/src/resume/dates.test.ts b/packages/schema/src/resume/dates.test.ts index b8e9499ee..2b6fa166c 100644 --- a/packages/schema/src/resume/dates.test.ts +++ b/packages/schema/src/resume/dates.test.ts @@ -240,12 +240,12 @@ describe("syncResumeDates", () => { if (!entry) throw new Error("Missing entry."); entry.dates = { start: "2019-04", end: null, present: true }; - syncResumeDates(next, previous); + syncResumeDates(next); expect(job(next)?.period).toBe("Apr 2019 – Present"); }); - it("reads the text again when only the text changed, as clients unaware of dates do", () => { + it("overwrites an edit to the text alone: the dates are the only source", () => { const previous = parseResumeData(resume("2020 - 2022")); syncResumeDates(previous); const next = structuredClone(previous); @@ -253,10 +253,10 @@ describe("syncResumeDates", () => { if (!entry) throw new Error("Missing entry."); entry.period = "Jan 2018 - Present"; - syncResumeDates(next, previous); + syncResumeDates(next); - expect(job(next)?.dates).toEqual({ start: "2018-01", end: null, present: true }); - expect(job(next)?.period).toBe("Jan 2018 – Present"); + expect(job(next)?.dates).toEqual({ start: "2020", end: "2022", present: false }); + expect(job(next)?.period).toBe("2020 – 2022"); }); it("reformats every entry when the locale or format changes, without reading the text again", () => { @@ -266,7 +266,7 @@ describe("syncResumeDates", () => { next.metadata.page.locale = "ja-JP"; next.metadata.page.dateFormat = "long"; - syncResumeDates(next, previous); + syncResumeDates(next); expect(job(next)?.dates).toEqual({ start: "2022-03", end: null, present: true }); expect(job(next)?.period).toBe( @@ -278,7 +278,7 @@ describe("syncResumeDates", () => { const data = resume("Summer 2016 - 2018"); syncResumeDates(data); const once = structuredClone(data); - syncResumeDates(data, once); + syncResumeDates(data); expect(job(data)?.period).toBe("Summer 2016 - 2018"); expect(job(data)?.dates?.raw).toBe("Summer 2016 - 2018"); diff --git a/packages/schema/src/resume/dates.ts b/packages/schema/src/resume/dates.ts index eecc7188a..534dab196 100644 --- a/packages/schema/src/resume/dates.ts +++ b/packages/schema/src/resume/dates.ts @@ -42,10 +42,6 @@ export const DEFAULT_DATE_FORMAT: DateFormat = "short"; export const EMPTY_RESUME_DATES: ResumeDates = { start: null, end: null, present: false }; -/** Dates of the same entry are the same when their fields are; `raw` counts, since it changes what prints. */ -export const areResumeDatesEqual = (a: ResumeDates | undefined, b: ResumeDates | undefined) => - a?.start === b?.start && a?.end === b?.end && a?.present === b?.present && a?.raw === b?.raw; - const labels: Record = presentLabels; /** @@ -241,44 +237,20 @@ type PageDateOptions = { locale: string; dateFormat?: DateFormat | undefined }; export const formatEntryDates = (dates: ResumeDates | undefined, text: string, page: PageDateOptions) => dates ? formatResumeDates(dates, { locale: page.locale, format: page.dateFormat }) : text; -type Snapshot = { text: string; dates: ResumeDates | undefined }; - -const entryKey = (entry: DatedEntry) => (entry as { id?: string }).id; - /** - * Keeps structured dates and the legacy text (`period` or `date`) in step before resume data is saved, so - * older app versions and API clients that read the text keep working (the dual write). - * - * Dates are the source of truth: the text is rewritten from them in the resume's locale and date format. - * The one exception is an edit that changed only the text since `previous` (a client that doesn't know - * structured dates); then the text is read into new dates. Entries without dates get them from their text. + * Rewrites each entry's text (`period` or `date`) from its structured dates, in the resume's locale and date + * format. Dates are the only source: an edit to the text alone is overwritten. Entries without dates (new + * items from imports or older data) get them from their text first. * * Mutates `data` in place and writes only what changed, so it's safe inside an immer draft. */ -export function syncResumeDates(data: ResumeData, previous?: ResumeData) { +export function syncResumeDates(data: ResumeData) { const { locale, dateFormat } = data.metadata.page; const options: DateFormatOptions = { locale, format: dateFormat, presentLabel: getPresentLabel(locale) }; - const before = new Map(); - if (previous) { - forEachDatedEntry(previous, (entry, field) => { - const key = entryKey(entry); - if (key) before.set(key, { text: getLegacyDateText(entry, field), dates: entry.dates }); - }); - } - forEachDatedEntry(data, (entry, field) => { const text = getLegacyDateText(entry, field); - const read = () => readLegacyDates(text, { locale, single: field === "date" }); - - if (!entry.dates) { - entry.dates = read(); - } else if (text !== formatResumeDates(entry.dates, options)) { - const key = entryKey(entry); - const snapshot = key ? before.get(key) : undefined; - const onlyTextChanged = snapshot && snapshot.text !== text && areResumeDatesEqual(snapshot.dates, entry.dates); - if (onlyTextChanged) entry.dates = read(); - } + entry.dates ??= readLegacyDates(text, { locale, single: field === "date" }); const formatted = formatResumeDates(entry.dates, options); if (formatted === text) return; diff --git a/skills/resume-builder/references/schema.md b/skills/resume-builder/references/schema.md index afb3a9142..1aa64a4ff 100644 --- a/skills/resume-builder/references/schema.md +++ b/skills/resume-builder/references/schema.md @@ -169,7 +169,7 @@ Choose one coherent shape for each union value. Required fields are local to tha | `sections.experience.items[].company` | `string` | yes | — | The name of the company or organization. Empty while the entry is a draft, which isn't printed. | | `sections.experience.items[].position` | `string` | yes | — | The position held at the company or organization. Used when there is only a single role. If multiple roles are provided in the 'roles' field, this serves as a summary title or can be left blank. | | `sections.experience.items[].location` | `string` | yes | — | The location of the company or organization. | -| `sections.experience.items[].period` | `string` | yes | — | The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Kept in sync from `dates`; prefer writing `dates`. | +| `sections.experience.items[].period` | `string` | yes | — | The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Written from `dates` on every save; write `dates` instead. | | `sections.experience.items[].dates` | `object` | no | — | Structured dates. Write these rather than the legacy text field (`period` or `date`), which is kept in sync from them. | | `sections.experience.items[].dates.start` | `string or null` | yes | default: null | When it started, or the date itself for single-date entries (awards, certifications, publications). | | `sections.experience.items[].dates.start` | `string` | yes (variant 1 at sections.experience.items[].dates.start) | — | A year ("2022") or a year and month ("2022-03"). | @@ -188,7 +188,7 @@ Choose one coherent shape for each union value. Required fields are local to tha | `sections.experience.items[].roles[]` | `object` | — | — | — | | `sections.experience.items[].roles[].id` | `string` | yes | — | The unique identifier for the role. Usually generated as a UUID. | | `sections.experience.items[].roles[].position` | `string` | yes | — | The position or job title for this role. | -| `sections.experience.items[].roles[].period` | `string` | yes | — | The period of time this role was held, as text. Kept in sync from `dates`; prefer writing `dates`. | +| `sections.experience.items[].roles[].period` | `string` | yes | — | The period of time this role was held, as text. Written from `dates` on every save; write `dates` instead. | | `sections.experience.items[].roles[].dates` | `object` | no | — | Structured dates. Write these rather than the legacy text field (`period` or `date`), which is kept in sync from them. | | `sections.experience.items[].roles[].dates.start` | `string or null` | yes | default: null | When it started, or the date itself for single-date entries (awards, certifications, publications). | | `sections.experience.items[].roles[].dates.start` | `string` | yes (variant 1 at sections.experience.items[].roles[].dates.start) | — | A year ("2022") or a year and month ("2022-03"). | @@ -216,7 +216,7 @@ Choose one coherent shape for each union value. Required fields are local to tha | `sections.education.items[].area` | `string` | yes | — | The area of study or specialization. | | `sections.education.items[].grade` | `string` | yes | — | The grade or score achieved. | | `sections.education.items[].location` | `string` | yes | — | The location of the school or institution. | -| `sections.education.items[].period` | `string` | yes | — | The period of time the education was obtained over, as text. Kept in sync from `dates`; prefer writing `dates`. | +| `sections.education.items[].period` | `string` | yes | — | The period of time the education was obtained over, as text. Written from `dates` on every save; write `dates` instead. | | `sections.education.items[].dates` | `object` | no | — | Structured dates. Write these rather than the legacy text field (`period` or `date`), which is kept in sync from them. | | `sections.education.items[].dates.start` | `string or null` | yes | default: null | When it started, or the date itself for single-date entries (awards, certifications, publications). | | `sections.education.items[].dates.start` | `string` | yes (variant 1 at sections.education.items[].dates.start) | — | A year ("2022") or a year and month ("2022-03"). | @@ -244,7 +244,7 @@ Choose one coherent shape for each union value. Required fields are local to tha | `sections.projects.items[].id` | `string` | yes | — | The unique identifier for the item. Usually generated as a UUID. | | `sections.projects.items[].hidden` | `boolean` | yes | — | Whether to hide the item from the resume. | | `sections.projects.items[].name` | `string` | yes | — | The name of the project. Empty while the entry is a draft, which isn't printed. | -| `sections.projects.items[].period` | `string` | yes | — | The period of time the project was worked on, as text. Kept in sync from `dates`; prefer writing `dates`. | +| `sections.projects.items[].period` | `string` | yes | — | The period of time the project was worked on, as text. Written from `dates` on every save; write `dates` instead. | | `sections.projects.items[].dates` | `object` | no | — | Structured dates. Write these rather than the legacy text field (`period` or `date`), which is kept in sync from them. | | `sections.projects.items[].dates.start` | `string or null` | yes | default: null | When it started, or the date itself for single-date entries (awards, certifications, publications). | | `sections.projects.items[].dates.start` | `string` | yes (variant 1 at sections.projects.items[].dates.start) | — | A year ("2022") or a year and month ("2022-03"). | @@ -326,7 +326,7 @@ Choose one coherent shape for each union value. Required fields are local to tha | `sections.awards.items[].hidden` | `boolean` | yes | — | Whether to hide the item from the resume. | | `sections.awards.items[].title` | `string` | yes | — | The title of the award. Empty while the entry is a draft, which isn't printed. | | `sections.awards.items[].awarder` | `string` | yes | — | The awarder of the award. | -| `sections.awards.items[].date` | `string` | yes | — | The date when the award was received, as text. Kept in sync from `dates`; prefer writing `dates`. | +| `sections.awards.items[].date` | `string` | yes | — | The date when the award was received, as text. Written from `dates` on every save; write `dates` instead. | | `sections.awards.items[].dates` | `object` | no | — | Structured dates. Write these rather than the legacy text field (`period` or `date`), which is kept in sync from them. | | `sections.awards.items[].dates.start` | `string or null` | yes | default: null | When it started, or the date itself for single-date entries (awards, certifications, publications). | | `sections.awards.items[].dates.start` | `string` | yes (variant 1 at sections.awards.items[].dates.start) | — | A year ("2022") or a year and month ("2022-03"). | @@ -355,7 +355,7 @@ Choose one coherent shape for each union value. Required fields are local to tha | `sections.certifications.items[].hidden` | `boolean` | yes | — | Whether to hide the item from the resume. | | `sections.certifications.items[].title` | `string` | yes | — | The title of the certification. Empty while the entry is a draft, which isn't printed. | | `sections.certifications.items[].issuer` | `string` | yes | — | The issuer of the certification. | -| `sections.certifications.items[].date` | `string` | yes | — | The date when the certification was received, as text. Kept in sync from `dates`; prefer writing `dates`. | +| `sections.certifications.items[].date` | `string` | yes | — | The date when the certification was received, as text. Written from `dates` on every save; write `dates` instead. | | `sections.certifications.items[].dates` | `object` | no | — | Structured dates. Write these rather than the legacy text field (`period` or `date`), which is kept in sync from them. | | `sections.certifications.items[].dates.start` | `string or null` | yes | default: null | When it started, or the date itself for single-date entries (awards, certifications, publications). | | `sections.certifications.items[].dates.start` | `string` | yes (variant 1 at sections.certifications.items[].dates.start) | — | A year ("2022") or a year and month ("2022-03"). | @@ -384,7 +384,7 @@ Choose one coherent shape for each union value. Required fields are local to tha | `sections.publications.items[].hidden` | `boolean` | yes | — | Whether to hide the item from the resume. | | `sections.publications.items[].title` | `string` | yes | — | The title of the publication. Empty while the entry is a draft, which isn't printed. | | `sections.publications.items[].publisher` | `string` | yes | — | The publisher of the publication. | -| `sections.publications.items[].date` | `string` | yes | — | The date when the publication was published, as text. Kept in sync from `dates`; prefer writing `dates`. | +| `sections.publications.items[].date` | `string` | yes | — | The date when the publication was published, as text. Written from `dates` on every save; write `dates` instead. | | `sections.publications.items[].dates` | `object` | no | — | Structured dates. Write these rather than the legacy text field (`period` or `date`), which is kept in sync from them. | | `sections.publications.items[].dates.start` | `string or null` | yes | default: null | When it started, or the date itself for single-date entries (awards, certifications, publications). | | `sections.publications.items[].dates.start` | `string` | yes (variant 1 at sections.publications.items[].dates.start) | — | A year ("2022") or a year and month ("2022-03"). | @@ -413,7 +413,7 @@ Choose one coherent shape for each union value. Required fields are local to tha | `sections.volunteer.items[].hidden` | `boolean` | yes | — | Whether to hide the item from the resume. | | `sections.volunteer.items[].organization` | `string` | yes | — | The name of the organization or company. Empty while the entry is a draft, which isn't printed. | | `sections.volunteer.items[].location` | `string` | yes | — | The location of the organization or company. | -| `sections.volunteer.items[].period` | `string` | yes | — | The period of time the author was volunteered at the organization or company, as text. Kept in sync from `dates`; prefer writing `dates`. | +| `sections.volunteer.items[].period` | `string` | yes | — | The period of time the author was volunteered at the organization or company, as text. Written from `dates` on every save; write `dates` instead. | | `sections.volunteer.items[].dates` | `object` | no | — | Structured dates. Write these rather than the legacy text field (`period` or `date`), which is kept in sync from them. | | `sections.volunteer.items[].dates.start` | `string or null` | yes | default: null | When it started, or the date itself for single-date entries (awards, certifications, publications). | | `sections.volunteer.items[].dates.start` | `string` | yes (variant 1 at sections.volunteer.items[].dates.start) | — | A year ("2022") or a year and month ("2022-03"). | @@ -507,7 +507,7 @@ Choose one coherent shape for each union value. Required fields are local to tha | `customSections[].items[].company` | `string` | yes (type experience, schema experienceItemSchema at customSections[]) | — | The name of the company or organization. Empty while the entry is a draft, which isn't printed. | | `customSections[].items[].position` | `string` | yes (type experience, schema experienceItemSchema at customSections[]) | — | The position held at the company or organization. Used when there is only a single role. If multiple roles are provided in the 'roles' field, this serves as a summary title or can be left blank. | | `customSections[].items[].location` | `string` | yes (type experience, schema experienceItemSchema at customSections[]) | — | The location of the company or organization. | -| `customSections[].items[].period` | `string` | yes (type experience, schema experienceItemSchema at customSections[]) | — | The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Kept in sync from `dates`; prefer writing `dates`. | +| `customSections[].items[].period` | `string` | yes (type experience, schema experienceItemSchema at customSections[]) | — | The overall period of time at the company, as text. When multiple roles are used, this should reflect the total tenure. Written from `dates` on every save; write `dates` instead. | | `customSections[].items[].dates` | `object` | no (type experience, schema experienceItemSchema at customSections[]) | — | Structured dates. Write these rather than the legacy text field (`period` or `date`), which is kept in sync from them. | | `customSections[].items[].dates.start` | `string or null` | yes (type experience, schema experienceItemSchema at customSections[]) | default: null | When it started, or the date itself for single-date entries (awards, certifications, publications). | | `customSections[].items[].dates.start` | `string` | yes (type experience, schema experienceItemSchema at customSections[]; variant 1 at customSections[].items[].dates.start) | — | A year ("2022") or a year and month ("2022-03"). | @@ -526,7 +526,7 @@ Choose one coherent shape for each union value. Required fields are local to tha | `customSections[].items[].roles[]` | `object` | — (type experience, schema experienceItemSchema at customSections[]) | — | — | | `customSections[].items[].roles[].id` | `string` | yes (type experience, schema experienceItemSchema at customSections[]) | — | The unique identifier for the role. Usually generated as a UUID. | | `customSections[].items[].roles[].position` | `string` | yes (type experience, schema experienceItemSchema at customSections[]) | — | The position or job title for this role. | -| `customSections[].items[].roles[].period` | `string` | yes (type experience, schema experienceItemSchema at customSections[]) | — | The period of time this role was held, as text. Kept in sync from `dates`; prefer writing `dates`. | +| `customSections[].items[].roles[].period` | `string` | yes (type experience, schema experienceItemSchema at customSections[]) | — | The period of time this role was held, as text. Written from `dates` on every save; write `dates` instead. | | `customSections[].items[].roles[].dates` | `object` | no (type experience, schema experienceItemSchema at customSections[]) | — | Structured dates. Write these rather than the legacy text field (`period` or `date`), which is kept in sync from them. | | `customSections[].items[].roles[].dates.start` | `string or null` | yes (type experience, schema experienceItemSchema at customSections[]) | default: null | When it started, or the date itself for single-date entries (awards, certifications, publications). | | `customSections[].items[].roles[].dates.start` | `string` | yes (type experience, schema experienceItemSchema at customSections[]; variant 1 at customSections[].items[].roles[].dates.start) | — | A year ("2022") or a year and month ("2022-03"). | @@ -557,7 +557,7 @@ Choose one coherent shape for each union value. Required fields are local to tha | `customSections[].items[].area` | `string` | yes (type education, schema educationItemSchema at customSections[]) | — | The area of study or specialization. | | `customSections[].items[].grade` | `string` | yes (type education, schema educationItemSchema at customSections[]) | — | The grade or score achieved. | | `customSections[].items[].location` | `string` | yes (type education, schema educationItemSchema at customSections[]) | — | The location of the school or institution. | -| `customSections[].items[].period` | `string` | yes (type education, schema educationItemSchema at customSections[]) | — | The period of time the education was obtained over, as text. Kept in sync from `dates`; prefer writing `dates`. | +| `customSections[].items[].period` | `string` | yes (type education, schema educationItemSchema at customSections[]) | — | The period of time the education was obtained over, as text. Written from `dates` on every save; write `dates` instead. | | `customSections[].items[].dates` | `object` | no (type education, schema educationItemSchema at customSections[]) | — | Structured dates. Write these rather than the legacy text field (`period` or `date`), which is kept in sync from them. | | `customSections[].items[].dates.start` | `string or null` | yes (type education, schema educationItemSchema at customSections[]) | default: null | When it started, or the date itself for single-date entries (awards, certifications, publications). | | `customSections[].items[].dates.start` | `string` | yes (type education, schema educationItemSchema at customSections[]; variant 1 at customSections[].items[].dates.start) | — | A year ("2022") or a year and month ("2022-03"). | @@ -588,7 +588,7 @@ Choose one coherent shape for each union value. Required fields are local to tha | `customSections[].items[].id` | `string` | yes (type projects, schema projectItemSchema at customSections[]) | — | The unique identifier for the item. Usually generated as a UUID. | | `customSections[].items[].hidden` | `boolean` | yes (type projects, schema projectItemSchema at customSections[]) | — | Whether to hide the item from the resume. | | `customSections[].items[].name` | `string` | yes (type projects, schema projectItemSchema at customSections[]) | — | The name of the project. Empty while the entry is a draft, which isn't printed. | -| `customSections[].items[].period` | `string` | yes (type projects, schema projectItemSchema at customSections[]) | — | The period of time the project was worked on, as text. Kept in sync from `dates`; prefer writing `dates`. | +| `customSections[].items[].period` | `string` | yes (type projects, schema projectItemSchema at customSections[]) | — | The period of time the project was worked on, as text. Written from `dates` on every save; write `dates` instead. | | `customSections[].items[].dates` | `object` | no (type projects, schema projectItemSchema at customSections[]) | — | Structured dates. Write these rather than the legacy text field (`period` or `date`), which is kept in sync from them. | | `customSections[].items[].dates.start` | `string or null` | yes (type projects, schema projectItemSchema at customSections[]) | default: null | When it started, or the date itself for single-date entries (awards, certifications, publications). | | `customSections[].items[].dates.start` | `string` | yes (type projects, schema projectItemSchema at customSections[]; variant 1 at customSections[].items[].dates.start) | — | A year ("2022") or a year and month ("2022-03"). | @@ -680,7 +680,7 @@ Choose one coherent shape for each union value. Required fields are local to tha | `customSections[].items[].hidden` | `boolean` | yes (type awards, schema awardItemSchema at customSections[]) | — | Whether to hide the item from the resume. | | `customSections[].items[].title` | `string` | yes (type awards, schema awardItemSchema at customSections[]) | — | The title of the award. Empty while the entry is a draft, which isn't printed. | | `customSections[].items[].awarder` | `string` | yes (type awards, schema awardItemSchema at customSections[]) | — | The awarder of the award. | -| `customSections[].items[].date` | `string` | yes (type awards, schema awardItemSchema at customSections[]) | — | The date when the award was received, as text. Kept in sync from `dates`; prefer writing `dates`. | +| `customSections[].items[].date` | `string` | yes (type awards, schema awardItemSchema at customSections[]) | — | The date when the award was received, as text. Written from `dates` on every save; write `dates` instead. | | `customSections[].items[].dates` | `object` | no (type awards, schema awardItemSchema at customSections[]) | — | Structured dates. Write these rather than the legacy text field (`period` or `date`), which is kept in sync from them. | | `customSections[].items[].dates.start` | `string or null` | yes (type awards, schema awardItemSchema at customSections[]) | default: null | When it started, or the date itself for single-date entries (awards, certifications, publications). | | `customSections[].items[].dates.start` | `string` | yes (type awards, schema awardItemSchema at customSections[]; variant 1 at customSections[].items[].dates.start) | — | A year ("2022") or a year and month ("2022-03"). | @@ -712,7 +712,7 @@ Choose one coherent shape for each union value. Required fields are local to tha | `customSections[].items[].hidden` | `boolean` | yes (type certifications, schema certificationItemSchema at customSections[]) | — | Whether to hide the item from the resume. | | `customSections[].items[].title` | `string` | yes (type certifications, schema certificationItemSchema at customSections[]) | — | The title of the certification. Empty while the entry is a draft, which isn't printed. | | `customSections[].items[].issuer` | `string` | yes (type certifications, schema certificationItemSchema at customSections[]) | — | The issuer of the certification. | -| `customSections[].items[].date` | `string` | yes (type certifications, schema certificationItemSchema at customSections[]) | — | The date when the certification was received, as text. Kept in sync from `dates`; prefer writing `dates`. | +| `customSections[].items[].date` | `string` | yes (type certifications, schema certificationItemSchema at customSections[]) | — | The date when the certification was received, as text. Written from `dates` on every save; write `dates` instead. | | `customSections[].items[].dates` | `object` | no (type certifications, schema certificationItemSchema at customSections[]) | — | Structured dates. Write these rather than the legacy text field (`period` or `date`), which is kept in sync from them. | | `customSections[].items[].dates.start` | `string or null` | yes (type certifications, schema certificationItemSchema at customSections[]) | default: null | When it started, or the date itself for single-date entries (awards, certifications, publications). | | `customSections[].items[].dates.start` | `string` | yes (type certifications, schema certificationItemSchema at customSections[]; variant 1 at customSections[].items[].dates.start) | — | A year ("2022") or a year and month ("2022-03"). | @@ -744,7 +744,7 @@ Choose one coherent shape for each union value. Required fields are local to tha | `customSections[].items[].hidden` | `boolean` | yes (type publications, schema publicationItemSchema at customSections[]) | — | Whether to hide the item from the resume. | | `customSections[].items[].title` | `string` | yes (type publications, schema publicationItemSchema at customSections[]) | — | The title of the publication. Empty while the entry is a draft, which isn't printed. | | `customSections[].items[].publisher` | `string` | yes (type publications, schema publicationItemSchema at customSections[]) | — | The publisher of the publication. | -| `customSections[].items[].date` | `string` | yes (type publications, schema publicationItemSchema at customSections[]) | — | The date when the publication was published, as text. Kept in sync from `dates`; prefer writing `dates`. | +| `customSections[].items[].date` | `string` | yes (type publications, schema publicationItemSchema at customSections[]) | — | The date when the publication was published, as text. Written from `dates` on every save; write `dates` instead. | | `customSections[].items[].dates` | `object` | no (type publications, schema publicationItemSchema at customSections[]) | — | Structured dates. Write these rather than the legacy text field (`period` or `date`), which is kept in sync from them. | | `customSections[].items[].dates.start` | `string or null` | yes (type publications, schema publicationItemSchema at customSections[]) | default: null | When it started, or the date itself for single-date entries (awards, certifications, publications). | | `customSections[].items[].dates.start` | `string` | yes (type publications, schema publicationItemSchema at customSections[]; variant 1 at customSections[].items[].dates.start) | — | A year ("2022") or a year and month ("2022-03"). | @@ -776,7 +776,7 @@ Choose one coherent shape for each union value. Required fields are local to tha | `customSections[].items[].hidden` | `boolean` | yes (type volunteer, schema volunteerItemSchema at customSections[]) | — | Whether to hide the item from the resume. | | `customSections[].items[].organization` | `string` | yes (type volunteer, schema volunteerItemSchema at customSections[]) | — | The name of the organization or company. Empty while the entry is a draft, which isn't printed. | | `customSections[].items[].location` | `string` | yes (type volunteer, schema volunteerItemSchema at customSections[]) | — | The location of the organization or company. | -| `customSections[].items[].period` | `string` | yes (type volunteer, schema volunteerItemSchema at customSections[]) | — | The period of time the author was volunteered at the organization or company, as text. Kept in sync from `dates`; prefer writing `dates`. | +| `customSections[].items[].period` | `string` | yes (type volunteer, schema volunteerItemSchema at customSections[]) | — | The period of time the author was volunteered at the organization or company, as text. Written from `dates` on every save; write `dates` instead. | | `customSections[].items[].dates` | `object` | no (type volunteer, schema volunteerItemSchema at customSections[]) | — | Structured dates. Write these rather than the legacy text field (`period` or `date`), which is kept in sync from them. | | `customSections[].items[].dates.start` | `string or null` | yes (type volunteer, schema volunteerItemSchema at customSections[]) | default: null | When it started, or the date itself for single-date entries (awards, certifications, publications). | | `customSections[].items[].dates.start` | `string` | yes (type volunteer, schema volunteerItemSchema at customSections[]; variant 1 at customSections[].items[].dates.start) | — | A year ("2022") or a year and month ("2022-03"). | diff --git a/tests/e2e/specs/applications-export.spec.ts b/tests/e2e/specs/applications-export.spec.ts index c89038d54..0b8fbd13e 100644 --- a/tests/e2e/specs/applications-export.spec.ts +++ b/tests/e2e/specs/applications-export.spec.ts @@ -22,20 +22,20 @@ test("exports filtered or all owned applications with an inclusive date range", String(testInfo.project.use.baseURL), ); await otherContext.close(); - for (const [email, company, date, archived] of [ - [account.email, "Alpha Company", "2026-08-03T00:00:00Z", false], - [account.email, "Beta Archived", "2026-08-03T23:59:59Z", true], - [account.email, "Gamma Later", "2026-08-04T00:00:00Z", false], - [foreign.email, "Foreign Secret", "2026-08-03T12:00:00Z", false], + for (const [email, company, date, status] of [ + [account.email, "Alpha Company", "2026-08-03T00:00:00Z", "applied"], + [account.email, "Beta Closed", "2026-08-03T23:59:59Z", "closed"], + [account.email, "Gamma Later", "2026-08-04T00:00:00Z", "applied"], + [foreign.email, "Foreign Secret", "2026-08-03T12:00:00Z", "applied"], ] as const) { await pool.query( - `INSERT INTO application (id,user_id,company,role,status,applied_at,archived,notes,activity) - SELECT $1,id,$2,'Engineer','applied',$3,$4,$5,$6 FROM "user" WHERE email=$7`, + `INSERT INTO application (id,user_id,company,role,status,applied_at,notes,activity) + SELECT $1,id,$2,'Engineer',$4,$3,$5,$6 FROM "user" WHERE email=$7`, [ randomUUID(), company, date, - archived, + status, 'Quoted "note"\nSecond line', JSON.stringify([{ id: randomUUID(), type: "stage", stage: "applied", at: date }]), email, @@ -57,7 +57,7 @@ test("exports filtered or all owned applications with an inclusive date range", if (!path) throw new Error("CSV download was not saved"); let csv = await readFile(path, "utf8"); expect(csv).toContain('"Alpha Company"'); - expect(csv).not.toMatch(/Beta Archived|Gamma Later|Foreign Secret/); + expect(csv).not.toMatch(/Beta Closed|Gamma Later|Foreign Secret/); expect(csv).toContain('"Applied (2026-08-03)"'); expect(csv).toContain('"Quoted ""note""\nSecond line"'); @@ -76,7 +76,7 @@ test("exports filtered or all owned applications with an inclusive date range", if (!path) throw new Error("CSV download was not saved"); csv = await readFile(path, "utf8"); expect(csv).toContain('"Alpha Company"'); - expect(csv).toContain('"Beta Archived"'); + expect(csv).toContain('"Beta Closed"'); expect(csv).not.toMatch(/Gamma Later|Foreign Secret/); await page.setViewportSize({ width: 390, height: 844 }); await page.reload();