Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/dependabot.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,17 @@ updates:
- dependency-name: "@types/node"
update-types: ["version-update:semver-major"]

- package-ecosystem: "gomod"
directory: "/lambdas/goose-migrator-lambda/src"
schedule:
interval: "daily"
cooldown:
default-days: 7
groups:
go-dependencies:
patterns:
- "*"

- package-ecosystem: "pre-commit"
directory: "/"
schedule:
Expand Down
14 changes: 13 additions & 1 deletion .github/workflows/stage-2-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,21 @@ jobs:
test-name: "Jest Lambda Tests"
report-title: "Lambdas Coverage Report"

test-goose-migrations:
name: "Test Goose DB Migrations"
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: "Checkout code"
uses: actions/checkout@v6
- name: "Initialize mise"
uses: ./.github/actions/init-mise
- name: "Run Goose Migration Tests"
run: mise run test-migrations

perform-static-analysis:
name: "Perform static analysis"
needs: [test-unit-ui, test-unit-lambda]
needs: [test-unit-ui, test-unit-lambda, test-goose-migrations]
runs-on: ubuntu-latest
permissions:
id-token: write
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,8 @@ junit.xml

# Test configuration with personal credentials
tests/users.ts

# Goose migrator build artifacts
lambdas/goose-migrator-lambda/goose-migrator-lambda.zip
lambdas/goose-migrator-lambda/src/bootstrap
.migrator-build-cache/
9 changes: 9 additions & 0 deletions .gitleaksignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# SEE: https://github.com/gitleaks/gitleaks/blob/master/README.md#gitleaksignore

cd9c0efec38c5d63053dd865e5d4e207c0760d91:docs/guides/Perform_static_analysis.md:generic-api-key:37

# False positives: AWS Secrets Manager path names, not actual secrets

lambdas/goose-migrator-lambda/migrations/000002_seed_home_test_data.sql:generic-api-key:18
lambdas/goose-migrator-lambda/migrations/000002_seed_home_test_data.sql:generic-api-key:42

# False positives: OAuth client_id values (public identifiers, not secrets)
lambdas/goose-migrator-lambda/migrations/000007_supplier_data_update.sql:generic-api-key:3
lambdas/goose-migrator-lambda/migrations/000007_supplier_data_update.sql:generic-api-key:8
14 changes: 14 additions & 0 deletions .mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ node = "24.14.1"
# https://github.com/pnpm/pnpm/releases
"npm:pnpm" = "10.33.0"

# https://go.dev/dl/
go = "1.26.2"
Comment thread
iichr marked this conversation as resolved.

# https://github.com/pressly/goose/releases
"go:github.com/pressly/goose/v3/cmd/goose" = "3.27.0"

[tasks.pre-commit]
description = "Run pre-commit checks on all files"
run = "pre-commit run --all-files --show-diff-on-failure --color=always"
Expand All @@ -73,3 +79,11 @@ run = "pre-commit run --from-ref origin/main --to-ref HEAD --show-diff-on-failur
[tasks.install-pnpm]
description = "Install pnpm dependencies"
run = "pnpm install --frozen-lockfile"

[tasks.test-migrations]
description = "Test Goose DB migrations against local PostgreSQL in Docker"
run = "./lambdas/goose-migrator-lambda/scripts/test-migrations.sh"

[tasks.test-migrations-keep]
description = "Test migrations and keep PostgreSQL container running"
run = "KEEP_CONTAINER=true ./lambdas/goose-migrator-lambda/scripts/test-migrations.sh"
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ After running `pnpm start`, use targeted commands instead of restarting everythi
pnpm run local:deploy
```

- **Database schema or seed changes** (rerun DB migration container, including goose migrations):
- **Database schema or seed changes** (rerun goose migrations and seed data):

```shell
pnpm run local:service:db:migrate
Expand Down Expand Up @@ -170,7 +170,7 @@ After running `pnpm start`, use targeted commands instead of restarting everythi
pnpm run local:frontend:restart
```

- **Restart backend containers only** (Postgres, LocalStack, WireMock, db-migrate):
- **Restart backend containers only** (Postgres, LocalStack, WireMock):

```shell
pnpm run local:compose -- stop postgres-db localstack wiremock
Expand Down
89 changes: 25 additions & 64 deletions database/03-seed-hometest-data.sql
Comment thread
iichr marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -8,64 +8,33 @@

SET search_path TO hometest;

INSERT INTO supplier (
supplier_id,
supplier_name,
service_url,
website_url,
client_secret_name,
client_id,
oauth_token_path,
order_path,
oauth_scope,
results_path
)
VALUES (
'c1a2b3c4-1234-4def-8abc-123456789abc',
'Preventx',
'http://wiremock:8080',
'https://www.preventx.com/',
'test_supplier_client_secret',
'preventx-client-id',
'/oauth/token',
'/order',
'orders results',
'/results'
)
ON CONFLICT (supplier_id) DO NOTHING;

INSERT INTO supplier (
supplier_id,
supplier_name,
service_url,
website_url,
client_secret_name,
client_id,
oauth_token_path,
order_path,
oauth_scope,
results_path
)
VALUES (
'd2b3c4d5-2345-4abc-8def-23456789abcd',
'SH:24',
'http://wiremock:8080',
'https://sh24.org.uk/',
'test_supplier_client_secret',
'sh24-client-id',
'/oauth/token',
'/order',
'order results',
'/results'
)
ON CONFLICT (supplier_id) DO NOTHING;
-- Override dev/staging supplier credentials and service URL with local values.
-- Goose migrations (000002, 000006, 000009) insert these suppliers with
-- environment-specific credentials/URLs/paths that don't exist or don't match
-- locally. WireMock expects: oauth at /oauth/token, orders at /order.
UPDATE supplier
SET
client_secret_name = 'test_supplier_client_secret',
service_url = 'http://wiremock:8080',
oauth_token_path = '/oauth/token',
order_path = '/order'
WHERE supplier_id IN (
'11111111-1111-4111-8111-111111111111',
'77777777-7777-4777-8777-777777777777'
);

