Canonical data model
web-tanstack/prisma/schema.prisma is the canonical schema. Objects Prisma
cannot express live in web-tanstack/prisma/manual-indexes.sql.
flowchart LR Source["Source"] -->|"nullable provenance"| Resource["Resource"] Resource --> Translation["ResourceTranslation"] User["User"] --> Library["LibraryItem"] --> Resource Workspace["Workspace"] -->|"pins"| Link["ResourceLink"] --> Resource Workspace -->|"pins"| Link --> Collection["Collection"] Collection -->|"pins"| Link Workspace -->|"owns through workspace_id"| Document["UserDocument"] User -->|"pins shared document"| Link --> Document
Resource content
Section titled “Resource content”| Prisma model | Database table | Responsibility |
|---|---|---|
Resource |
resources |
canonical URL/blob identity, type, scope, lifecycle, dates, source provenance, platform payload |
ResourceTranslation |
resource_translations |
localized title, summary, content, keywords |
Source |
sources |
monitored RSS, Twitter, or YouTube configuration and monitoring policy |
ResourceEntity |
resource_entities |
normalized resource-to-entity edge |
Resource.type is the only content-kind discriminator. Resource.sourceId is
a nullable foreign key to the monitored source that produced the resource; it
is not an array of resources on Source. Deleting a source sets provenance to
null and does not delete content.
platform_metadata stores provider payloads and display snapshots. Its
sourceName value is not relational identity, and it must not contain another
content-kind field.
Use two date meanings:
published_at: nullable source publication time;effective_at:published_date ?? scraped_date ?? created_at, used for discovery order and recency filters.
User ownership and visibility
Section titled “User ownership and visibility”library is the per-user edge to a canonical resource. It owns acquisition
origin, visibility, saved time, note, and state. A resource may be public corpus
content, viewer-private content, or both public and saved by a user without
duplicating the resource row.
Public corpus documents are ranked in Cloudflare AI Search. Viewer-private library documents stay in PostgreSQL and are merged with public ranks in the Web Worker. Private content never enters the public index.
Pins and citations
Section titled “Pins and citations”resource_links is a user-owned pin graph with these valid pairs:
- workspace → resource;
- collection → resource;
- workspace → collection;
- user → document.
Workspace-owned documents use user_documents.workspace_id, not a resource
link. Pinning a collection to a workspace does not copy every collection member
into workspace links; reads expand the collection one hop.
AI and document citations are inline [n](URL) markers in generated prose.
They are not resource_links rows and do not have a citation CRUD API.
Worker ownership
Section titled “Worker ownership”- Web owns product authorization, library/pin writes, feeds, collections, resource HTTP/MCP DTOs, private search, and PostgreSQL hydration.
- Core owns monitored acquisition, enrichment, translations, entities, and the public AI Search corpus.
- Chat owns chat state and tools. It calls Web/Core through service bindings and does not query product resource tables directly.
See resource-access-inventory.md for the live read/write touchpoint inventory and worker-boundaries.md for cross-Worker rules.