Fix full charge catalog search and prescription stock recovery #775
Workflow file for this run
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
| name: CI | |
| on: | |
| push: | |
| branches: [development, staging, main] | |
| pull_request: | |
| branches: [development, staging, main] | |
| permissions: | |
| contents: read | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| persist-credentials: false | |
| - uses: pnpm/action-setup@f520eceda224fe1a4aed5a2a27a194379a409996 # v6 | |
| - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7 | |
| with: | |
| node-version: 24 | |
| cache: "pnpm" | |
| - run: pnpm install --frozen-lockfile | |
| - name: Verify public release contents | |
| run: pnpm verify:oss-release | |
| - name: Audit production dependencies | |
| run: pnpm audit --prod --audit-level high | |
| - run: pnpm type-check | |
| - run: pnpm test | |
| - run: pnpm build | |
| # Note: next build includes linting — no separate lint step needed | |
| migration-integrity: | |
| name: Migration history integrity | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| # The append-only check resolves the actual merge base and compares | |
| # every pre-existing SQL/snapshot byte plus every journal entry. | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - uses: pnpm/action-setup@f520eceda224fe1a4aed5a2a27a194379a409996 # v6 | |
| - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7 | |
| with: | |
| node-version: 24 | |
| cache: "pnpm" | |
| - run: pnpm install --frozen-lockfile | |
| - name: Verify append-only migration history | |
| env: | |
| MIGRATION_INTEGRITY_EVENT_NAME: ${{ github.event_name }} | |
| MIGRATION_INTEGRITY_PR_BASE_SHA: ${{ github.event.pull_request.base.sha }} | |
| MIGRATION_INTEGRITY_PUSH_BEFORE_SHA: ${{ github.event.before }} | |
| run: pnpm --filter @openpims/db db:migrations:check | |
| rls: | |
| name: RLS tenant isolation | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| services: | |
| postgres: | |
| image: postgres:16-alpine | |
| env: | |
| POSTGRES_USER: openpims | |
| POSTGRES_PASSWORD: openpims | |
| POSTGRES_DB: openpims | |
| ports: | |
| - 5432:5432 | |
| options: >- | |
| --health-cmd "pg_isready -U openpims" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| env: | |
| DATABASE_URL: postgresql://openpims:openpims@localhost:5432/openpims | |
| OPENPIMS_APP_DB_PASSWORD: openpims_app | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| persist-credentials: false | |
| - uses: pnpm/action-setup@f520eceda224fe1a4aed5a2a27a194379a409996 # v6 | |
| - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7 | |
| with: | |
| node-version: 24 | |
| cache: "pnpm" | |
| - run: pnpm install --frozen-lockfile | |
| # Apply committed migrations, apply RLS (+ least-priv role), then prove | |
| # tenant isolation against a real Postgres on every PR. | |
| - run: pnpm --filter @openpims/db db:migrate | |
| - name: Execute RLS ownership preflight contract | |
| run: pnpm --filter @openpims/db db:rls:preflight:test | |
| # A data-only migration has no schema snapshot to prove it ran. Exercise | |
| # the baseline command against a disposable database and prove that exact | |
| # and later cutoffs both fail without a ledger until live data is safe. | |
| - name: Execute snapshotless baseline safety contract | |
| env: | |
| BASELINE_POSTCONDITION_DB_INTEGRATION: "1" | |
| run: pnpm --filter @openpims/web exec vitest run lib/__tests__/baseline-postconditions.integration.test.ts | |
| # Schema drift guard: if drizzle-kit generate produces anything, a schema | |
| # change was committed without its migration (or a migration was written | |
| # without its snapshot, which silently re-emits old DDL forever). | |
| - name: Check schema matches committed migrations | |
| run: | | |
| pnpm --filter @openpims/db db:generate | |
| if [ -n "$(git status --porcelain packages/db/drizzle)" ]; then | |
| echo "::error::Schema and committed migrations are out of sync — run pnpm db:generate and commit the result." | |
| git status --porcelain packages/db/drizzle | |
| exit 1 | |
| fi | |
| - run: pnpm --filter @openpims/db db:rls | |
| # Client treatment-plan decisions are legal record evidence. Prove the | |
| # sealed revision/response graph, signature hash binding, replay refusal, | |
| # immutable grants, and tenant/no-context isolation in real PostgreSQL. | |
| - name: Execute treatment-plan evidence contract | |
| run: | | |
| pnpm --filter @openpims/db db:treatment-plan-evidence:test | |
| pnpm --filter @openpims/db db:treatment-plan-concurrency:test | |
| # Signed consent rows and their exact PDFs are legal evidence. Exercise | |
| # both the owner-only sealed recovery path and app-role immutability, | |
| # privilege, tenant, replay, and exact-byte recovery boundaries. | |
| - name: Execute signed-consent evidence contract | |
| env: | |
| OPENPIMS_APP_DATABASE_URL: postgresql://openpims_app:openpims_app@localhost:5432/openpims | |
| run: pnpm --filter @openpims/db db:consent-evidence:test | |
| # The staff authoring API is dark by default. Exercise the complete | |
| # protected route with the least-privilege app role against disposable | |
| # real PostgreSQL, including replay, rollback, RLS, and two-writer races. | |
| - name: Execute treatment-plan staff authoring contract | |
| env: | |
| TREATMENT_PLAN_AUTHORING_DB_INTEGRATION: "1" | |
| TREATMENT_PLAN_AUTHORING_ENABLED: "true" | |
| run: pnpm --filter @openpims/web exec vitest run server/__tests__/visit-treatment-plan-authoring.integration.test.ts | |
| # Recreate the exact staging-era 0093 state in a disposable database, | |
| # preserve existing settlement evidence through 0094, advance through | |
| # later migrations, and attack every finance tenant/privilege boundary | |
| # with the restricted application role under the current RLS contract. | |
| - name: Execute finance schema adoption contract | |
| run: pnpm --filter @openpims/db db:finance-adoption:test | |
| # Demo received the dormant backup/MFA objects from non-main migrations. | |
| # Rebuild both a fresh-main database and that exact populated object shape, | |
| # then prove the canonical forward migration is lossless and fail closed. | |
| - name: Execute demo schema reconciliation contract | |
| run: pnpm --filter @openpims/db db:demo-schema-reconciliation:test | |
| # Exercise the clinic-facing patient + owner search through the real | |
| # router and least-privilege RLS role. The fixture proves literal LIKE | |
| # escaping, deterministic bounds, context cleanup, and cross-tenant deny. | |
| - name: Execute patient and owner search database contract | |
| env: | |
| PATIENT_SEARCH_DB_INTEGRATION: "1" | |
| run: pnpm --filter @openpims/web exec vitest run server/__tests__/patient-search.integration.test.ts | |
| # Steven Dennis's long-chart workflow crosses multiple clinical tables. | |
| # Exercise the exact read-only POST projection as openpims_app, including | |
| # literal matching, lifecycle lineage, keyset paging, role gates, RLS, | |
| # clinic-local dates, and high-cardinality query-plan evidence. | |
| - name: Execute patient history search contract | |
| env: | |
| PATIENT_HISTORY_DB_INTEGRATION: "1" | |
| run: pnpm --filter @openpims/web exec vitest run server/__tests__/patient-history.integration.test.ts | |
| # Template catalog selection is a clinic-facing data boundary. Exercise | |
| # the real router as the least-privilege app role and prove literal, | |
| # bounded, deterministic, active-only, tenant-isolated search behavior. | |
| - name: Execute template catalog search contract | |
| env: | |
| TEMPLATE_CATALOG_DB_INTEGRATION: "1" | |
| run: pnpm --filter @openpims/web exec vitest run server/__tests__/template-catalog-search.integration.test.ts | |
| # Steven Dennis exposed a real route-level patient merge 500 caused by | |
| # changing isolation inside a nested savepoint. Exercise the protected | |
| # router as openpims_app and prove the event is written in the outer | |
| # SERIALIZABLE tenant transaction with replay and RLS cleanup intact. | |
| - name: Execute patient merge transaction contract | |
| env: | |
| PATIENT_MERGE_DB_INTEGRATION: "1" | |
| run: pnpm --filter @openpims/web exec vitest run server/__tests__/patient-merge-transaction.integration.test.ts | |
| # Compile, bind, and execute the exact read-only SQL used by the shared | |
| # platform-admin and daily SMS operations queues. Unit tests cannot catch | |
| # postgres.js timestamp encoders or correlated identifier rendering. | |
| - name: Execute SMS operations queue SQL | |
| env: | |
| SMS_QUEUE_DB_INTEGRATION: "1" | |
| run: pnpm --filter @openpims/web exec vitest run lib/messaging/__tests__/sms-operations-queues.integration.test.ts | |
| # Execute the immutable provider-resolution insert validations and | |
| # evidence assertions against the fully migrated disposable database. | |
| - name: Execute SMS provider-resolution database contract | |
| run: pnpm --filter @openpims/db db:sms-provider-resolutions:test | |
| # Exercise real PostgreSQL row/advisory locks, savepoints, and durable | |
| # event convergence with synthetic data only. No provider adapter is | |
| # imported or called, and every hosted SMS capability remains disabled. | |
| - name: Execute provider-free SMS concurrency drill | |
| env: | |
| SMS_CONCURRENCY_DB_INTEGRATION: "1" | |
| MESSAGING_PROVISIONING_ENABLED: "false" | |
| MESSAGING_INBOUND_ENABLED: "false" | |
| MESSAGING_SENDING_ENABLED: "false" | |
| run: pnpm --filter @openpims/web exec vitest run lib/messaging/__tests__/sms-concurrency-drill.integration.test.ts | |
| # The reminder sweep is a candidate list. Prove against real PostgreSQL | |
| # that dispatch-time revalidation honors clinic enablement, each clinic's | |
| # lead window, cancellation, and rescheduling before a provider claim. | |
| - name: Execute appointment reminder policy SQL | |
| env: | |
| REMINDER_POLICY_DB_INTEGRATION: "1" | |
| run: pnpm --filter @openpims/web exec vitest run lib/messaging/__tests__/appointment-reminder-eligibility.integration.test.ts | |
| - name: Prove tenant/RLS pool-reuse isolation | |
| run: pnpm --filter @openpims/db db:rls:test | |
| - run: pnpm --filter @openpims/db db:migration-runs:test |