Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions .agents/skills/agenza-api-contract-review/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,25 @@ description: >
generated by `npm run generate:api-types` from services-service's live
OpenAPI document, checked for staleness by `npm run generate:api-types:check`
(also gated in CI — `api-contract-check` in `.github/workflows/frontend-ci.yml`).
- Frontend hand-written types: per-feature DTO interfaces in
`src/infrastructure/mappers/*.ts` (see `agent-skills/agenza-frontend-feature`
step 5) — these exist for features not yet covered by the generated
client, or that intentionally narrow it.
- Frontend decoders/mappers: feature-local infrastructure files under
`src/features/*/infrastructure/`. A hand-written wire type is justified only
when no generated contract exists or when it intentionally narrows unknown
input without shadowing the generated shape.

## Checks

1. **Generated types are current.** Run `npm run generate:api-types:check
--workspace=apps/admin-frontend` (requires services-service running and
reachable, matching the CI job) — a failure here means a controller/DTO
changed without regenerating.
2. **DTO duplication.** A hand-written DTO interface in
`src/infrastructure/mappers/` that shadows a type already in
2. **DTO duplication.** A hand-written DTO interface in a feature's
`infrastructure/` that shadows a type already in
`services-api.d.ts` for the same resource — flag for consolidation.
3. **Field limit drift.** A `MaximumLength`/`.PrecisionScale(...)` on the
backend validator or EF column vs. a `maxLength`/`max()` in the
matching Zod schema (`agent-skills/agenza-frontend-feature`'s form
section) — these must match exactly (see docs/adr/0012's
matching Zod schema (see
`.agents/skills/agenza-frontend-feature/references/page-ui-conventions.md`)
— these must match exactly (see docs/adr/0012's
`Category.NameMaxLength`/`Service.NameMaxLength` alignment for the kind
of drift this catches). A limit encoded only in a comment, never a
type/schema/const, is itself a finding — flag it for a real check.
Expand All @@ -50,8 +51,8 @@ description: >
6. **Unhandled API error shape.** A backend error `code` introduced
(`Error.Conflict("Entity.SomeCode", ...)`) with no corresponding entry
in the matching frontend `codeFieldMap` (see
`agent-skills/agenza-frontend-feature`'s "Structured API errors"
section) — it will still work (falls back to a global message) but
`.agents/skills/agenza-frontend-feature/references/api-integration.md`) —
it will still work (falls back to a global message) but
loses field-level precision; flag it, don't treat it as broken.
7. **Structured vs. free-text errors.** Confirm a new validation failure
path returns through `Error.FieldErrors` (structured, docs/adr/0012),
Expand Down
28 changes: 14 additions & 14 deletions .agents/skills/agenza-architecture-review/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,38 +26,38 @@ Check, across whichever of these areas are in scope for the request:
shape followed? Frontend feature folders self-contained, no cross-feature
imports?
- **Multi-tenancy**: delegate the deep pass to
`agent-skills/agenza-tenant-isolation-review` rather than duplicating it
`.agents/skills/agenza-tenant-isolation-review` rather than duplicating it
here — this review only checks that tenant scoping is *present* where
expected, not the full mechanism.
- **Exceptions / Result pattern**: delegate the deep pass to
`agent-skills/agenza-exception-flow-audit`.
`.agents/skills/agenza-exception-flow-audit`.
- **Domain model**: anemic entities (public setters, no invariant
enforcement), missing `DomainResult` usage, entities bypassing
`BaseEntity`/`TenantOwnedEntity` without a documented reason.
- **Persistence**: query filters applied by hand instead of via
`ApplyAuditableConventions`, missing indexes for a new uniqueness rule,
a migration issue — delegate depth to
`agent-skills/agenza-migration-safety`.
- **Contracts**: delegate to `agent-skills/agenza-api-contract-review`.
`.agents/skills/agenza-migration-safety`.
- **Contracts**: delegate to `.agents/skills/agenza-api-contract-review`.
- **Frontend**: layering (see above), `any` usage, design-system drift
(raw palette classes instead of semantic tokens), reusable-component
discipline (`agent-skills/agenza-frontend-feature`).
discipline (`.agents/skills/agenza-frontend-feature`).
- **Accessibility**: keyboard operability, accessible names, contrast —
sample a few recently-changed pages rather than the whole app unless
asked for a full sweep.
- **Tests**: coverage gate status, mock-strategy-per-layer discipline
(frontend), no integration-test reintroduction without an ADR reverting
docs/adr/0015 (backend).
- **Migrations**: `agent-skills/agenza-migration-safety`.
- **Documentation**: `AGENTS.md`/`CLAUDE.md` files still accurate and in
sync (`scripts/check_agent_governance.py` covers the mechanical half of
(frontend), narrow persistence/runtime boundaries matching the current ADR
index instead of treating historical ADR 0015 as the final state.
- **Migrations**: `.agents/skills/agenza-migration-safety`.
- **Documentation**: `AGENTS.md`, import-only `CLAUDE.md`, and the Copilot
bridge still accurate and in sync (`scripts/check_agent_governance.py` covers the mechanical half of
this), STATUS.md rows matching what's actually built, ADRs referenced
by number actually existing.
- **CI**: workflows still matching the commands documented in
`docs/QUALITY.md`, coverage gates not silently loosened.
- **Dependencies**: any package pinned for a documented reason
(`docs/QUALITY.md`, `README.md`'s Versions table) that a routine bump
would silently violate.
- **Dependencies**: compare executable pins (`packageManager`, lockfiles,
`backend/global.json`, `backend/Directory.Packages.props`, `.python-version`,
CI actions) with `docs/adr/0032` before recommending a routine bump.

## Mode: review-only (default)

Expand All @@ -68,7 +68,7 @@ Produce a diagnosis, not a diff. For each finding:
- **Why it matters** (tie back to a rule in `AGENTS.md`, an ADR, or a
skill — don't invent a new rule mid-review; if there's genuinely no
existing rule this violates, that's a finding for
`agent-skills/agenza-rule-persistence` to formalize, not a silent
`.agents/skills/agenza-rule-persistence` to formalize, not a silent
judgment call)
- **Severity**: blocks tenant isolation / security > breaks a build gate
> architectural drift > style nit
Expand Down
81 changes: 81 additions & 0 deletions .agents/skills/agenza-backend-new-service/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
name: agenza-backend-new-service
description: >
Use when creating a brand-new .NET service under backend/services or when
deciding whether a capability needs its own service. Covers this repository's
context-aggregated service boundary, project layout, central package
management, tenant-safe persistence, authentication, Aspire wiring, tests,
and documentation. Do not copy an old service template without reading it.
---

# Backend new service

Create a service only for a genuinely new business context. If an existing
service owns the capability, use `agenza-backend-use-case` there instead. ADR
0001 records the context-aggregated service decision.

## Use live references

Inspect the current `services-service`, `identity-service`, AppHost, solution,
`backend/Directory.Packages.props`, and CI workflow before writing files. They
are the executable templates; this skill intentionally contains no copied
`Program.cs`, `.csproj`, or package-version blocks that can drift.

## Required shape

1. Create Domain, Application, Infrastructure, Api, and Tests projects and add
them to `backend/AdminBackend.slnx`.
2. Add a separate PersistenceTests project when the service owns tenant-scoped
EF entities/query filters or another persistence mechanism whose security
behavior cannot be proven by Domain/Application unit tests.
3. Preserve inward references: Domain has no project dependency; Application
references Domain and the framework-agnostic shared kernel; Infrastructure
implements Application ports; Api composes Application/Infrastructure and
may reference the ASP.NET Core shared package; Tests reference only the
layers their boundary needs.
4. Use central package management. Add a version once to
`backend/Directory.Packages.props`; project files contain versionless
`PackageReference` entries. Never run an unreviewed latest-version upgrade as
part of scaffolding.

## Application and domain

- Follow `agenza-backend-use-case` for the first vertical slice.
- Use rich entities with `DomainResult`, handlers returning `Result`, and
`PersistenceResult` at technical persistence boundaries. Expected business
outcomes do not throw.
- Define a service-local UnitOfWork shape that matches its real transaction
boundary; do not copy another service's interface blindly.
- Register handlers and validators through the service's assembly-scanning
application extension rather than one registration per slice.

## Tenant safety and persistence

- Resource services use `Admin.Identity.Client`, an authorization filter, and
`TenantHeaderFilter` by default. `[IgnoreTenant]` is only for a reviewed,
genuinely tenant-free action.
- Tenant-owned aggregates inherit the service-local `TenantOwnedEntity` shape.
The save interceptor assigns the current tenant; handlers do not set or accept
arbitrary tenant ids.
- Apply shared auditable/tenant conventions from `DbContext.OnModelCreating`.
Do not add hand-written query filters or capture a tenant constant during
model construction.
- Use one schema and migrations-history table owned by the service. Any schema
change also uses `agenza-migration-safety`.
- Add persistence tests proving automatic tenant assignment and cross-tenant
query isolation. Manual smoke testing complements these tests; it does not
replace them.

## API, runtime, and delivery

- Add API versioning to business routes; do not version fixed OIDC protocol
endpoints.
- Register the service's audience/scope in identity-service and exercise both
allowed and denied access where the runtime smoke boundary applies.
- Add the project and database/resource dependencies to
`backend/AppHost/AppHost.cs`. Aspire remains the only local orchestrator; do
not add Docker Compose or application Dockerfiles.
- Add the service to `docs/MONOREPO.md` and its context to `docs/VISION.md`.
- Run the backend, governance, and any affected API-contract gates before
completion.

Loading
Loading