feat: refresh shared skills catalog
This commit is contained in:
1 parent
98bb35e6fb
commit
418792d1ec
49 files changed
+2273
-2390
No files matched your search
+19
-97
@@ -1,104 +1,26 @@
|
||||
---
|
||||
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]
|
||||
Design or modify API routes, validated request/response schemas, error contracts, and API documentation within the existing project stack.
|
||||
scope: global
|
||||
---
|
||||
|
||||
# API Design & Membrane Architecture
|
||||
# API design
|
||||
|
||||
Governs API design and boundary membranes, ensuring typed validation, input clamping, predictable HTTP semantics, and consistent structured error contracts.
|
||||
1. Inspect the existing transport, schema library, auth, and error conventions.
|
||||
Keep domain logic independent of HTTP/framework request objects where practical.
|
||||
2. Define inputs, outputs, status codes, authorization, and meaningful payload limits.
|
||||
Use runtime validation at untrusted boundaries; TypeScript interfaces alone do
|
||||
not validate requests. Derive limits from product needs and resource budgets.
|
||||
3. Implement the route using existing services and data access patterns. Reuse
|
||||
existing dependency injection; do not introduce layers or repositories by default.
|
||||
4. Preserve HTTP semantics and the project's error shape. Use Problem Details
|
||||
when adopting that format; otherwise document the existing structured contract.
|
||||
Serialize timestamps consistently with explicit timezone information.
|
||||
5. Verify changed contracts and failure behavior under
|
||||
[shared verification](../../protocols/workflow.md#verification).
|
||||
|
||||
---
|
||||
|
||||
## 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.
|
||||
Read [security guidance](../app-security/SKILL.md) for affected untrusted boundaries,
|
||||
not as a mandatory second audit. Validation and authorization failures reject the
|
||||
request. A dependency fallback requires an explicit behavior contract; never infer
|
||||
"fail open" merely because an endpoint is internal.
|
||||
Reference in new issue
Block a user