ICPI API And Persistence Surface
Status: ACTIVE
Sprint: Extraction Prep Sprint 44
Purpose
This document maps the current ICPI route/API surface and persistence surface and classifies each area as:
Resolving locale, route permissions, and workspace projection.
Current scope: Guest
Category: 10_normative | Version: v1.0.0
Owner: DOCUMENT_CUSTODIAN | Review cycle: 90 days
Approval authority: GOVERNANCE_ADMIN
Documentation portal is read-only. Editing and mutation endpoints are disabled.
Kvary platform is originally created in Georgian. Where a Georgian version exists, Georgian is authoritative for platform UI, documentation, and legal interpretation.
Translations into other languages are provided for convenience. Some records may originate in other languages and carry their own source or legal locale for a specific flow, but where a Georgian version is available, the Georgian version prevails for platform-level wording and interpretation.
Metadata incomplete: Document ID, Version, Owner Role, Last Review Date, Next Review Date, Change Log
Status: ACTIVE
Sprint: Extraction Prep Sprint 44
This document maps the current ICPI route/API surface and persistence surface and classifies each area as:
svc-tenders host surface| Route | Current module | Auth surface | Classification | Notes |
| --- | --- | --- | --- | --- |
| GET /icpi/prices | registerIcpiRoutes.ts | public/read-only | stable route surface, temporarily shell-hosted | paginated price list and filter surface |
| GET /icpi/suggest | registerIcpiRoutes.ts | public/read-only | stable route surface, temporarily shell-hosted | item suggestion/search helper |
| GET /icpi/latest/:itemCode | registerIcpiRoutes.ts | public/read-only | stable route surface, temporarily shell-hosted | latest lookup by item and region |
| GET /icpi/estimate | registerIcpiRoutes.ts | public/read-only | stable route surface, temporarily shell-hosted | derived estimate from latest price point |
| POST /icpi/upsert | registerIcpiRoutes.ts | requireServiceAuth-gated | stable route surface, shell-auth-hosted | ingestion/admin-style write path |
| Route | Current module | Auth surface | Classification | Notes |
| --- | --- | --- | --- | --- |
| GET /api/v1/icpi/prices | services/api/src/routes/icpi.ts | public/read-only | stable gateway surface | pure proxy |
| GET /api/v1/icpi/suggest | services/api/src/routes/icpi.ts | public/read-only | stable gateway surface | pure proxy |
| GET /api/v1/icpi/latest/:itemCode | services/api/src/routes/icpi.ts | public/read-only | stable gateway surface | pure proxy |
| GET /api/v1/icpi/estimate | services/api/src/routes/icpi.ts | public/read-only | stable gateway surface | pure proxy |
| POST /api/v1/icpi/upsert | services/api/src/routes/icpi.ts | requireGatewayAuth-gated | stable gateway surface | forwards auth header upstream |
| Consumer | Surface used | Classification | Notes |
| --- | --- | --- | --- |
| apps/web/src/app/[locale]/(portal)/icpi/page.tsx | fetchIcpiPrices, fetchIcpiSuggestions | stable UI consumer | dedicated ICPI portal page |
| apps/web/src/app/[locale]/[country]/(portal)/icpi/page.tsx | re-export of locale ICPI page | stable UI alias | country-scoped alias only |
| apps/web/src/portal/api.ts fetchIcpiLatestPrice | /api/v1/icpi/latest/:itemCode | stable client helper, active consumer not verified here | helper exists even if current page does not use it |
| apps/web/src/portal/api.ts ICPI upsert client | no helper found | MISSING | no verified web upsert UI path found |
VERIFIED: the ICPI read API surface is already stable enough to survive extraction with minimal contract churn.VERIFIED: the write surface is small and explicit: one upsert endpoint.VERIFIED: gateway hosting is already extraction-friendly because it uses ICPI_SERVICE_URL.VERIFIED: the direct svc-tenders host surface is still shell-hosted only because the runtime has not been split yet.| Persistence element | Current source | Classification | Extraction note |
| --- | --- | --- | --- |
| icpi_price_points | migration 0007_icpi_price_points.sql | stable, ICPI-owned persistence | clean single-table family |
| idx_icpi_price_points_lookup | migration 0007_icpi_price_points.sql | stable | standard lookup support |
| idx_icpi_price_points_period | migration 0007_icpi_price_points.sql | stable | period filtering support |
| idx_icpi_price_points_category | migration 0007_icpi_price_points.sql | stable | category filtering support |
| idx_icpi_price_points_latest_lookup | migration 0008_icpi_latest_lookup_index.sql | stable | latest-item lookup optimization |
| Method family | Current source | Classification | Notes |
| --- | --- | --- | --- |
| upsertIcpiPricePoints(...) | src/icpi/repository.ts | stable ICPI persistence surface | transaction + batched upsert |
| countIcpiPricePoints(...) | src/icpi/repository.ts | stable read surface | filter-aware count |
| listIcpiPricePoints(...) | src/icpi/repository.ts | stable read surface | paginated read |
| suggestIcpiItems(...) | src/icpi/repository.ts | stable read surface | region-aware suggestion and fallback behavior |
| findLatestIcpiPricePoint(...) | src/icpi/repository.ts | stable read surface | item/region latest lookup |
| Residue | Current source | Classification | Extraction note |
| --- | --- | --- | --- |
| ICPI delegation methods on TendersRepository | services/svc-tenders/src/repository.ts | transitional compatibility surface | not needed as ICPI owner once callers stop importing through root repository |
| ICPI type exports on TendersRepository file | services/svc-tenders/src/repository.ts | mixed type-hosting surface | should move before clean extraction |
VERIFIED: ICPI persistence is already isolated enough for package-first or API-first extraction.VERIFIED: ICPI does not currently depend on mixed root-repository SQL blocks for its real data path.VERIFIED: the remaining persistence problem is not table ownership. It is type and compatibility hosting.VERIFIED: DB-boundary-first extraction is not required because the table family is already narrow and low-coupling.| Surface | Verdict | Why |
| --- | --- | --- |
| Direct svc-tenders ICPI routes | stable but shell-hosted | route shape is clean, host is temporary |
| Gateway /api/v1/icpi/* surface | stable | already the cleanest extraction seam |
| Web ICPI page | stable UI consumer | product-distinct page exists |
| icpi_price_points persistence | stable | dedicated table and repository |
| Root repository ICPI delegation | transitional | compatibility only |
| Root repository ICPI types | mixed | real reuse, but wrong long-term host |
| ICPI event/runtime surface | MISSING | no Kafka/outbox dependence found |
ICPI_SERVICE_URL.svc-tenders domains.