Skip to content
bcgovPublic

About

My Self Serve Repository

Resources

Code of conduct

Contributing

Stars

3 stars

Watchers

0 watching

Forks

Repository files navigation

My Self Serve

"My Self Serve (MySS) provides online access to income and disability assistance for residents of British Columbia."

Guidance for AI agents (and humans): the AGENTS.md hierarchy

Agent guidance is layered, and each layer is authoritative for its own depth — deeper files add app specifics, they never restate what a level above already says:

AGENTS.md                     workspace-wide rules: commands, architecture,
                              conventions, secrets policy (CLAUDE.md points here)
Apps/<App>/AGENTS.md          app-specific rules; links the app's full docs
Apps/<App>/Docs/*.md          the full docs (architecture, design principles,
                              accessibility, …) — each carries a status banner
                              saying whether it describes reality or a target

Today Apps/MyssWebclient has the app level built out (AGENTS.md, Docs/); other apps add theirs as they grow one. When guidance changes, update the layer that owns it — duplicated rules drift.

Local development

Prerequisites: Docker, the .NET 10 SDK, Node 22+.

One command: Aspire

Everything below — the containers, the EF migrations, and all three apps — can be run with a single command through the Aspire app host. Its configuration comes from Apps/MySS.AspireHost/appsettings.json (non-secret defaults, committed) plus user secrets for everything password-shaped, stored under Aspire:Parameters:* — the .env files are for the compose path only. Get the secret values from another developer or the team's central secrets store, and load them into the app host's user-secret store once. A clean checkout without them fails fast at startup, naming the first missing value. Then:

dotnet run --project Apps/MySS.AspireHost

It starts the compose containers' equivalents (Postgres 17, ClamAV, MinIO with its bucket-creation one-shot), applies the four EF migration contexts once Postgres is healthy, then starts MySSApi (http://localhost:5000), MySSContent (Strapi, http://localhost:1337, run with npm on the host), MyssWebClient (Vite) and, when an ICM base URL is configured (Icm:BaseUrl in the shared user-secret store), the ICM middleware IcmApi (http://localhost:5100; see Apps/IcmApi.Host/README.md) — with a dashboard (URL printed at startup) showing every resource's logs, health and telemetry.

Container data lives in named volumes (myss_postgres-data, myss_clamav-db, myss_minio-data) and survives restarts; the containers themselves stop when the app host stops. The names are exactly what docker compose creates for compose.yaml, so the Aspire and compose paths share one set of data in either direction — but only one of the two can be up at a time (same host ports).

Still manual, because they live inside Strapi's admin UI: the first-visit admin user, and the API token for Strapi:ApiToken (goes in Apps/MyssApi/appsettings.local.json). The token is read-only and scoped: it needs find and findOne on Form Spec, Eligibility Rate and Error Message. A token created before the Error Message collection existed lacks the last grant; MyssApi then logs a warning and words refused submissions from its compiled defaults until the token is updated.

Start the stack manually (compose)

Strapi reads its configuration from a gitignored .env — create it from the example first (the committed values work as-is for local development):

cp Apps/MyssContent/.env.example Apps/MyssContent/.env
docker compose up -d --wait

This brings up Postgres 17, Strapi, ClamAV and MinIO (the ClamAV first start downloads its signature databases, so --wait can take a few minutes; the minio-init one-shot creates the myss-attachments bucket). The databases initialize themselves on the first start:

  • myss (the application database) is created by the Postgres image (POSTGRES_DB).
  • strapi and its role come from Infra/Development/Postgres/init/01-strapi-db.sql. Init scripts only run when the data volume is empty — they do not re-run on restarts.
  • Strapi applies its own schema migrations and seeds the POC form specs at boot.

The forms, attachments, platform and intake schemas in myss are not automatic. Apply the EF migrations once (and again after pulling new migrations):

cd Apps/MyssApi
dotnet tool restore
dotnet ef database update --context FormsDbContext
dotnet ef database update --context AttachmentsDbContext
dotnet ef database update --context PlatformDbContext
dotnet ef database update --context IntakeDbContext

or, equivalently, cd Apps/MyssApi && dotnet run -- --migrate, which applies all four and exits. Deployed environments get their migrations from the pipeline, which runs the same migrate mode as a Job before restarting the API.

The connection string in appsettings.Development.json already points at the compose Postgres.

Run the apps

  • API: cd Apps/MyssApi && dotnet run → http://localhost:5000
  • ICM middleware: dotnet run --project Apps/IcmApi.Host → http://localhost:5100 (needs the Icm:* user secrets; see Apps/IcmApi.Host/README.md)
  • Webclient: cd Apps/MyssWebclient && npm install && npm run dev → http://localhost:5173 (the forms demo is under /techdemos/forms)
  • Strapi admin: http://localhost:1337/admin — the first visit asks you to create the initial admin user (local account, any credentials)

Tests

  • ClamAV: ./test-clamav.sh — confirms the local clamd answers and actually detects (EICAR via INSTREAM, the same protocol the API uses). Run it when attachment scanning misbehaves; on a first-ever ClamAV start it will say the daemon is not answering until the signature download finishes.
  • API: dotnet test Apps/MyssApi.Tests
  • ICM client and middleware: dotnet test Apps/IcmApi.Tests and dotnet test Apps/IcmApi.Host.Tests
  • Webclient: cd Apps/MyssWebclient && npm run test:unit and npm run test:browser-headless — the browser tests need a one-time npx playwright install chromium

SonarQube Cloud

Non-draft pull requests from this repository targeting dev run four SonarQube Cloud analyses, each with its own quality gate. Fork pull requests skip analysis because they cannot access the SONAR_TOKEN secret.

Project Key
MySS API bcgov-sonarcloud_myss_api
MySS Web Client bcgov-sonarcloud_myss_webclient
MySS Content bcgov-sonarcloud_myss_content
MySS ICM Client bcgov-sonarcloud_myss_icmapi

The workflow imports OpenCover reports from the .NET tests and LCOV reports from both TypeScript test suites. Configure the SONAR_TOKEN GitHub Actions secret for the bcgov-sonarcloud organization, and disable Automatic Analysis for all four projects so the CI analyses are the single source of results.

Reset

docker compose down keeps the data. docker compose down -v wipes it — the next up re-runs the init script and the Strapi seed; re-apply the EF migrations afterwards.

Previous work

Reference Prototypes

https://github.com/bcgov/myss-web https://github.com/bcgov/myss-api

Current running app

https://myselfserve.gov.bc.ca/

About

My Self Serve Repository

Resources

Code of conduct

Contributing

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages