Ctrl K
ComunidadGuías…

AGENTS/Architecture.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Architecture Guidance

This file captures the current runtime architecture so agents can orient quickly before making design or implementation changes.

## Solution Layers

- `BoardOil.Api`
  - HTTP transport, endpoint wiring, auth policies, runtime hosting, MCP transport wiring.
  - Endpoints stay thin and delegate behaviour to services.
- `BoardOil.Contracts`
  - API contracts (`*Request`, `*Dto`, `ApiResult`, `ValidationError`) shared across API/services/tests.
- `BoardOil.Abstractions`
  - Cross-cutting service and infrastructure abstractions (service interfaces, db scope abstractions, auth abstractions).
- `BoardOil.Data.Abstractions`
  - Persistence-facing contracts and EF entity types (`Entity*`) plus repository interfaces.
- `BoardOil.Ef`
  - EF Core implementation (`BoardOilDbContext`), repository implementations, ambient db scope implementation, migrations.
  - Infrastructure composition and startup initialisation extensions for EF wiring/migrations/bootstrap.
- `BoardOil.Services`
  - Business workflows, invariants, validation orchestration, persistence coordination, mapping to contracts, realtime event publishing.
  - Service-layer DI registrations only; no EF registration or migration/bootstrap startup ownership.
- `BoardOil.Web`
  - Vue 3 + Pinia frontend, typed API client, route guards, realtime board updates.

## Request and Write Flow

1. Endpoint/controller-equivalent in `BoardOil.Api` invokes a service (`I*Service`).
2. Service opens a db scope (`Create()` for write, `CreateReadOnly()` for read).
3. Service performs validation + repository operations.
4. Service commits with `scope.SaveChangesAsync()`.
5. Service returns `ApiResult`/`ApiResult<T>` and API layer serialises that contract.

Default: one save per service operation unless a specific transactional reason requires otherwise.

## Endpoint Verb Preference

- For update endpoints, generally prefer `PUT` over `PATCH`.
- Use `PATCH` only when the endpoint is intentionally a partial-update contract.

## Contract Design Guidance

- Prefer endpoint-specific DTOs when read and write concerns diverge; do not force one contract shape to serve both equally if that makes either side awkward.
- Do not create multiple DTOs or record types for the same area unless there is a genuine difference to justify them. A naming distinction on its own is not enough; there should be a concrete difference in fields, behaviour, lifecycle, audience, or contract semantics.
- If two DTOs have the same shape and are used the same way, prefer a single contract until a real divergence appears. Avoid speculative semantic types that add naming without adding clarity.
- Full-update (`PUT`) contracts should remain cheap for clients to round-trip. If a client edits one field and keeps the rest unchanged, it should not need complex shape conversion just to resend the untouched fields.
- Denormalised read models are acceptable when they materially improve consumer ergonomics (for example richer one-hit payloads for integrations), but treat that as a convenience projection rather than proof that the denormalised payload is the only source of truth.
- When a read model duplicates data from a catalogue or parent entity, explicitly document the intended authority model:
  - which payload/store is authoritative for live updates and mutations
  - which payload is convenience/snapshot data for easier reads
- Do not introduce partial-update contracts just to paper over awkward DTO design. Prefer improving the contract shape first; adopt `PATCH` only when partial semantics are genuinely required.
- Periodically remove dead or orphaned contract types when the intended abstraction never materialised. Unused DTO/record layers create noise and make the real architecture harder to read.

## Boundaries

- Repositories:
  - Entity-level data access only.
  - No orchestration/policy decisions.
  - No commit ownership.
- Services:
  - Own orchestration, policy, validation coordination, and cross-repository workflows.

## Realtime and Auth Notes

- Realtime notifications are emitted from services through `IBoardEvents`.
- Clients should treat realtime as incremental and resync-safe after reconnects.
- API auth uses JWT/cookies for user sessions.
- MCP-specific auth policy and bearer challenge behavior are composed through `BoardOil.Api/Mcp/McpAuthExtensions.cs`.
- `Program.cs` should remain orchestration-focused; MCP transport/auth wiring should live in `BoardOil.Api/Mcp/*` extension modules.