Add Full Slice (backend → frontend)
The kit's accelerator: deliver a feature from database to UI in one pass. This skill composes
add-feature (backend) and add-react-page (frontend) — follow each for the detailed code; this file is
the order of operations and the contract that keeps the two halves in sync.
Order of operations
- Backend slice —
add-feature(andadd-entityfirst if a new entity is needed):- Command/Query + response DTO in
Modules.{X}.Contracts/v1/{Area}/(+Contracts/Dtos/). - Handler (
public sealed, injects{X}DbContext), Validator, Endpoint (internal static Map…Endpoint,.RequirePermission(...)). - Wire in
{X}Module.MapEndpoints. Build + test backend green.
- Command/Query + response DTO in
- Lock the contract — note the final route path, HTTP method, request shape, and response DTO field names/casing. The React side must match these exactly.
- Frontend page —
add-react-pagein the chosen app:- API module calls the same path; hand-write TS types mirroring the response DTO (the API serializes C# records as camelCase JSON — TS fields are camelCase even though admin query params are PascalCase).
- Page (
useQuery/useMutation), route (RouteGuardfor admin /withSuspensefor dashboard).
- Permission — if the endpoint is gated, mirror the constant into admin's
lib/permissions.tsand gate the route (add-permission). Dashboard relies on the server 403. - Tests both sides — backend handler/validator test (xUnit/Shouldly/NSubstitute) + frontend Playwright spec (route-mocked).
The contract (the thing that breaks if you're sloppy)
| Backend | Frontend must match |
|---|---|
Endpoint route api/v{n}/{module}/{resources} |
apiFetch path |
Request: the Command/Query record fields |
request body / query-param keys (admin params PascalCase; body JSON camelCase) |
| Response: the DTO record (camelCase JSON) | the hand-written TS type |
.RequirePermission({X}Permissions...) |
(admin) RouteGuard perms + the mirrored constant |
Paginated → PagedResponse<T> |
PagedResponse<T> (admin: @/lib/api-types; dashboard: inline) |
Verify end-to-end
dotnet build src/FSH.Starter.slnx && dotnet test src/Tests/{X}.Tests
cd clients/{app} && npm run lint && npm run test:e2e
# optional manual check: dotnet run --project src/Host/FSH.Starter.AppHost (brings up API + both apps)
Checklist
- Backend slice complete + green (
add-feature) - Contract locked: route, request shape, response DTO field names
- Frontend api module path + TS types match the contract (body JSON camelCase)
- Page + route added (
add-react-page); admin permission mirrored + gated (add-permission) - Backend test + Playwright test added; both suites green