Changelog
All notable changes to this template are documented in this file.
The format is based on Keep a Changelog, and this template adheres to Semantic Versioning.
[Unreleased]
Added
-
Template package (
templatepack/).ITLab.Template.Next.Templatesnupkg (PackageType=Template) so consumers install from the ITLab.Template feed (dotnet new install ITLab.Template.Next.Templates) instead of cloning. Packs.template.config+ src/tests/infra/.github + root files, shipping dotfiles and excluding bin/obj/node_modules/dist and repo-only docs/examples. Validated end-to-end: install from the nupkg → scaffold → 38 backend tests + SPA 8 tests + build green. Publishing pipeline at.azure/template-publish.yml(tagrelease/template/vX.Y.Z): build + solution tests → pack → scaffold smoke from the packed nupkg (dotnet new install, build, backend + SPA tests) → push to the ITLab.Template feed. -
Frontend SPA (ADR-007).
src/ITLab.Template.Next.Spa: React + Vite + TypeScript + Tailwind v4 + shadcn/ui, served same-origin by the API so the ADR-006 BFF cookie works without CORS —UseStaticFiles+ SPA fallback (reserved prefixes/v1,/health,/.well-known,/openapi,/scalarreturn 404, never HTML). Publish-time integration: the Api csproj builds the SPA (pnpm, override seams for CI) and bundlesdistintowwwroot; dev uses the Vite proxy. Typed API client via committed OpenAPI spec +openapi-typescript/openapi-fetch(hermetic codegen); session bootstrap fromGET /v1/auth/mewith CSRF middleware (X-XSRF-TOKEN) and global 401 handling — no token ever touches JavaScript. UI canon: login (react-hook-form + zod), protected shell with route guard, and Orders as living reference (paginated table, create dialog, approve — role-gated while the API stays the enforcement). Tests: Vitest + Testing Library + MSW (8).dotnet newscaffolds the SPA renamed end-to-end (folder, csproj SpaRoot, brand, titles), excludingnode_modules/dist. -
GET /v1/auth/me— current authenticated user (id, name, roles) projected fromICurrentUser, for SPA session hydration and UI gating; works for both cookie and Bearer schemes. -
OpenAPI response schemas. Endpoints now declare
.Produces<T>(...)(the doc previously had no response schemas —IResultis opaque);/v1/auth/csrfreturns a typedCsrfTokenResponse; Asp.Versioning ApiExplorer substitutes the version in paths (/v1/orders, not/v{version}/orders). Benefits Scalar UI and the SPA codegen alike. -
Phase 3 packaging —
dotnet new itlab-fullstack..template.config/template.jsondeclares the template withsourceName: ITLab.Template.Next, classifications Web/WebAPI/Worker/DDD/CQRS, andsources.modifiers.excludethat keepsexamples/,docs/,**/bin/,**/obj/, IDE state and per-devappsettings.Development.jsonout of generated projects. Smoke-tested end-to-end (dotnet new itlab-fullstack -n Probebuilds Debug + Release clean and passes 20/20 tests against renamed namespaces). -
Local authentication, dual-scheme (ADR-006, supersedes ADR-003; DevPack bumped to 10.4.0). The template ships with working auth — local ASP.NET Core Identity (
AppUser/AppRoleoverBaseIdentityDbContext, tables in theidentityschema without theAspNetprefix) issuing its own asymmetric (RSA) JWTs. Two schemes coexist via a forwarding selector: a BFFHttpOnlysession cookie for browsers (/v1/auth/session*, CSRF-protected viaBffAntiforgeryMiddleware+/v1/auth/csrf) and Bearer JWT validated through a published JWKS (/.well-known/jwks.json) for mobile (/v1/auth/token*, rotating refresh tokens) and service-to-service (/v1/auth/clients/token, client-credentials). Signing key is ephemeral in Development and a required PEM in production (fail-early).IdentitySeederseeds canonical roles + an optional admin fromIdentity:Admin:*. Authorization (RolePermissions+RoleBasedPermissionEvaluator) is unchanged across schemes. External-JWT resource-server (ADR-003) remains as a documented opt-in swap. -
DB-backed permission resolver.
RolePermissionentity +DbRolePermissionResolverwithIMemoryCache(5 min TTL per role). Seed viaRolePermissionConfiguration.HasData(Admin/Operator/Viewer × Orders.*) honored by both relational migrations and EF Core InMemory. Documented in ADR-004. -
Order concurrency token.
byte[] RowVersionmapped viaIsRowVersion()in the entity config plus a dedicated migrationAddOrderConcurrencyToken. Concurrent updates raiseDbUpdateConcurrencyExceptioninstead of silently overwriting; integration tests via EF InMemory cannot exercise the race (documented caveat) — cover with Testcontainers.MsSql when it matters. -
OpenTelemetry observability.
AddTemplateObservabilityhelper in Infrastructure ships baseline (resource, HttpClient, Runtime, EF Core ActivitySource, OTLP exporter); Api addsAddAspNetCoreInstrumentation()in its own composition root. Endpoint follows OTel env-var standard (OTEL_EXPORTER_OTLP_ENDPOINT, defaulthttp://localhost:4317). -
Bearer security scheme in OpenAPI.
BearerSecuritySchemeTransformerdeclares the scheme + document-wide requirement so Scalar UI auto-renders the Authorize button. -
Split health probes.
/health/live(no checks — process is alive) and/health/ready(filters checks taggedready, includesAddDbContextCheck<AppDbContext>). Both anonymous and opted out of rate limiting. -
Rate limiting. Built-in fixed-window per-IP partition with 1000 req/min default, configurable via
RateLimiting:PermitLimit/WindowSeconds./health/*opts out via.DisableRateLimiting(). -
CORS (opt-in). Registered only when
Cors:AllowedOriginscontains at least one entry; defaults allow any method/header + credentials + 10 min preflight cache. -
API versioning.
Asp.Versioning.Http10.0.0 with URL-segment primary reader (/v{version:apiVersion}/orders) andX-Api-Versionheader fallback. Default version 1.0,ReportApiVersionsenabled. Health probes stay unversioned. -
Docker + docker-compose. Multi-stage
Dockerfileper project (Api/Worker),.dockerignore,docker-compose.ymlorchestrating sql, api, worker and otel-collector. BuildKit secret mounts~/.nuget/NuGet/NuGet.Configso dotnet restore can hit the private feed inside the build. -
GitHub Actions CI workflow (
.github/workflows/ci.yml). Restore (usingAZURE_DEVOPS_PATsecret) + build Debug + build Release + tests with TRX logger + XPlat Code Coverage. -
examples/Customers/opt-in reference (ADR-005). Domain withEmail/Cpfvalue objects (Cpf delegates to DevPackGuard.Against.InvalidCpf), uniqueness pre-check + unique index, deactivation as state transition. 8-step copy recipe in the per-example README. Not shipped viadotnet new. -
Architecture Decision Records under
docs/adrs/(5 ADRs covering vertical slices, English-only source, JWT Bearer, DB-backed roles, examples opt-in). -
appsettings.Development.json.sampleas the copy-from reference (.env.samplepattern). Localappsettings.Development.jsonstays gitignored; the sample carries plausible Authority/Audience values for IdP-less local runs. -
Setup section in README with prerequisites, primeiro-run sequence, NuGet feed credential setup and Docker/docker-compose recipes.
-
CLAUDE.mdas the live contract for AI agents — vertical slices, returns/validation, domain events policy, permissions convention, authentication, observability, rate limiting, CORS, API versioning, EF, tests. -
LICENSE (ITLab proprietary internal).
Changed
- Canon
Pedidos→Orders(English-only). All identifiers, methods, events, DTOs, EF table names, migration names, endpoint paths and test class/method names refactored to English. Markdown docs (CLAUDE.md, README, docs/) intentionally remain in Portuguese. Documented in ADR-002. ITLabTemplateNextPermissions→Permissions. Short class identifier sosourceName: ITLab.Template.Nextsubstitution does not need custom symbols atdotnet newtime.- DevPack 10.2.3 → 10.3.0. Migrate
Result/ErrortoITLab.Template.DevPack.Corenamespace per the 10.3 BREAKING change. Drop four local shims now shipped by the package:ResultHttpExtensions,IdentityContextMiddleware,ScopedDispatchDomainEventsInterceptorand theTestAuthenticationHandler(latter moves to the newITLab.Template.DevPack.Testingnupkg). Orderconstructor chains: base(id)(DevPack 10.3AuditedSoftDeletableEntity<TKey>ctor).OrdersEndpointsusesMapPaginatedGet<TQuery, TDto>for the paginated GET (replaces ~26 LOC of manual query-string binding).Program.csusesapp.UseDevPackIdentityContext()instead of a local middleware to bridgeHttpContext.UserintoAsyncLocalCurrentUserAccessor.IntegrationTestFactoryinheritsWebApplicationFactoryBase<Program, AppDbContext>fromITLab.Template.DevPack.Testing— body collapses to a single class declaration. OverridesConfigureAdditionalServicesto injectJwtOptionsand callEnsureCreatedso the HasData seed populates the in-memory database.
Removed
PlaceholderAuthenticationHandlerand the#if !DEBUG / #errorgate — superseded by JWT Bearer (ADR-003).InMemoryRolePermissionResolver— superseded byDbRolePermissionResolver(ADR-004).Api/Extensions/ResultHttpExtensions.cs,Api/Middleware/IdentityContextMiddleware.cs,Infrastructure/Persistence/Interceptors/ScopedDispatchDomainEventsInterceptor.cs,tests/.../Setup/TestAuthenticationHandler.cs— all canonical in DevPack 10.3.0 now.- "Known doc-vs-binary mismatches in DevPack 10.2.3" section from CLAUDE.md — fixed in 10.3.
Phases overview (historical)
This template went through three phases before its first release:
- Phase 1 — initial skeleton. Project structure, base configuration, NuGet packages. Pre-this-changelog.
- Phase 2 — canon
Orders+ DevPack 10.3 absorption. Vertical-slice canon shipped, English-only refactor applied, JWT Bearer + DB-backed roles + observability + concurrency + Docker + CI all landed under theUnreleasedbucket above. - Phase 3 —
dotnet newpackaging..template.config/template.jsonshipped, smoke test verified end-to-end. Ready for first tagged release.