-- PCR test type (goose migration 000005 only seeds 31676001)
INSERT INTO test_type (test_code, description)
VALUES
('31676001', 'HIV antigen test'),
('PCR', 'Polymerase Chain Reaction')
VALUES ('PCR', 'Polymerase Chain Reaction')
ON CONFLICT (test_code) DO NOTHING;

-- PCR offerings (goose migration 000012 only seeds test code 31676001)
INSERT INTO la_supplier_offering (offering_id, supplier_id, test_code, la_code, effective_from)
VALUES
('20000002-0000-4000-8000-000000000001', '11111111-1111-4111-8111-111111111111', 'PCR', '1440', DATE '2026-02-09'),
('20000002-0000-4000-8000-000000000002', '77777777-7777-4777-8777-777777777777', 'PCR', '4230', DATE '2026-02-09')
ON CONFLICT (la_code, supplier_id, test_code) DO NOTHING;

INSERT INTO patient_mapping (patient_uid, nhs_number, birth_date)
VALUES (
'e3c4d5e6-3456-4bcd-8efa-3456789abcde',
Expand All @@ -82,18 +51,10 @@ VALUES (
)
ON CONFLICT (nhs_number) DO NOTHING;

INSERT INTO la_supplier_offering (offering_id, supplier_id, test_code, la_code, effective_from)
VALUES
('a5e6f7a8-5678-4def-8abc-56789abcdefa', 'c1a2b3c4-1234-4def-8abc-123456789abc', '31676001', '1440', DATE '2026-02-09'),
('b6f7a8b9-6789-4efa-8bcd-6789abcdefab', 'c1a2b3c4-1234-4def-8abc-123456789abc', 'PCR', '1440', DATE '2026-02-09'),
('c7a8b9c0-7890-4fab-8cde-789abcdefabc', 'd2b3c4d5-2345-4abc-8def-23456789abcd', '31676001', '4230', DATE '2026-02-09'),
('d8b9c0d1-8901-4abc-8def-89abcdefabcd', 'd2b3c4d5-2345-4abc-8def-23456789abcd', 'PCR', '4230', DATE '2026-02-09')
ON CONFLICT (la_code, supplier_id, test_code) DO NOTHING;

INSERT INTO test_order (order_uid, supplier_id, patient_uid, test_code, originator)
VALUES (
'e9c0d1e2-9012-4bcd-8efa-90abcdefabcd',
'c1a2b3c4-1234-4def-8abc-123456789abc',
'11111111-1111-4111-8111-111111111111',
'e3c4d5e6-3456-4bcd-8efa-3456789abcde',
'31676001',
'seed-migration'
Expand All @@ -103,7 +64,7 @@ ON CONFLICT (order_uid) DO NOTHING;
INSERT INTO test_order (order_uid, supplier_id, patient_uid, test_code, originator)
VALUES (
'fab1c2d3-0123-4cde-8fab-01abcdefabcd',
'd2b3c4d5-2345-4abc-8def-23456789abcd',
'77777777-7777-4777-8777-777777777777',
'f4d5e6f7-4567-4cde-8fab-456789abcdef',
'PCR',
'seed-migration'
Expand Down
31 changes: 0 additions & 31 deletions database/migrations/000002_static_data.sql

This file was deleted.

17 changes: 0 additions & 17 deletions database/migrations/000004_add_results_to_supplier_table.sql

This file was deleted.

30 changes: 0 additions & 30 deletions database/migrations/000009_add_order_status_reminder_table.sql

This file was deleted.

37 changes: 36 additions & 1 deletion lambdas/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,24 @@ lambdas/
│ │ ├── index.ts
│ │ └── [other files]
│ └── lib # shared code
├── goose-migrator-lambda/
│ ├── src/
│ │ ├── main.go
│ │ ├── go.mod
│ │ └── go.sum
│ ├── migrations/
│ │ └── *.sql
│ └── scripts/
│ ├── build.sh
│ └── test-migrations.sh
└── package.json
```

## Development Rules

### Directory Naming

- All Lambdas must be direct subdirectories of `src/`
- All TypeScript Lambdas must be direct subdirectories of `src/`
- Lambda directory names must end with `-lambda` suffix
- Each Lambda directory contains its handler and related code

Expand Down Expand Up @@ -114,3 +124,28 @@ pnpm test
```

**Note:** Integration tests are slower (~10-30s startup) but provide confidence that infrastructure components work correctly with real external systems.

## Goose Migrator Lambda (Go)

The `goose-migrator-lambda/` contains a Go-based Lambda that runs database migrations using [Goose](https://github.com/pressly/goose). Unlike the TypeScript lambdas above, it has its own build process and directory structure.

Comment thread
iichr marked this conversation as resolved.
Note that `lambdas/goose-migrator-lambda/migrations/` is the source of truth for all goose migration files in this repository.

Comment thread
iichr marked this conversation as resolved.
Comment thread
iichr marked this conversation as resolved.
### Build

```bash
# Build the Lambda zip (uses content hashing to skip unnecessary rebuilds)
./lambdas/goose-migrator-lambda/scripts/build.sh
```

Output: `lambdas/goose-migrator-lambda/goose-migrator-lambda.zip`

### Test Migrations

```bash
# Run migrations against a local PostgreSQL container (requires Docker)
mise run test-migrations

# Same, but keep the PostgreSQL container running
mise run test-migrations-keep
```
File renamed without changes.
Loading
Loading