AssetTrack is Contoso Industries' internal application for tracking hardware assets (laptops, monitors, phones, badges, docking stations) and the employees they're assigned to. It is intentionally built as a polyglot microservices application so that course learners can practice agentic, Copilot-driven development across a realistic multi-language stack — including a couple of older Java services that still need modernization.
flowchart LR
browser([Browser]) --> web
subgraph frontend
web[web<br/>Astro SSR + React islands]
end
subgraph modern[Modern services]
assets[assets-svc<br/>.NET 8]
workforce[workforce-svc<br/>Java 21 / Spring Boot 3]
reporting[reporting-svc<br/>Python FastAPI]
notifications[notifications-svc<br/>Python FastAPI]
end
subgraph legacy[Legacy services - intentionally dated]
audit[audit-svc<br/>Java 11 / Spring Boot 2.7]
auth[auth-svc<br/>Java 11 / Spring Boot 2.7]
end
web --> assets
web --> workforce
web --> reporting
web --> auth
workforce -.audit hook<br/>not yet wired.-> audit
workforce --> notifications
assets -.JWKs.-> auth
workforce -.JWKs.-> auth
All services talk over REST/JSON. Each service owns its own SQLite database.
| Service | Stack | Port | Owns |
|---|---|---|---|
web |
Astro (SSR) + React islands + Bootstrap 5 | 4321 | UI, BFF composition |
assets-svc |
.NET 8 (ASP.NET Core minimal APIs) | 5001 | Asset CRUD + search |
workforce-svc |
Java 21 / Spring Boot 3 | 5002 | Employees + Assignments |
reporting-svc |
Python 3.12 / FastAPI | 5003 | Reports, CSV bulk import |
notifications-svc |
Python 3.12 / FastAPI | 5004 | Webhook receiver, email/Slack stub |
audit-svc |
Java 11 / Spring Boot 2.7 (legacy) | 5005 | Audit event log |
auth-svc |
Java 11 / Spring Boot 2.7 (legacy) | 5006 | JWT issuer, user lookup |
-
Open the repository in GitHub Codespaces, or in VS Code with the Dev Containers extension.
-
Wait for the devcontainer to finish provisioning. It installs:
- Node 22, .NET 8, Python 3.12, Maven, and two Java JDKs side-by-side (Java 21 for modern services, Java 11 for the two legacy services).
concurrentlyand editable Python installs for the FastAPI services (viapostCreateCommand).
-
From the workspace root:
npm run dev
This starts all seven services as plain processes (no Docker required). A startup banner prints the URL. Run
npm run dev:verboseif you need full log output instead of WARN-only. -
Open http://localhost:4321 — that's the UI. Backend services listen on 5001–5006 if you want to hit them directly with
curl.
You need Node 22, .NET 8, Python 3.12, Maven, and both Java 21 and Java 11 on your machine. Then:
npm install
npm run install:all
npm run devA docker-compose.yml is still provided as an alternative to the dockerless workflow:
docker compose up --buildOpen http://localhost:4321.
Each service folder has its own README.md with native (non-Docker) run instructions and per-service scripts. See:
services/web/README.mdservices/assets-svc/README.mdservices/workforce-svc/README.mdservices/reporting-svc/README.mdservices/notifications-svc/README.mdservices/audit-svc/README.mdservices/auth-svc/README.md
auth-svc issues RS256 JWTs from POST /token. Other services validate tokens via the JWKs document at http://auth-svc:8080/.well-known/jwks.
For course exercises that aren't about auth, the frontend runs with DEV_TOKEN_MODE=true, which uses a pre-issued long-lived token so learners aren't blocked by login flows. To exercise the real flow, set it to false.
This is a teaching codebase. Several services have deliberate gaps that drive the course exercises (see exercises.md). For example:
- The two legacy Java services use raw JDBC string concatenation and have SQL injection.
reporting-svchas old-style Python helpers and an import endpoint that crashes on bad rows.assets-svcaccepts unvalidated input on create.- The dashboard renders some status badges with the wrong colors.
workforce-svcdoes not yet POST toaudit-svcon assignment changes.
See exercises.md for the full exercise list.
See exercises.md. Each exercise is atomic — completing one is not a prerequisite for another. Exercises cover all five stacks (Astro, .NET, modern Java, Python, legacy Java) so learners can pick what's most useful to them.