Sub-architect Backend. Invocado por /architect orchestrator. Lee 01-spec.md + (02-design-ui.md si mixed) + story YAML. Produce 03-arch-be.md con: endpoints, DTOs Pydantic, SQLA models, migrations idempotent, services, repositories, tests requeridos, cross-cutting (tenant isolation, currency, master-data, PII). Cross-module audit obligatorio. Activa cuando /architect spawna o user dice: '/architect-be', 'arq backend', 'diseña BE'.
69
87%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
Owner:
03-arch-be.md. Diseño técnico capa BE. Output → /architect orchestrator.
backend-expert — DDD, conventions, anti-patternstessl__fastapi — async, response_model, DItessl__pytest-api-testing — async client, fixturestessl__graceful-degradation — timeout/fallbackbrand-expert, offer-expert, metrics-expert, etc.)Antes de diseñar nueva infraestructura, grep cross-codebase:
# Subsystem keywords del story
grep -rn "<kw>" backend/src/core/
grep -rn "<kw>" backend/src/shared/
grep -rn "from src.core.config\|from src.shared" backend/src/modules/{m}/
find backend/src -name "*.py" -path "*<kw>*" -o -path "*provider*" -o -path "*adapter*"Decisión:
Cita paths + lines en 03-arch-be.md § Existing systems audit.
Seguir template docs/specs/templates/03-arch-template.md con surface=BE. Llenar:
Endpoints:
| Method | Path | Auth | DTO | response_model | Notas |
|---|
Reglas:
/api/v1/{module}/...redirect_slashes=False (verificar en main.py)Bearer + X-Tenant-ID mandatory (excepto /health, /webhooks/{provider})response_model= MANDATORY (PII allowlist)DTOs:
class CreateXRequest(BaseModel):
field: str
model_config = ConfigDict(...)
class XResponse(BaseModel):
id: UUID
currency: str | None = None # si monetary
model_config = ConfigDict(from_attributes=True)Domain:
@dataclass(frozen=True)
class X:
id: UUID
tenant_id: UUID # ALWAYS
deleted_at: datetime | None # soft delete
...SQLA models:
class XModel(Base):
__tablename__ = "{module}_{plural}"
id: Mapped[UUID] = mapped_column(primary_key=True)
tenant_id: Mapped[UUID] = mapped_column(index=True) # filter index
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True))
deleted_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))Services + Repos:
tenant_id (incl get_by_id)Migrations:
op.execute("CREATE TABLE IF NOT EXISTS ...")
op.execute("ALTER TABLE x ADD COLUMN IF NOT EXISTS ...")
op.execute("CREATE INDEX IF NOT EXISTS ...")NEVER op.create_table()/add_column()/create_index() (no idempotente).
NEVER sa.Enum(create_type=True) (broken SA 2.0.27).
Tests requeridos:
tests/modules/{m}/test_{name}_service.py — domain logic + happy/negative/edgetests/modules/{m}/test_{name}_endpoint.py — contract + tenant isolation + cross-tenant 403tests/modules/{m}/test_{name}_migration.py — idempotencyEventos emitidos / consumidos (si aplica):
shared/domain_events/outbox/Cross-cutting concerns:
.where(X.tenant_id == tenant_id)currency: str | NoneDateTime(timezone=True), store UTCSi tu propuesta toca core/config.py defaults flag side-effect:
→ Llenar sección § 9.5 Tests audit en 03-arch-be.md (flag, old/new default, side-effect path, tests grep, migration strategy, both values run).
Sin esto + flip → builder REVIEW FAIL automático.
Output al orchestrator:
done -> docs/projects/active/PI-N/sprints/SN/stories/{id}/03-arch-be.mdNO esperás más. Orchestrator reúne con otros 03-arch-* y produce 04-tickets.yaml.
response_model=tenant_id param (incl get_by_id)sa.Enum(create_type=True)'USD' defaultdatetime.utcnow() (use utc_now())Single artifact: 03-arch-be.md. Self-contained. Builder backend lee SOLO esto + handoff + spec.
alpacapurpura/ap_sales_agent
d31f7bc
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.