AI-Assisted Development¶
Rules for using Claude, Copilot, and Cursor on this codebase. Non-negotiable — compliance and security requirements underpin all of them.
Core rule¶
Danger
Do not merge AI-generated code you cannot explain line by line.
If you can't explain it, re-prompt with more context, read the library docs, or raise it with the team. Merging code you don't understand is how silent security bugs get into a compliance-sensitive codebase.
When to use AI¶
Appropriate uses:
- CRUD endpoint boilerplate (router + schema + service)
- pytest test generation for existing functions
- Pydantic schema and SQLAlchemy model generation
- Alembic migration scripts
- Explaining unfamiliar errors
- Python ↔ TypeScript type translation
- PR review (paste diff, ask for issues)
Use with caution — review output closely:
- Database query construction (multi-tenancy bugs are silent)
- Performance-sensitive code
- File uploads or S3 interactions
- Complex business logic with edge cases
Do not use AI for:
- Authentication middleware
- Permission and authorisation logic
- Encryption or cryptographic operations
- Tenant context extraction
- Architectural decisions
Prompting¶
AI output quality is directly proportional to prompt quality. Always include:
- The relevant file(s) in full — not just the function
- The constraints — multi-tenant, schema-per-tenant PostgreSQL, FastAPI async
- The expected output format — three separate code blocks, or a single file, etc.
- The standards — type hints everywhere, no
Any, async for I/O
Example:
I'm adding `internal_reference` (optional string, max 100 chars) to the Project entity.
Here's the existing model: [paste file]
Here's the existing schema: [paste file]
Here's a migration example: [paste file]
We use schema-per-tenant PostgreSQL — migrations need the {tenant_schema} placeholder.
Generate: model update, schema update, migration, and test cases for tests/modules/test_projects.py.
Reviewing AI output¶
Before committing:
- Can you explain every line?
- Does it respect tenant boundaries?
- Are edge cases handled (null, empty string, large input)?
- Does it follow existing patterns in the codebase?
- Types correct — no
Any, no untypeddict? - Tests present?
- Error handling present?
- Did it hallucinate a function or import that doesn't exist? Run it to verify.
PR review prompt¶
Paste your diff to Claude before opening every PR:
Review this diff for the Construo platform:
1. Multi-tenancy bugs — missing tenant_schema, cross-tenant data access
2. Missing tests
3. Security issues — auth bypass, missing permission checks, SQL injection
4. Unhandled edge cases
5. Performance issues — N+1 queries, missing indexes, unbatched operations
6. Coding standards violations
7. Type safety — Any, missing hints, incorrect generics
[paste diff]
Fix every finding before requesting human review.
Prompt library¶
Save effective prompts to the shared Notion prompt library. Common ones:
| Task | Prompt location |
|---|---|
| Generate a new CRUD module | Notion → Prompt Library → Backend |
| Add a custom field type | Notion → Prompt Library → Backend |
| Write tests for a function | Notion → Prompt Library → Testing |
| Review a PR diff | Notion → Prompt Library → Review |
Tooling¶
| Tool | Purpose |
|---|---|
| Cursor | Primary IDE — inline autocomplete, multi-file context |
| Claude (web or in Cursor) | Larger tasks — drafting, debugging, PR review |
Pick one tool per session. Switching mid-task degrades output quality.