You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
🔨 Update mdc cursor rules and claude.md for backend services, apps, english comments and global environments, which would be applied automatically during the chat.
description: App layer (API) contract for FastAPI endpoints in backend/apps. Parse/validate input, call services, map domain errors to HTTP, return JSONResponse on success.
4
+
---
5
+
6
+
### Purpose and Scope
7
+
8
+
- The App layer is the HTTP boundary for the backend. It applies to files under `backend/apps/*.py`.
9
+
- Responsibilities:
10
+
- Parse and validate HTTP inputs.
11
+
- Call underlying services; do not implement core business logic here.
12
+
- Translate domain/service exceptions into `HTTPException` with proper status codes.
13
+
- Return `JSONResponse(status_code=HTTPStatus.OK, content=payload)` on success.
14
+
- Configuration: Do not access environment variables directly. Read configuration via `consts.const` or pass values through from the request to services.
- Use action-style paths only when necessary to match current patterns or when the operation is not naturally CRUD (e.g., `"/agent/run"`, `"/agent/stop/{conversation_id}"`).
25
+
- Path parameters must be singular, semantic nouns: `"/agents/{agent_id}"`, `"/memories/{memory_id}"`.
26
+
- Keep backwards compatibility: do not rename existing routes; new routes should follow these conventions.
27
+
28
+
### HTTP Methods
29
+
30
+
- GET: Read and list operations only. Maintain existing special cases where GET performs safe actions (e.g., `GET /agent/stop/{conversation_id}`), but do not introduce new side-effecting GETs.
31
+
- POST: Create resources, perform searches, or trigger actions with side effects (e.g., `POST /memory/add`, `POST /memory/search`, `POST /agent/run`).
- PUT/PATCH: Update resources. Prefer `PUT` for full updates and `PATCH` for partial updates. Preserve legacy `POST /update` endpoints for compatibility but favor PUT/PATCH for new code.
34
+
35
+
### Authorization and Identity
36
+
37
+
- Retrieve the bearer token via header injection: `authorization: Optional[str] = Header(None)`.
38
+
- Use utility helpers to parse identity (prefer functions in `utils.auth_utils`, such as `get_current_user_id` or `get_current_user_info`) and pass `user_id` and/or `tenant_id` down to services. The App layer should not implement token parsing logic itself.
39
+
40
+
### Request Validation
41
+
42
+
- Prefer Pydantic models in `consts.model` as request bodies for complex payloads (e.g., `AgentRequest`).
43
+
- For simple atomic fields, use `Body(..., embed=True)` to pin the JSON key name.
44
+
- Use `Query(...)` for filters and pagination, `Path(...)` for path parameters, and `Header(...)` for headers.
45
+
- Pagination recommendations for listing endpoints: `page: int = Query(1, ge=1)`, `page_size: int = Query(20, ge=1, le=100)`, plus optional `order_by`, `filters` as appropriate. Return pagination metadata (`items`, `total`) or match existing return shapes in the codebase.
46
+
47
+
### Responses
48
+
49
+
- On success, return `JSONResponse(status_code=HTTPStatus.OK, content=payload)`.
50
+
- If a standard response model exists in the project (e.g., conversation responses), continue to use it for consistency.
51
+
- For new endpoints, return a structured content dictionary with necessary fields (e.g., `{"data": ..., "message": "OK"}`) while staying consistent with existing patterns.
52
+
53
+
### Exception Mapping
54
+
55
+
- Catch domain/service exceptions from `backend/consts/exceptions.py` and map to `HTTPException` with appropriate status codes. Examples:
56
+
- `UnauthorizedError` → 401 UNAUTHORIZED
57
+
- `LimitExceededError` → 429 TOO_MANY_REQUESTS
58
+
- Parameter/validation errors (e.g., invalid enum, unknown config key) → 400 BAD_REQUEST or 406 NOT_ACCEPTABLE (follow existing precedent such as `set_single_config` using 406)
59
+
- Unexpected errors → 500 INTERNAL_SERVER_ERROR (log the error; do not leak internal details)
60
+
61
+
### Logging and Observability
62
+
63
+
- Use a module-level logger: `logger = logging.getLogger("<module_name>")`.
64
+
- Log key events and errors. For listing/search endpoints, optionally log query scope and timing while avoiding sensitive data.
65
+
66
+
### Async/Sync Conventions
67
+
68
+
- Match the existing style in each module. Keep `async def` where already used.
69
+
- When calling async services, prefer direct `await`. When calling sync services, invoke them directly without creating new event loops.
70
+
71
+
### Backward Compatibility
72
+
73
+
- Do not break existing routes, payload shapes, or response structures.
74
+
- New endpoints should follow these conventions strictly to converge the API style across modules.
description: Service layer implements core business logic orchestration; raise custom exceptions; no HTTP handling
4
+
---
5
+
6
+
### Service Layer Rules
7
+
8
+
- **Scope**: Applies to `backend/services/*.py`.
9
+
- **Goal**: Implement core business logic and orchestrate complex workflows. Coordinate repositories/SDKs. Keep HTTP concerns out of this layer.
10
+
- **Exceptions**: Raise domain/service exceptions declared in `backend/consts/exceptions.py`. If a new case is needed, add a new class there, then raise it here. Do not translate to HTTP here.
11
+
- **Environment variables**: Do not access `os.getenv()` directly. Read configuration from `consts.const` (see `environment_variable` rule) or accept parameters.
0 commit comments