feat(core,server): log feed, titles on changes, work titles on copies

GET log (engagements and listens, keyset over at/kind/id), listChanges
title and intoTitle, listCopies workTitle, all via batched lookups.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Lucas WintherandClaude Opus 5.5 committed 2026-10-30 22:11:53 +01:00
1 parent 5fa59310f3
commit c2e8c83f86
12 files changed
+561 -7

No files matched your search

+20
View File
@@ -2,6 +2,7 @@ import { expect, test } from "bun:test";
import { forEachDialect } from "@sttracker/db/testing";
import { createCopy, listCopies, softDeleteCopy, updateCopy } from "../src/copies.ts";
import { defineCustomField } from "../src/custom-fields.ts";
import { upsertEntry } from "../src/entries.ts";
import { NotFoundError, ValidationError } from "../src/errors.ts";
import { getHistory, restoreVersion } from "../src/history.ts";
import { makeUser, makeWork } from "./user-layer-fixtures.ts";
@@ -73,4 +74,23 @@ forEachDialect("copies", (getDb) => {
NotFoundError,
);
});
test("listCopies carries the work title, with the user's title override", async () => {
const db = getDb();
const userId = await makeUser(db);
const dune = await makeWork(db, { title: "Dune" });
const hyperion = await makeWork(db, { title: "Hyperion" });
await upsertEntry(db, userId, dune, { overrides: { title: "Dune (1965)" } }, "user");
const a = await createCopy(db, userId, { workId: dune });
const b = await createCopy(db, userId, { workId: hyperion });
const c = await createCopy(db, userId, { titleHint: "HALF-LIFE 2" });
const byId = new Map((await listCopies(db, userId)).map((x) => [x.id, x]));
expect(byId.get(a.id)!.workTitle).toBe("Dune (1965)");
expect(byId.get(b.id)!.workTitle).toBe("Hyperion");
expect(byId.get(c.id)!.workTitle).toBeNull();
// Another user's override does not leak.
const bob = await makeUser(db, "bob");
await createCopy(db, bob, { workId: dune });
expect((await listCopies(db, bob))[0]!.workTitle).toBe("Dune");
});
});