You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
First part of the shared groundwork for the Collections endpoints (IN-1403, epic IN-1146). The API gets read access to the CM database, which holds collections, plus the shared response schemas the collection routes will use.
libs/postgres-client: a new workspace lib with createPostgresPool. It carries the pool settings the frontend already used, so both apps connect the same way. Queries stay in each app, per ADR-0017.
Frontend: server/utils/db.ts builds both pools through the lib. Settings and repos are unchanged.
API client: src/clients/postgres.ts builds the pool on first use from API_CM_DB_* and exposes queryCm, which turns driver and config failures into a 503, like Tinybird failures.
Health routes: /health/live always answers 200. /health/ready answers 503 only when the pod lacks required config (API_CM_DB_* or API_TB_*), naming the missing variables, so a misconfigured rollout stops. It ignores upstream health: every pod shares the CM database and Tinybird, so an outage would pull all pods at once, and each route already answers 503 for its own upstream. Both are the unversioned probes ADR-0009 reserves, and both stay out of the OpenAPI documents.
Env helpers: requiredEnv and missingEnv in src/env.ts, used by both clients and the readiness check.
Shared schemas: src/lib/collections.ts defines Collection and CollectionProject with their row guards and mappers. The list stays Postgres-only; collection-level Tinybird numbers belong to /collections/{slug}/metrics.
Build and CI: both Dockerfiles and the lint and test workflows install and build the new lib.
Configuration
The API needs these variables before this deploys, or /health/ready answers 503 and the rollout stops:
Variable
Notes
API_CM_DB_HOST
Read replica of the CM database
API_CM_DB_PORT
Defaults to 5432
API_CM_DB_DATABASE
API_CM_DB_USERNAME
Read-only user
API_CM_DB_PASSWORD
API_CM_DB_SSL
false turns TLS off for local databases
Notes
pnpm-lock.yaml also re-pairs the pg-promise peer between two crowd.dev importers. pnpm does this once a second workspace package depends on pg.
Still to come on IN-1403
The shared public-only collections query
Collection-scope routing and the collections, categories and oss-index autoload groups
Route-suite variants and pagination
Tests
libs/postgres-client: pool options.
api/tests/health.test.ts: live, ready with full config, ready while the CM database is down, missing config, env parsing, and queryCm failures.
api/tests/collections.test.ts: row guards and mappers.
Document null owner behavior for community collections
api/src/lib/collections.ts:51
This contract says owner is null only for curated collections, but toCollection also returns null for a community collection whose ownerName is unavailable, as the new test explicitly covers. Document that case so API consumers do not infer owner: null means type: curated.
This issue also appears on line 103 of the same file.
Medium Risk
Adds required deploy config (API_CM_DB_*) and new read paths to the shared CM Postgres; misconfiguration blocks rollout via readiness, but query/SQL bugs would affect future collection endpoints.
Overview
Introduces @lfx-insights/postgres-client so the API and Nuxt app share the same Postgres pool settings; the frontend switches server/utils/db.ts to that helper, and CI/Docker builds now include the new workspace package.
The standalone API gains CM database read access via API_CM_DB_* and queryCm (driver/config errors become 503 like Tinybird). /health/live and /health/ready are registered on the app; readiness follows ADR-0022—it only validates required env (CM + Tinybird), not upstream connectivity—documented in a new ADR and reflected in the public API plan.
Collections groundwork adds TypeBox schemas and row mappers in collections.ts, plus collections-db with public-only list/slug/member SQL (filters, sort, pagination bind params). v1-alpha pre-registers autoload groups for collections, categories, and oss-index when those route folders exist; HTTP handlers are not in this diff. Env helpers requiredEnv / missingEnv centralize config checks for clients and readiness.
Reviewed by Cursor Bugbot for commit 7c9960e. Bugbot is set up for automated code reviews on this repo. Configure here.
Readiness reports malformed API_TB_HOST values as ready, although the Tinybird client later builds request URLs from this value and every affected route fails. Validate an absolute HTTP(S) URL as part of the config-only probe.
Percentage validation allows values outside the 0–100 range
api/src/lib/collections.ts:243
This accepts every finite number, including negative values and values above 100, even though both callers represent percentages. Bound the value to 0–100 so malformed pipe rows cannot pass validation.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
First part of the shared groundwork for the Collections endpoints (IN-1403, epic IN-1146). The API gets read access to the CM database, which holds collections, plus the shared response schemas the collection routes will use.
libs/postgres-client: a new workspace lib withcreatePostgresPool. It carries the pool settings the frontend already used, so both apps connect the same way. Queries stay in each app, per ADR-0017.server/utils/db.tsbuilds both pools through the lib. Settings and repos are unchanged.src/clients/postgres.tsbuilds the pool on first use fromAPI_CM_DB_*and exposesqueryCm, which turns driver and config failures into a 503, like Tinybird failures./health/livealways answers 200./health/readyanswers 503 only when the pod lacks required config (API_CM_DB_*orAPI_TB_*), naming the missing variables, so a misconfigured rollout stops. It ignores upstream health: every pod shares the CM database and Tinybird, so an outage would pull all pods at once, and each route already answers 503 for its own upstream. Both are the unversioned probes ADR-0009 reserves, and both stay out of the OpenAPI documents.requiredEnvandmissingEnvinsrc/env.ts, used by both clients and the readiness check.src/lib/collections.tsdefinesCollectionandCollectionProjectwith their row guards and mappers. The list stays Postgres-only; collection-level Tinybird numbers belong to/collections/{slug}/metrics.Configuration
The API needs these variables before this deploys, or
/health/readyanswers 503 and the rollout stops:API_CM_DB_HOSTAPI_CM_DB_PORTAPI_CM_DB_DATABASEAPI_CM_DB_USERNAMEAPI_CM_DB_PASSWORDAPI_CM_DB_SSLfalseturns TLS off for local databasesNotes
pnpm-lock.yamlalso re-pairs thepg-promisepeer between two crowd.dev importers. pnpm does this once a second workspace package depends onpg.Still to come on IN-1403
collections,categoriesandoss-indexautoload groupsTests
libs/postgres-client: pool options.api/tests/health.test.ts: live, ready with full config, ready while the CM database is down, missing config, env parsing, andqueryCmfailures.api/tests/collections.test.ts: row guards and mappers.main