import type { CatalogEntityType } from './SubmissionRepository' import type { Catalog, CableType, DeviceCategoryDef, DeviceTemplate, Manufacturer, PortType } from '../domain/types' /** * Storage abstraction for the global port/cable/category/device-template * catalog — mirrors DiagramRepository's role, but for catalog data instead * of diagrams. Fetching returns everything the current user can see (public * entries plus their own private ones); RLS does that filtering server-side, * so implementations don't need to filter client-side. * * The `add*`/`update*` methods always create or edit an `is_public = false` * row you own — that's the regular-user "own private catalog" surface. * Getting an entry into the public catalog otherwise goes through the * submission/review workflow (organized-ideas.md §3), except for the * `admin*` methods below: per §6's capability table, an Admin/Super-Admin * can also CRUD public entries directly, without a submission — those * bypass ownership entirely (RLS's `is_admin()` clause is what actually * allows it) and only ever touch already-public rows. */ export interface CatalogRepository { /** Everything visible to the current user: public entries plus their own private ones. */ load(): Promise addDeviceCategory(name: string): Promise updateDeviceCategory(id: string, name: string): Promise /** Throws (rather than swallowing, like most methods here) if the delete * is rejected — most commonly a foreign-key violation because one of * your device templates still references this category, which the * caller needs to know about to tell you why nothing happened. */ removeDeviceCategory(id: string): Promise addManufacturer(name: string): Promise updateManufacturer(id: string, name: string): Promise /** Same throw-on-failure contract as removeDeviceCategory. */ removeManufacturer(id: string): Promise addPortType(portType: Omit): Promise updatePortType(id: string, patch: Partial>): Promise /** Same throw-on-failure contract as removeDeviceCategory — most commonly * a foreign-key violation because some device template's port still * references it. */ removePortType(id: string): Promise addCableType(cableType: Omit): Promise updateCableType(id: string, patch: Partial>): Promise removeCableType(id: string): Promise addDeviceTemplate(template: Omit): Promise updateDeviceTemplate(id: string, patch: Partial>): Promise removeDeviceTemplate(id: string): Promise /** Admin/Super-Admin direct-to-public creation — skips the submission/ * review workflow entirely, for authoring the shared library yourself * (e.g. building out the initial device catalog) rather than reviewing * someone else's proposal. Same RLS branch that already allows an Admin * to directly edit a public entry (`is_admin() and is_public`) also * covers inserting one — unlike adminUpdate* below, this is a genuinely * different write, not just an alias (is_public: true, owner_id: null * from the start). */ adminAddDeviceCategory(name: string): Promise adminAddManufacturer(name: string): Promise adminAddPortType(portType: Omit): Promise adminAddCableType(cableType: Omit): Promise adminAddDeviceTemplate(template: Omit): Promise /** Admin/Super-Admin direct edit of an already-public port/cable/device * entry — same underlying write as approving a submission, minus the * submission. */ adminUpdatePortType(id: string, patch: Partial>): Promise adminUpdateCableType(id: string, patch: Partial>): Promise adminUpdateDeviceTemplate(id: string, patch: Partial>): Promise adminUpdateDeviceCategory(id: string, name: string): Promise adminUpdateManufacturer(id: string, name: string): Promise /** Unpublishes a public entry (is_public -> false) rather than deleting * it — organized-ideas.md §3's "public catalog entries are never hard- * deleted, only hidden/unpublished". Existing diagrams that reference it * by id are unaffected; it just stops being offered for new use. */ adminUnpublish(entityType: CatalogEntityType, id: string): Promise /** Admin/Super-Admin permanent delete of a built-in (public) entry — * narrower than adminUnpublish: the caller is expected to have already * verified zero usage (no diagram references it, nothing else in the * catalog does either) before calling this, same gate already applied to * a regular user deleting their own private entry. Doesn't relax * organized-ideas.md §3's "never break an existing diagram" principle — * it only ever removes something genuinely unused (e.g. a mistake made * while authoring the library), which is why this exists alongside * adminUnpublish rather than instead of it. Same RLS branch as the other * admin* methods (`is_admin()`), so these are aliases of the plain * remove* methods above, not separate logic. Throws on failure. */ adminRemoveDeviceCategory(id: string): Promise adminRemoveManufacturer(id: string): Promise adminRemovePortType(id: string): Promise adminRemoveCableType(id: string): Promise adminRemoveDeviceTemplate(id: string): Promise }