app/db/cv.ts
49 lines and 6 functions in DrDustinEdwards/dustinedwards-info, at commit 1590ba4 on 2026-10-24. This file on GitHub.
Functions
| Function | Lines | Complexity | Covered | CRAP | Mutation |
|---|---|---|---|---|---|
| listCvRows | 13 to 25 | 1 | No data: no coverage report in this map | No data: no coverage report in this map | No data: no mutants in this code |
| <anonymous:24> | 24 to 24 | 1 | No data: no coverage report in this map | No data: no coverage report in this map | No data: no mutants in this code |
| readCv | 32 to 42 | 2 | No data: no coverage report in this map | No data: no coverage report in this map | No data: no mutants in this code |
| <anonymous:34> | 34 to 34 | 1 | No data: no coverage report in this map | No data: no coverage report in this map | No data: no mutants in this code |
| listCvCitedDois | 48 to 54 | 3 | No data: no coverage report in this map | No data: no coverage report in this map | No data: no mutants in this code |
| <anonymous:53> | 53 to 53 | 2 | No data: no coverage report in this map | No data: no coverage report in this map | No data: no mutants in this code |
Imports
It imports app/db/client.ts, app/db/publications.ts, app/db/schema.ts, app/lib/cv/compile.mjs, app/lib/cv/types.ts. Imported by app/lib/carrel/cv-handler.server.ts, app/lib/cv/pdf.server.ts, app/lib/cv/save.server.ts, app/lib/health/checks.server.ts, app/lib/operator/api.server.ts, app/lib/operator/sync-tools.server.ts, app/lib/publications/save.server.ts, app/routes/cv.charts[.json].ts, app/routes/cv.tsx, app/routes/cv[.md].ts.
Source
// The cv table: read by the CV page, its charts, its markdown twin and the operator API. Written only by
// writeCvRow in app/lib/cv/save.server.ts and by sync:content, from a compile (app/lib/cv/compile.mjs).
import { asc, eq } from "drizzle-orm";
import { compileCv } from "~/lib/cv/compile.mjs";
import type { CvFileRecord } from "~/lib/cv/types";
import { listPublishedPublications } from "./publications";
import { getDb } from "./client";
import { cv } from "./schema";
/** Every file's row, in slug order, with its record parsed. */
export async function listCvRows(env: Env) {
const rows = await getDb(env)
.select({
slug: cv.slug,
type: cv.type,
record: cv.record,
sourceBlobSha: cv.sourceBlobSha,
syncedAt: cv.syncedAt,
})
.from(cv)
.orderBy(asc(cv.slug));
return rows.map(({ record, ...row }) => ({ ...row, record: JSON.parse(record) as CvFileRecord }));
}
/**
* The CV as the page, the charts and the twin draw it: the rows joined to the published publication records
* and compiled by the one door (compileCv). A set of rows that does not make a CV (a row missing before the
* first sync, a cited paper unpublished since) throws, naming the repair, rather than answering a partial CV.
*/
export async function readCv(env: Env) {
const [rows, publications] = await Promise.all([listCvRows(env), listPublishedPublications(env)]);
const compiled = compileCv({ records: rows.map((row) => row.record), publications });
if (!compiled.ok) {
throw new Error(
`The CV rows in D1 do not make a CV: ${compiled.errors.join("; ")}. The repair is the content sync ` +
"(npm run sync:content, or the sync_cv operator tool).",
);
}
return compiled.cv;
}
/**
* The DOIs (lower-cased) the CV's publications file cites, as D1 holds them now. The publication save reads it to
* refuse a change that would leave the CV citing a paper that is gone, and to know when a paper's save changes the CV.
*/
export async function listCvCitedDois(env: Env): Promise<Set<string>> {
const row = (await getDb(env).select({ record: cv.record }).from(cv).where(eq(cv.slug, "publications")).limit(1))[0];
if (!row) return new Set();
const record = JSON.parse(row.record) as CvFileRecord;
if (record.type === "profile") return new Set();
return new Set(record.entries.flatMap((entry) => ("doi" in entry ? [entry.doi.toLowerCase()] : [])));
}