Skip to content
StarLive demo →
ReferenceChecked against main · 31 Oct 20267 min read

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 run in src/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.

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.

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

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

Every script except generate:api is a thin wrapper around Vite+’s vp command. Run them from src/AppointMe.Frontend.

src/AppointMe.Frontend/package.jsonView source ↗
"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

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.

There’s no tool manifest or script in the repo. Install dotnet-ef globally, then add migrations per module.

Terminal window
dotnet tool install --global dotnet-ef
dotnet 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 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.

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.