"My Self Serve (MySS) provides online access to income and disability assistance for residents of British Columbia."
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.
Prerequisites: Docker, the .NET 10 SDK, Node 22+.
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.AspireHostIt 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.
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 --waitThis 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).strapiand its role come fromInfra/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 IntakeDbContextor, 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.
- API:
cd Apps/MyssApi && dotnet run→ http://localhost:5000 - ICM middleware:
dotnet run --project Apps/IcmApi.Host→ http://localhost:5100 (needs theIcm:*user secrets; seeApps/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)
- 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.Testsanddotnet test Apps/IcmApi.Host.Tests - Webclient:
cd Apps/MyssWebclient && npm run test:unitandnpm run test:browser-headless— the browser tests need a one-timenpx playwright install chromium
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.
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.
https://github.com/bcgov/myss-web https://github.com/bcgov/myss-api