-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path.cursorrules
More file actions
91 lines (75 loc) · 4.27 KB
/
Copy path.cursorrules
File metadata and controls
91 lines (75 loc) · 4.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# SerpentStack — Cursor Rules
You are working on SerpentStack, a fullstack template: FastAPI + React + PostgreSQL + Terraform.
## Architecture
- **Backend**: FastAPI, Python 3.12+, async SQLAlchemy 2.0 (asyncpg), Alembic, pydantic-settings, structlog, SlowAPI, Sentry SDK, ARQ
- **Frontend**: React 18, Vite, TypeScript (strict), Tailwind CSS v4, React Router, React Query, shadcn/ui
- **Cache/Queue**: Redis 7 (rate limiting, background tasks)
- **Database**: PostgreSQL 16 (Docker locally, RDS in production)
- **Testing**: pytest + testcontainers (real Postgres), httpx AsyncClient, Vitest
- **Infrastructure**: Terraform, AWS (App Runner, ECR, RDS, S3)
## Key Conventions
### Python / Backend
- All route handlers and service methods MUST be `async def`
- Use `AsyncSession` from `sqlalchemy.ext.asyncio` — never sync Session
- Services return `None` or domain values — NEVER raise `HTTPException` in services
- Services flush() but do NOT commit() — routes own the transaction boundary
- Routes translate service results to HTTP responses (None → 404, etc.) and call `await db.commit()` after mutations
- New models MUST be imported in `backend/app/models/__init__.py` for Alembic to detect them
- Use `get_logger(__name__)` with structured event-style logging: `logger.info("event_name", key=value)`
- UUID primary keys on all models — never integer IDs
- Pydantic schemas in `schemas/` — never expose ORM models directly
- API routes prefixed with `/api/v1/`
- Protect routes with `Depends(get_current_user)` from `routes/auth.py` — returns `UserInfo`
- Database engine is lazily initialized (not at import time)
- Line length: 100 characters
- Formatter/linter: ruff
### TypeScript / Frontend
- Strict mode — no `any` without justifying comment
- Named exports for hooks and utilities (components may use default exports)
- Types auto-generated from OpenAPI spec via `make types` — prefer generated types over hand-written
- Use React Query for data fetching, React Router for routing
- Tailwind CSS v4 for styling
### Database
- Async driver: `postgresql+asyncpg://`
- All models inherit from `Base` in `app/models/base.py` (UUID pk, created_at, updated_at)
- Migrations via Alembic (async engine with `run_sync` bridge)
### Testing
- Backend tests use testcontainers with real PostgreSQL — Docker must be running
- `asyncio_mode = "auto"` is set — do NOT add `@pytest.mark.asyncio` to tests
- Use `AsyncClient` (httpx) for endpoint tests
- Frontend tests use Vitest
## File Structure
```
backend/app/routes/ — API route handlers (thin, delegate to services)
backend/app/services/ — Business logic (async, no HTTPException)
backend/app/schemas/ — Pydantic request/response models
backend/app/models/ — SQLAlchemy ORM models
backend/app/config.py — pydantic-settings configuration
backend/tests/ — pytest tests with testcontainers
frontend/src/ — React application
infra/ — Terraform modules (AWS)
.skills/ — IDE agent skills (Agent Skills standard)
.openclaw/ — Persistent agent workspace (OpenClaw)
```
## Agent Skills
This project includes project-specific Agent Skills in `.skills/`. Key skills:
- `scaffold` — full end-to-end resource generation following project conventions
- `auth` — UserInfo contract, get_current_user, provider swapping
- `test` — testcontainers, savepoint isolation, asyncio_mode = "auto"
- `generate-skills` — interviews developers to produce skills for any codebase
- `model-routing` — delegate code generation to on-device models (Ollama) for cost savings
Persistent agent configs live in `.openclaw/` (SOUL.md, HEARTBEAT.md, AGENTS.md).
## Common Commands
```bash
make dev # Start Postgres + Redis + backend + frontend
make verify # Lint + typecheck + test (backend & frontend) — run before pushing
make test # Run all tests (requires Docker)
make lint # ruff + ESLint
make types # Auto-generate frontend types from OpenAPI spec
make migrate # Run database migrations
make seed # Seed database with sample data
make worker # Start ARQ background task worker
make ui component=X # Add a shadcn/ui component
make persistent # Start OpenClaw background agent
```
**Always run `make verify` before pushing.** It runs the same checks as CI.