Skip to content

Commit 3b99fee

Browse files
committed
add seed demonstrating shared schema'
1 parent b3b4e25 commit 3b99fee

1 file changed

Lines changed: 87 additions & 0 deletions

File tree

src/db/seed.ts

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,93 @@ async function seed() {
403403
);
404404

405405
console.log("[seed] Created collection: knowledge-futures/climate-observations (12 records)");
406+
407+
// --- Collection 4: Pub Notes (demonstrates cross-collection schema reuse) ---
408+
const pubnotesId = uuidv4();
409+
await db.insert(schema.collections).values({
410+
id: pubnotesId,
411+
accountId: kfId,
412+
slug: "pub-notes",
413+
name: "Pub Notes",
414+
description:
415+
"Personal research notes linked to authors from the PubPub archive. Author schema shared with pubpub-archive via content-addressing.",
416+
public: true,
417+
});
418+
419+
const pubnotesSchema = {
420+
Author: {
421+
// Identical body to pubpub-archive Author → upsertSchemas returns the same schemaId
422+
type: "object",
423+
properties: {
424+
name: { type: "string" },
425+
orcid: { type: "string" },
426+
affiliation: { type: "string" },
427+
},
428+
},
429+
Note: {
430+
type: "object",
431+
properties: {
432+
authorId: { type: "string", "x-ref-type": "Author" },
433+
title: { type: "string" },
434+
body: { type: "string" },
435+
tags: { type: "array", items: { type: "string" } },
436+
createdAt: { type: "string", format: "date-time" },
437+
},
438+
},
439+
};
440+
441+
const pubnotesRecords = [
442+
{ recordId: "author-001", type: "Author", data: { name: "Sean Devine", orcid: "0000-0002-1234-5678", affiliation: "McGill University" } },
443+
{ recordId: "author-002", type: "Author", data: { name: "Maha Bali", orcid: "0000-0003-9876-5432", affiliation: "American University in Cairo" } },
444+
{ recordId: "author-003", type: "Author", data: { name: "Catherine D'Ignazio", orcid: "0000-0002-8888-7777", affiliation: "MIT" } },
445+
{ recordId: "note-001", type: "Note", data: { authorId: "author-001", title: "Notes on failure as a scientific method", body: "The Journal of Trial and Error piece makes a compelling case that failure is not noise to be filtered out but signal to be amplified. Key insight: null results constrain the hypothesis space just as strongly as positive results.", tags: ["philosophy of science", "open science", "failure"], createdAt: "2024-03-10T14:22:00.000Z" } },
446+
{ recordId: "note-002", type: "Note", data: { authorId: "author-002", title: "Reflections on open pedagogy", body: "Maha Bali's work on equity in open education keeps returning to a core tension: openness can democratize access while simultaneously exposing vulnerable learners to extractive platforms. Worth revisiting with the new data governance lens.", tags: ["open education", "equity", "pedagogy"], createdAt: "2024-04-02T09:15:00.000Z" } },
447+
{ recordId: "note-003", type: "Note", data: { authorId: "author-003", title: "Data feminism and knowledge infrastructure", body: "D'Ignazio's framing of data as always already political maps well onto our underlay design questions. Who decides what counts as a record type? What gets schematized vs. left as freetext? These are power questions.", tags: ["data feminism", "knowledge graphs", "infrastructure"], createdAt: "2024-04-18T16:45:00.000Z" } },
448+
{ recordId: "note-004", type: "Note", data: { authorId: "author-001", title: "Follow-up: collective memory paper", body: "The collective memory piece draws on Halbwachs in ways I hadn't expected. The argument that online communities form memory through repetition rather than storage resonates with how underlay versions work — it's the diff, not the snapshot, that carries meaning.", tags: ["collective intelligence", "memory", "versioning"], createdAt: "2024-05-05T11:30:00.000Z" } },
449+
];
450+
451+
const pubnotesReadme = `# Pub Notes\n\nPersonal research notes linked to authors from the [PubPub Archive](../pubpub-archive) collection.\n\n## What's included\n\n- **Author** — Researcher profiles (schema shared with pubpub-archive via content-addressing)\n- **Note** — Annotated reading notes with tags and timestamps\n\n## Coverage\n\n| Type | Count |\n|------|-------|\n| Authors | 3 |\n| Notes | 4 |\n\n## Schema reuse\n\nThe Author schema in this collection is identical to the one in pubpub-archive. Because schemas are content-addressed by hash, both collections reference the same underlying schema row — no duplication.`;
452+
453+
const pubnotesSchemaEntries = await upsertSchemas(pubnotesSchema);
454+
const pubnotesHash = computeVersionHash(pubnotesSchemaEntries, pubnotesRecords, [], pubnotesReadme);
455+
const pubnotesTotalBytes = pubnotesRecords.reduce((sum, r) => sum + Buffer.byteLength(JSON.stringify(r.data), "utf-8"), 0);
456+
const [pubnotesVersion] = await db
457+
.insert(schema.versions)
458+
.values({
459+
collectionId: pubnotesId,
460+
number: 1,
461+
semver: "v1.0.0",
462+
hash: pubnotesHash,
463+
baseNumber: null,
464+
message: "Initial pub notes",
465+
readme: pubnotesReadme,
466+
pushedBy: adminId,
467+
appId: "underlay-seed/1.0",
468+
actorId: "admin",
469+
recordCount: pubnotesRecords.length,
470+
fileCount: 0,
471+
totalBytes: pubnotesTotalBytes,
472+
})
473+
.returning();
474+
475+
await db.insert(schema.versionSchemas).values(
476+
pubnotesSchemaEntries.map((e) => ({
477+
versionId: pubnotesVersion!.id,
478+
slug: e.slug,
479+
schemaId: e.schemaId,
480+
})),
481+
);
482+
483+
await db.insert(schema.records).values(
484+
pubnotesRecords.map((r) => ({
485+
versionId: pubnotesVersion!.id,
486+
recordId: r.recordId,
487+
type: r.type,
488+
data: r.data,
489+
})),
490+
);
491+
492+
console.log("[seed] Created collection: knowledge-futures/pub-notes (7 records)");
406493
console.log("[seed] Done.");
407494
process.exit(0);
408495
}

0 commit comments

Comments
 (0)