Commands
Every command for AppointMe. Run the .NET 10 stack with Aspire or Docker Compose, build and test, the Vite+ frontend, API client generation, EF Core migrations, Wolverine codegen and dotnet new.
- Run everything
dotnet runinsrc/AppointMe.Aspire- Test everything
dotnet test AppointMe.sln, no database needed- Frontend
- npm scripts that call Vite+
vp - Extra tool
dotnet-ef, for migrations only
These are the commands the repo itself uses: in its README, CI workflows, Dockerfile, npm scripts and agent skills. Run them from the repo root unless the table says otherwise. In a project generated with dotnet new -n, replace AppointMe in paths with your name.
One command starts the whole stack. The others run a single piece, the backing services, or fix the dev certificate.
Aspire and the API
Section titled “Aspire and the API”| Command | Run from | What it does |
|---|---|---|
aspire run |
Repo root | Starts the AppHost through the Aspire CLI, which .aspire/settings.json points at src/AppointMe.Aspire. Optional: the AppHost doesn’t need the CLI. |
dotnet dev-certs https --check --trust |
Anywhere | Exits 0 when the dev certificate is trusted. The AppHost runs this check at startup. |
dotnet dev-certs https --clean |
Anywhere | Removes the dev certificate. Run --trust again afterwards. |
dotnet dev-certs https --trust |
Anywhere | Creates and trusts the dev certificate. Once per machine. |
dotnet run |
src/AppointMe.Aspire |
Starts SQL Server, Keycloak, Mailpit, the API and the frontend |
dotnet run --project src/AppointMe.Api --launch-profile https |
Repo root | Runs the API alone on https://localhost:7233 and http://localhost:5179. Needs the Compose services. |
Docker Compose
Section titled “Docker Compose”Compose runs only SQL Server, Keycloak and Mailpit. Run these from the repo root.
| Command | What it does |
|---|---|
./docker/keycloak/export-dev-cert.sh |
Trusts the dev certificate and exports it as docker/keycloak/certs/keycloak.crt and keycloak.key. Once, before the first up. |
docker compose down |
Removes the containers. The sqlserver-data and keycloak-data volumes stay. |
docker compose down -v |
Removes the containers and both volumes |
docker compose logs -f keycloak |
Follows one service’s logs (sqlserver, keycloak or mailpit) |
docker compose ps |
Shows status. SQL Server and Keycloak report healthy when ready. |
docker compose stop |
Stops the containers and keeps all data |
docker compose up -d |
Starts SQL Server, Keycloak and Mailpit |
Build and test
Section titled “Build and test”dotnet build also writes the OpenAPI document, and dotnet test needs no running services.
| Command | What it does |
|---|---|
docker build -f src/AppointMe.Api/Dockerfile . |
Builds the production image: the SPA bundle, Wolverine’s pre-generated handlers and the API. The context is the repo root. |
dotnet build AppointMe.sln |
Builds all 17 projects, and writes src/AppointMe.Api/obj/openapi.json |
dotnet build AppointMe.sln -c Release --no-restore |
The CI build, after dotnet restore AppointMe.sln |
dotnet test AppointMe.sln |
Runs all 221 tests in six projects. They’re unit tests that never open a database connection, so nothing needs to be running. Name the solution: the root also holds AppointMe.slnx, and a bare dotnet test stops with MSB1011. |
dotnet test AppointMe.sln --filter "FullyQualifiedName~TestName" |
Runs the tests whose full name contains TestName |
dotnet test src/CRM/AppointMe.Crm.Tests |
Runs one test project |
Frontend
Section titled “Frontend”Every script except generate:api is a thin wrapper around Vite+’s vp command. Run them from src/AppointMe.Frontend.
"scripts": { "dev": "vp dev", "build": "vp build", "check": "vp check", "lint": "vp lint .", "format": "vp fmt", "preview": "vp preview", "generate:api": "dotnet build ../AppointMe.Api/AppointMe.Api.csproj -c Release --nologo -v q && orval"},| Command | What it does |
|---|---|
npm ci |
Installs the locked versions without touching package-lock.json. CI and the Dockerfile use it. |
npm run build |
Production build into dist/ |
npm run check |
Format check, lint and type-check in one pass. CI runs it and fails on unformatted code. |
npm run dev |
Dev server on https://localhost:5173, with the /api, /signin-oidc and /admin proxy |
npm run format |
Formats the code with Oxfmt, using the fmt block of vite.config.ts |
npm run lint |
Oxlint with type-aware rules, using the lint block of vite.config.ts |
npm run preview |
Serves the production build locally |
npx vp check --no-fmt --no-lint |
Type-check only |
API client
Section titled “API client”npm run generate:api builds the API, which writes the OpenAPI document, then runs orval on it. No running backend is needed.
| Command | Run from | What it does |
|---|---|---|
git diff --stat src/AppointMe.Frontend/src/api/ |
Repo root | Shows the contract change as reviewers see it |
npm run generate:api |
src/AppointMe.Frontend |
Builds AppointMe.Api in Release, then regenerates src/api/client.ts and src/api/client.schemas.ts |
npx orval |
src/AppointMe.Frontend |
Regenerates from the last build’s obj/openapi.json without building. Only useful when that build is current. |
The build runs the app’s startup in the Codegen environment, with placeholder settings from appsettings.Codegen.json and no database. It uses Release so it doesn’t collide with an API that Aspire is running from bin/Debug. See Typed API client.
EF Core migrations
Section titled “EF Core migrations”There’s no tool manifest or script in the repo. Install dotnet-ef globally, then add migrations per module.
dotnet tool install --global dotnet-efdotnet ef migrations add AddCustomerNotes \ --project src/CRM/AppointMe.Crm \ --startup-project src/AppointMe.Api \ --context CrmDbContext \ --output-dir Database/Migrations| Module | --project |
--context |
|---|---|---|
| Booking | src/Booking/AppointMe.Booking |
BookingDbContext |
| CRM | src/CRM/AppointMe.Crm |
CrmDbContext |
| Identity | src/Identity/AppointMe.Identity |
IdentityDbContext |
| Organizations | src/Organizations/AppointMe.Organizations |
OrganizationsDbContext |
--startup-project src/AppointMe.Api and --output-dir Database/Migrations are the same for all four. dotnet ef migrations remove with the same --project, --startup-project and --context undoes the last migration, as the tool’s own output suggests. Database migrations walks through a full change.
Wolverine codegen
Section titled “Wolverine codegen”Wolverine generates its handler code at runtime in Development, and ahead of time for other environments. These commands drive that generation.
| Command | What it does |
|---|---|
dotnet run --project src/AppointMe.Api -- codegen preview |
Prints the generated handler code |
dotnet run --project src/AppointMe.Api -- codegen write |
Writes it to src/AppointMe.Api/Internal/Generated/, which is git-ignored. The Dockerfile runs this before dotnet publish. |
dotnet run --project src/AppointMe.Api -- codegen test |
Generates and compiles all handler code in memory. CI runs it after the build. |
dotnet run --project src/AppointMe.Api -- codegen delete |
Deletes the written files |
dotnet run --project src/AppointMe.Api -- help |
Lists every JasperFx command the API host offers, such as describe, resources and storage |
Any argument list that contains codegen switches the host to the Codegen environment, so these commands need no database. CI’s exact form is dotnet run --project src/AppointMe.Api/AppointMe.Api.csproj -c Release --no-build --no-launch-profile -- codegen test.
Template
Section titled “Template”dotnet new creates a renamed copy of the whole repo. The smoke test is the gate that keeps the template working.
| Command | What it does |
|---|---|
./templates/smoke-test.sh |
Upstream repo only. Packs the template, installs it, generates Contoso.Booking, then builds, tests, lints and builds the output. Set NAME to test another name, KEEP=1 to keep the output. |
dotnet new appointme -n Contoso.Booking |
Generates a project in ./Contoso.Booking. -n must be a dotted .NET identifier. |
dotnet new appointme -n Contoso.Booking -o <dir> |
Generates into <dir> instead |
dotnet new install BravoDev.AppointMe.Templates::1.2.1 |
Installs the template package. Pin the version so a generation is reproducible. |
dotnet new uninstall BravoDev.AppointMe.Templates |
Removes the template package |
Why is there no database update step?1 min · optional
The API applies migrations itself. Each module’s Add<Module>Module() calls AddDatabaseMigration<TContext>(), and one hosted service runs MigrateAsync() for every registered context when the API starts, locally and in Azure alike.
That keeps one path for every environment: start the app and its schema is current. The cost is that a broken migration stops the API from starting, so test new migrations locally before you tag a release.