Canonical resource access inventory
This inventory tracks code that reads or writes the canonical resource graph. It is intentionally organized by ownership and data flow rather than by table name alone. Keep it current when a resource access path is added, removed, or moved.
Canonical schema: web-tanstack/prisma/schema.prisma.
Invariants
Section titled “Invariants”resourcesowns canonical content metadata, lifecycle state, and nullable monitored-source provenance throughsource_id.resource_translationsowns localized title, summary, content, and keywords.libraryowns per-user resource ownership and saved state.resource_linksowns user-scoped pins between product-domain objects.sourcesowns monitored feed configuration.resources.source_idis the stable relation;platform_metadata.sourceNameis a compatibility/display snapshot and non-monitored resources may keepsource_id = NULL.- The app Worker owns user-facing resource/library/link and blob lifecycle writes. Core owns acquisition, enrichment, translations, entities, and AI Search synchronization. Chat uses app/core service bindings and does not query product-owned resource tables directly.
Schema and database-only objects
Section titled “Schema and database-only objects”| Path | Role | Audit status |
|---|---|---|
web-tanstack/prisma/schema.prisma |
Canonical Prisma schema | audited |
web-tanstack/prisma/manual-indexes.sql |
Constraints, indexes, localized view, triggers | audited; canonical source/effective-date indexes back keyset reads, while obsolete publication-only and JSON source-name indexes are explicitly removed |
workers/core-worker/src/db/schema.ts |
Core Drizzle mirror | audited; nullable canonical source_id mirror added in the resource architecture refactor round 1 |
workers/core-worker/scripts/check-drizzle-prisma-drift.mjs |
Static schema/domain drift gate | audited; now checks complete columns and type domain |
web-tanstack/prisma/*cutover*.sql, drop-paper-graph.sql, fix-citations-cleanup-trigger.sql, issue-227-schema-consolidation.sql |
Historical/operator migrations | historical; do not use as runtime API |
web-tanstack/prisma/repair-resource-source-names.sql |
Idempotent provenance repair | audited against canonical sources; live corpus backfill completed in round 4 |
web-tanstack/prisma/resource-source-provenance.sql |
Idempotent canonical source FK/backfill | unique platform/name plus unambiguous RSS/Twitter/YouTube identity matching; unmatched rows intentionally remain null |
web-tanstack/prisma/source-monitoring-policy.sql |
Idempotent Source policy hardening | backfills non-null acquisition modes and enforces platform/mode domains without a physical rename cutover |
web-tanstack/prisma/resource-source-metadata-cleanup.sql |
Post-deploy provenance cleanup | removes the historical RSS metadata source ID after Core reads the canonical FK |
App Worker: canonical reads
Section titled “App Worker: canonical reads”| Path | Surface | Audit status |
|---|---|---|
web-tanstack/src/server/resource-read.ts |
Ranked hydration, effective-date keyset reads, detail selection, and card media hydration | feed, JSON API, HTTP MCP, and public saves reuse this server-only module directly; no surface-specific read-model wrappers |
web-tanstack/src/server/domain/resource.ts |
Shared resource selection, projection, access, localization, date, source, filter, type, and URL policy | feed, workspace links, and public saves use one canonical summary shape; source display prefers the relation and uses metadata/URL only as presentation fallback |
web-tanstack/src/server/domain/collection-previews.ts |
Authorized collection preview resource projection | audited; duplicate raw SQL consolidated in round 4 and public lifecycle aligned in round 7 |
web-tanstack/src/server/domain/workspace-context.ts |
Authorized workspace resource/document context | audited; moved from chat in round 1 and read policy aligned in round 4 |
web-tanstack/src/server/feed.ts |
Article feed, resource detail, and related resources | list/related/detail share the canonical summary selection and projections; detail keeps its separate lazy content-access boundary and YouTube transcript hydration |
web-tanstack/src/server/feeds.ts |
Feed catalog and custom-feed CRUD | split at the existing CRUD/article boundary without a barrel or adapter layer |
web-tanstack/src/server/api/resources-json.ts |
Public JSON resource list/detail/search | one GET query contract drives recent/search; typed filters run before retrieval; ranked pages expose nextOffset and chronological pages expose nextCursor |
web-tanstack/src/routes/api.mcp.ts |
HTTP MCP resource search/read | audited; typed source/type filters and canonical source IDs align with the JSON API |
web-tanstack/src/server/resources.ts |
Workspace/document resource hydration | reads reuse canonical projections; URL writes return the domain result directly and let the existing query invalidation refresh read models |
web-tanstack/src/server/collections.ts |
Collection resource hydration and profile saves | audited across reads and writes in rounds 3–4; shared card DTO aligned in round 6 |
web-tanstack/src/server/wiki.ts |
Collection graph/resource lookup | audited; access/source/date policy deduplicated in round 4 |
web-tanstack/src/server/profile.ts |
Public profile resources | audited; corpus-only public previews enforced in round 4 and direct card DTO/effective dates aligned in round 6 |
web-tanstack/src/server/share.ts |
Shared-document resource authorization | audited in round 4 |
web-tanstack/src/server/workspaces.ts |
Workspace collection pin hydration | audited in round 4 |
web-tanstack/src/server/domain/workspaces.ts |
Domain RPC resource hydration | audited in round 4 |
web-tanstack/src/routes/api.media.asset.$.ts |
Authorized resource blob read | audited in round 3 |
web-tanstack/src/routes/api.upload.ts |
Upload workflow resource link | durable save precedes best-effort enqueue; write response returns IDs/status without re-reading an unused resource DTO |
web-tanstack/src/routes/api.workflow.$id.status.ts |
Authorized workflow status lookup | audited; library and direct-link access aligned with resync in round 3 |
web-tanstack/src/routes/api.collections.export.ts |
Authorized Core OKF export proxy | audited; Core owns collection/resource authorization and streamed response generation |
web-tanstack/src/server/core-search.ts |
App-to-Core search and related-resource RPC boundary | audited; typed source/type/effective-date filters cross the RPC boundary, invalid ranks are rejected, RPC results are disposed, and search failures remain errors instead of empty results |
App Worker: authoritative writes
Section titled “App Worker: authoritative writes”| Path | Surface | Audit status |
|---|---|---|
web-tanstack/src/server/media.ts |
Blob resource create/quota/R2/delete | audited; canonical metadata and guarded R2 deletion in round 3 |
web-tanstack/src/server/core-ingest.ts |
App resource shell/translation creation before core RPC | audited; durable save and best-effort enqueue separated in round 3 |
web-tanstack/src/server/domain/resource-links.ts |
Resource-link ownership and canonical pin resolution | shared ownership policy, single-statement deletes, and batch URL linking without an unused citation re-read |
web-tanstack/src/server/collections.ts |
Library visibility/state and collection pins | audited in round 3 |
web-tanstack/src/routes/api.resources.save.ts |
Saved-URL HTTP boundary | audited in round 3 |
web-tanstack/src/server/domain/rpc.ts |
Chat-to-app resource write boundary | only the chat-used addDocumentResource operation remains; unused resource CRUD/link RPC contracts were removed |
Core Worker: engine reads and writes
Section titled “Core Worker: engine reads and writes”| Path | Role | Audit status |
|---|---|---|
workers/core-worker/src/ingest/domain/resource-store.ts |
Canonical resource, provenance, and translation persistence | guarded translation upserts preserve human content and keep original-language ownership aligned with the resource row |
workers/core-worker/src/ingest/resource-persistence.ts, workers/core-worker/src/entities/normalize.ts |
Enrichment status and entity graph persistence | normalized entity replacement and human translation protection remain inside the Core persistence boundary |
workers/core-worker/src/ingest/content-localization-workflow.ts |
Translation workflow reads/writes | audited in round 2 |
workers/core-worker/src/ingest/domain/source-store.ts |
Monitored source policy and watermarks | explicit acquisition/monitoring policy and canonical source domains aligned in the resource architecture refactor round 2 |
workers/core-worker/src/ingest/platforms/{rss,twitter,youtube}.ts |
Source discovery, dedup, provenance, and enqueue | audited in round 2 |
workers/core-worker/src/ingest/workflow.ts |
Resource workflow orchestration | audited; explicit shell loader in round 2 |
workers/core-worker/src/ingest/web-acquisition.ts |
Acquisition resource input | audited in round 2 |
workers/core-worker/src/corpus.ts |
Core resource/search/related RPC reads | typed orthogonal source/type/category/effective-date filters validate at the RPC boundary and are re-applied during PostgreSQL hydration |
workers/core-worker/src/ai-search.ts |
AI Search indexing, synchronization, deletion, and retrieval | newsence-corpus-v5 is the single production read/write/delete target; it indexes effective date, source ID, type, and category for pre-retrieval filtering; runtime code does not reference the legacy instance |
workers/core-worker/src/okf.ts |
OKF resource graph reads | audited in rounds 5 and 7; owner-scoped links, public lifecycle, locale fallback, deterministic export order, and streaming verified |
workers/core-worker/src/index.ts |
RPC/workflow entrypoints | audited in round 2 |
Chat Worker and CLI consumers
Section titled “Chat Worker and CLI consumers”| Path | Role | Audit status |
|---|---|---|
workers/chat-worker/src/chat/tools/registry.ts |
Core search-news and read-context RPC consumer |
direct SQL is absent; disposable search/context RPC results are cloned before returning to AI SDK tools |
workers/chat-worker/src/chat/tools/podcast-context.ts |
Thin app Domain context RPC consumer | audited; direct SQL removed in round 1 |
workers/chat-worker/src/chat/tools/add-resource.ts |
App Domain RPC consumer | audited in round 3 |
web-tanstack/src/server/domain/contracts.ts |
App-owned workspace/resource/blob contracts | audited; introduced in round 1 and narrowed in round 3 |
packages/newsence-cli/src/api/resources.ts |
Public resource HTTP client | search/recent share the GET query builder with canonical source UUIDs and content types while preserving explicit rank-offset/keyset-cursor pagination; resource DTOs expose nullable source_id |
packages/newsence-cli/src/api/collections.ts |
Collection resource HTTP client | audited; response contract aligned in round 4 |
packages/newsence-cli/src/mcp.ts |
CLI MCP resource consumer | audited; schemas and results expose the same canonical source/type vocabulary as HTTP MCP |
Frontend consumers
Section titled “Frontend consumers”The frontend must consume server-owned DTOs and must not reconstruct database ownership rules. These consumers were audited during the read-layer refactor; resource/card identity is explicit, source filter state stores Source UUIDs rather than display names, duplicate profile/collection adapters and localization wrappers were removed, and effective dates now come from server policy. Direct consumers live in:
web-tanstack/src/lib/queries/*web-tanstack/src/routes/_workspaceApp._noResources.index.tsxweb-tanstack/src/components/feed/*web-tanstack/src/components/article/*web-tanstack/src/lib/resource-workflow.ts(one normalized result list for URL/upload invalidation and polling)web-tanstack/src/components/workspace/ResourcesRail.tsxweb-tanstack/src/components/collections/*web-tanstack/src/components/chat/*web-tanstack/src/types/contracts.ts
Completion searches
Section titled “Completion searches”Run these from the repository root and classify every new match before marking the resource refactor complete:
rg -n --glob '!**/generated/**' \ '\b(prisma|tx)\.(resource|resourceTranslation|libraryItem|resourceLink|source)\.' \ web-tanstack/src
rg -n -i --glob '!**/generated/**' \ '(from|join|update|into|delete from)[[:space:]]+"?resources"?|resource_translations|resource_links' \ web-tanstack/src workers packagesHistorical SQL and documentation matches are not runtime touchpoints, but must remain clearly labeled so stale models are not copied back into production code.
Completion audit
Section titled “Completion audit”- The completion searches above were rerun after round 9 and every runtime match maps to an inventory entry; remaining SQL matches are canonical schema, operator migrations, or documentation.
- Live read-only invariant checks found no enriched corpus row missing its original translation, URL, title, or source; no duplicate normalized URL, orphan resource link, invalid public library row, ownerless private resource, or blob library row without a storage key.
- All resource, translation, link, and library indexes declared in
manual-indexes.sqlare present in the live database. - Final verification uses the web
check,typecheck, and productionbuild; core Drizzle/Prisma drift,typecheck, and lint; chattypecheckand lint; plus real workflow, scheduled cron, AI Search, search RPC, related-resource, and PostgreSQL smoke checks.