feat(skills): import architecture and workflow skills
- Add api-design: REST membranes, contract-first schemas, and clamped validation - Add database-design: SQLite WAL mode, repository pattern, and keyset pagination - Add git-workflow: atomic staging, conventional commits, and non-destructive hygiene - Add emergency-procedures: safe circuit breakers, backup snapshotting, and recovery - Standardize all skills to 5-phase Skill Architect protocol - Synchronize symlinks across OpenCode, Codex, and Claude Code
This commit is contained in:
1 parent
5a19e1cd9d
commit
3fe0d13dd6
4 files changed
+355
No files matched your search
@@ -0,0 +1,104 @@
|
||||
---
|
||||
name: api-design
|
||||
description: >
|
||||
Designs RESTful APIs, typed schema membranes, request/response validation contracts, and API documentation.
|
||||
Use when creating or modifying API routes, defining request/response schemas, designing error responses,
|
||||
or standardizing API contracts.
|
||||
concerns: [security, system-one-balance]
|
||||
---
|
||||
|
||||
# API Design & Membrane Architecture
|
||||
|
||||
Governs API design and boundary membranes, ensuring typed validation, input clamping, predictable HTTP semantics, and consistent structured error contracts.
|
||||
|
||||
---
|
||||
|
||||
## Phase 0: Setup and Protocols
|
||||
|
||||
1. **Membrane Principles**:
|
||||
- **Boundary Isolation**: Route handlers serve as the transport membrane. Core business services and data access layers remain transport-agnostic (never import web framework request objects or HTTP status codes into domain logic).
|
||||
- **Contract-First Validation**: Define typed schemas (e.g. Pydantic, Zod, TypeScript interfaces) before implementing endpoint logic.
|
||||
- **Dependency Injection**: Inject database sessions, repositories, and authentication state into route handlers; avoid importing global singletons directly.
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Ingest and Check
|
||||
|
||||
1. **Identify Endpoint Requirements**:
|
||||
- Resource name, target path, HTTP method (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`).
|
||||
- Expected input payload, query parameters, route path variables, and headers.
|
||||
- Response model, status codes (200, 201, 204), and error failure modes.
|
||||
2. **Input Boundary Clamping**:
|
||||
- Enforce explicit upper bounds on all strings (e.g. `min_length=1`, `max_length=200` for names; `max_length=50000` for content).
|
||||
- Enforce pagination limits: `1 <= limit <= 50` (or `100` max).
|
||||
- Constrain array inputs: clamp batch endpoints to maximum batch sizes.
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Processing (Core Logic)
|
||||
|
||||
### Step 1: Define Typed Contracts
|
||||
```python
|
||||
# 1. Request & Response Schemas
|
||||
class ResourceCreateRequest(BaseModel):
|
||||
name: str = Field(..., min_length=1, max_length=200)
|
||||
description: str | None = Field(None, max_length=2000)
|
||||
|
||||
class ResourceResponse(BaseModel):
|
||||
id: str
|
||||
name: str
|
||||
description: str | None = None
|
||||
created_at: datetime
|
||||
```
|
||||
|
||||
### Step 2: Implement Route Handler
|
||||
```python
|
||||
# 2. Endpoint Implementation
|
||||
@router.post("/resources", response_model=ResourceResponse, status_code=201)
|
||||
async def create_resource(
|
||||
payload: ResourceCreateRequest,
|
||||
repo: ResourceRepository = Depends(get_resource_repo),
|
||||
):
|
||||
entity = await repo.create(payload.model_dump())
|
||||
return ResourceResponse.model_validate(entity)
|
||||
```
|
||||
|
||||
### Step 3: Enforce HTTP & Error Semantics
|
||||
- **HTTP Methods**:
|
||||
- `POST`: Resource creation / command execution (201 Created or 200 OK).
|
||||
- `GET`: Idempotent retrieval (200 OK).
|
||||
- `PUT`: Full resource replacement (200 OK).
|
||||
- `PATCH`: Partial state update (200 OK).
|
||||
- `DELETE`: Resource removal (204 No Content).
|
||||
- **Structured Error Responses**:
|
||||
- Return standardized error objects (e.g. RFC 7807 problem details or structured error payloads):
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "RESOURCE_NOT_FOUND",
|
||||
"message": "Resource with id 'xyz' was not found",
|
||||
"details": {}
|
||||
}
|
||||
}
|
||||
```
|
||||
- Standard status codes: 400 (Validation), 401 (Unauthenticated), 403 (Unauthorized), 404 (Not Found), 409 (Conflict).
|
||||
- **Timezone Invariant**: Always serialize timestamps in UTC using ISO-8601 (`YYYY-MM-DDTHH:MM:SSZ`).
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: The System One Balance Pass
|
||||
|
||||
- **Augment, Don't Handcuff**:
|
||||
- Do NOT over-complicate simple internal endpoints with bloated enterprise middleware.
|
||||
- Keep route handlers thin: route logic should unpack requests, call services/repos, and map to response models.
|
||||
- Fail open on safe internal queries; enforce rigorous clamping at external boundary layers.
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Output Execution & Verification
|
||||
|
||||
1. Verify:
|
||||
- Route docstrings populate OpenAPI / Swagger schemas accurately.
|
||||
- All response models are strongly typed without bare `dict` or `Any` escapes.
|
||||
- Input clamping fields prevent memory exhaustion and DoS.
|
||||
2. Deliver the schema definition, route implementation, and corresponding test case.
|
||||
Reference in new issue
Block a user