Module: catalog · Dimension: architecture · Severity: medium · Location: apps/server/src/catalog/service/metadata-writes.ts:1
Problem
The module has no repo.ts (or repo/ directory). Raw drizzle-orm + schema imports are spread across service/access-throttle.ts, service/discover-feed.ts, service/metadata-reads.ts, service/metadata-writes.ts, service/prune.ts, service/recommendations.ts, and service/user-mirrors.ts (938 LOC total), each importing drizzle-orm and ../../db/schema/catalog directly. service/index.ts's CatalogService class then imports and calls these query functions as if they were a repo layer, e.g. import { patchArtworkUrls, upsertMetadata } from "./metadata-writes" (service/index.ts:24).
Why it matters
Convention rule 2 requires 'No raw drizzle outside repo.ts — service/jobs call repo.fn(). Only repo.ts imports drizzle-orm + schema.' Here the DB-access layer is fragmented across files named/labeled as 'service' with no single owned repo boundary; a future storage refactor (e.g. swapping the canonical_metadata upsert strategy) has to touch 7 separately-named files instead of one repo module, and there is no single place to audit every query issued against catalog's own tables.
Suggested fix
Consolidate the DB-access functions (access-throttle, discover-feed, metadata-reads, metadata-writes, prune, recommendations, user-mirrors query logic) into a repo/ directory (module-layout.md permits promoting repo.ts to a repo/ dir past 300 LOC) exporting plain repo.fn() calls; keep only orchestration/business logic (mutex, throttling policy, cross-cutting composition) in service/index.ts.
Fable-panel validated: 3/3 votes.
Filed from automated per-module audit workflow (Opus/Sonnet research → Fable-panel decision). Unverified by a human — triage before acting.
Module:
catalog· Dimension: architecture · Severity: medium · Location:apps/server/src/catalog/service/metadata-writes.ts:1Problem
The module has no repo.ts (or repo/ directory). Raw drizzle-orm + schema imports are spread across service/access-throttle.ts, service/discover-feed.ts, service/metadata-reads.ts, service/metadata-writes.ts, service/prune.ts, service/recommendations.ts, and service/user-mirrors.ts (938 LOC total), each importing
drizzle-ormand../../db/schema/catalogdirectly. service/index.ts's CatalogService class then imports and calls these query functions as if they were a repo layer, e.g.import { patchArtworkUrls, upsertMetadata } from "./metadata-writes"(service/index.ts:24).Why it matters
Convention rule 2 requires 'No raw drizzle outside repo.ts — service/jobs call repo.fn(). Only repo.ts imports drizzle-orm + schema.' Here the DB-access layer is fragmented across files named/labeled as 'service' with no single owned repo boundary; a future storage refactor (e.g. swapping the canonical_metadata upsert strategy) has to touch 7 separately-named files instead of one repo module, and there is no single place to audit every query issued against catalog's own tables.
Suggested fix
Consolidate the DB-access functions (access-throttle, discover-feed, metadata-reads, metadata-writes, prune, recommendations, user-mirrors query logic) into a repo/ directory (module-layout.md permits promoting repo.ts to a repo/ dir past 300 LOC) exporting plain repo.fn() calls; keep only orchestration/business logic (mutex, throttling policy, cross-cutting composition) in service/index.ts.
Fable-panel validated: 3/3 votes.
Filed from automated per-module audit workflow (Opus/Sonnet research → Fable-panel decision). Unverified by a human — triage before acting.