aayushus-skills 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +31 -0
- package/Solo Developer AI SOP.md +268 -0
- package/agent-config/CLAUDE.md +68 -0
- package/agent-config/README.md +89 -0
- package/agent-config/copilot-instructions.md +51 -0
- package/agent-config/howto.md +194 -0
- package/agent-config/project-templates/windsurfrules-blank +50 -0
- package/agent-config/project-templates/windsurfrules-node-prisma +73 -0
- package/agent-config/windsurfrules-global.md +128 -0
- package/agent-config/windsurfrules.md +155 -0
- package/cli.js +214 -0
- package/design/Icons.tsx +188 -0
- package/design/PRISM_MANIFESTO.md +131 -0
- package/design/README.md +55 -0
- package/design/SKILL.md +44 -0
- package/design/ai-surfaces.md +364 -0
- package/design/checklist.md +151 -0
- package/design/components.css +3163 -0
- package/design/components.tsx +2487 -0
- package/design/implementation-guide.md +181 -0
- package/design/mobile.css +550 -0
- package/design/package.json +28 -0
- package/design/patterns-desktop.md +752 -0
- package/design/patterns-mobile.md +480 -0
- package/design/tokens.css +225 -0
- package/design/tokens.md +515 -0
- package/guidelines/API-Design.md +95 -0
- package/guidelines/Architecture.md +1536 -0
- package/guidelines/Code-Quality.md +1776 -0
- package/guidelines/Container-Guidelines.md +72 -0
- package/guidelines/DECISION-Modular-Monolith.md +26 -0
- package/guidelines/Documentation.md +1330 -0
- package/guidelines/Engineering-Workflow.md +92 -0
- package/guidelines/Incident-Response.md +121 -0
- package/guidelines/Performance.md +1801 -0
- package/guidelines/Product-Management.md +88 -0
- package/guidelines/Security.md +1570 -0
- package/guidelines/TEMPLATE-Decision.md +20 -0
- package/guidelines/Testing.md +72 -0
- package/package.json +35 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
---
|
|
2
|
+
tags: [howto, ai-tools, windsurf, vscode, claude-code, setup]
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# How to wire AI coding agents to follow project guidelines
|
|
6
|
+
|
|
7
|
+
This vault contains two sets of rules that all AI coding agents should follow:
|
|
8
|
+
- **Design system** — `design/SKILL.md` + supporting files (Prism)
|
|
9
|
+
- **Engineering guidelines** — `guidelines/` (architecture, security, performance, code quality, documentation)
|
|
10
|
+
|
|
11
|
+
This guide explains how to load them into Windsurf, VS Code Copilot, and Claude Code so agents follow them automatically — without you having to paste context into every conversation.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Two-layer model
|
|
16
|
+
|
|
17
|
+
Rules split into two layers so they work across multiple projects (Anti Gravity, new projects, etc.) without rewriting anything:
|
|
18
|
+
|
|
19
|
+
**Layer 1 — Universal (global, set once)**
|
|
20
|
+
Stack-agnostic hard rules: security principles, code quality, performance budgets, Prism design system, observability. These never change between projects.
|
|
21
|
+
|
|
22
|
+
**Layer 2 — Project-specific (per repo)**
|
|
23
|
+
Stack decisions, architectural choices, module structure. Different for every project.
|
|
24
|
+
|
|
25
|
+
| File | Layer | For | Contains |
|
|
26
|
+
|---|---|---|---|
|
|
27
|
+
| `windsurfrules-global` | Universal | Windsurf global settings | Security, code quality, performance, design system — all projects |
|
|
28
|
+
| `project-templates/windsurfrules-node-prisma` | Project | `.windsurfrules` in Node/Prisma repos | Stack-specific rules for this project |
|
|
29
|
+
| `project-templates/windsurfrules-blank` | Project | `.windsurfrules` in any new repo | Template to fill in for a new project |
|
|
30
|
+
| `copilot-instructions.md` | Both | VS Code Copilot | Critical universal rules, compact |
|
|
31
|
+
| `CLAUDE.md` | Both | Claude Code | Rules + skill loading instructions |
|
|
32
|
+
|
|
33
|
+
The full guidelines are always the source of truth.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Windsurf
|
|
38
|
+
|
|
39
|
+
### Step 1 — Global rules (one-time setup, applies to every project)
|
|
40
|
+
|
|
41
|
+
1. Open Windsurf
|
|
42
|
+
2. `Cmd+,` → search **"Rules"** → click **Edit Global Rules**
|
|
43
|
+
3. Paste the full contents of `windsurfrules-global`
|
|
44
|
+
4. Save
|
|
45
|
+
|
|
46
|
+
Every Cascade conversation in every workspace now follows the universal rules automatically.
|
|
47
|
+
|
|
48
|
+
### Step 2 — Per-project rules (stack + architecture decisions)
|
|
49
|
+
|
|
50
|
+
For an existing Node.js + Prisma project:
|
|
51
|
+
```bash
|
|
52
|
+
cp /path/to/obsidian/04_Resources/Skills/agent-config/project-templates/windsurfrules-node-prisma \
|
|
53
|
+
/your-project/.windsurfrules
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
For a new project (Anti Gravity, etc.):
|
|
57
|
+
```bash
|
|
58
|
+
cp /path/to/obsidian/04_Resources/Skills/agent-config/project-templates/windsurfrules-blank \
|
|
59
|
+
/your-project/.windsurfrules
|
|
60
|
+
# Then fill in the stack, decisions, and repo structure sections
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Windsurf reads `.windsurfrules` from the project root automatically — no further configuration needed.
|
|
64
|
+
|
|
65
|
+
**The two layers stack**: global rules apply everywhere, `.windsurfrules` adds project context on top. An agent in Anti Gravity gets the universal security/quality/design rules plus Anti Gravity's specific stack decisions.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## VS Code — GitHub Copilot
|
|
70
|
+
|
|
71
|
+
### Per-project (workspace instructions)
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
mkdir -p /your-project/.github
|
|
75
|
+
cp /path/to/obsidian/04_Resources/Skills/agent-config/copilot-instructions.md \
|
|
76
|
+
/your-project/.github/copilot-instructions.md
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
VS Code reads `.github/copilot-instructions.md` automatically in Copilot Chat and inline suggestions. Requires VS Code ≥ 1.90. No setting needed — just commit the file.
|
|
80
|
+
|
|
81
|
+
### User-level (applies to all projects)
|
|
82
|
+
|
|
83
|
+
1. `Cmd+,` → search **"Copilot Instructions"**
|
|
84
|
+
2. Click **Edit in settings.json**
|
|
85
|
+
3. Add:
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
"github.copilot.chat.codeGeneration.instructions": [
|
|
89
|
+
{
|
|
90
|
+
"text": "PASTE CONTENTS OF copilot-instructions.md HERE"
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Claude Code
|
|
98
|
+
|
|
99
|
+
### Per-project
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
cp /path/to/obsidian/04_Resources/Skills/agent-config/CLAUDE.md /your-project/CLAUDE.md
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Claude Code reads `CLAUDE.md` from the project root automatically at the start of every session.
|
|
106
|
+
|
|
107
|
+
### Global (applies to all projects)
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
cp /path/to/obsidian/04_Resources/Skills/agent-config/CLAUDE.md ~/.claude/CLAUDE.md
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Project-level and global `CLAUDE.md` are merged — use global for universal rules, project-level for repo-specific context.
|
|
114
|
+
|
|
115
|
+
### Design system skill (Claude Code only)
|
|
116
|
+
|
|
117
|
+
The Prism design system is already set up as a Claude Code skill in this vault. When working on UI, tell Claude:
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
use the prism-design skill
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Claude will load `design/SKILL.md` and the relevant pattern files automatically. No extra setup needed.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## What each tool sees
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
Windsurf global settings (windsurfrules-global)
|
|
131
|
+
└─ Universal rules: security, code quality, performance budgets, Prism design
|
|
132
|
+
└─ Active on every conversation, every project — Anti Gravity, new projects, all of them
|
|
133
|
+
|
|
134
|
+
.windsurfrules (project root — different per project)
|
|
135
|
+
└─ Stack decisions: "this project uses Supabase not Prisma"
|
|
136
|
+
└─ Architecture choices: "cursor pagination, ULIDs, REST not GraphQL"
|
|
137
|
+
└─ Current context: "billing module, don't touch auth branch"
|
|
138
|
+
|
|
139
|
+
.github/copilot-instructions.md (project root)
|
|
140
|
+
└─ Compact version of universal rules for Copilot's shorter context window
|
|
141
|
+
└─ Committed to repo — teammates get it automatically
|
|
142
|
+
|
|
143
|
+
CLAUDE.md (project root or ~/.claude/)
|
|
144
|
+
└─ Universal rules + instructions to load Prism skill for UI work
|
|
145
|
+
└─ Points to full guidelines for deep dives
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Result for any project
|
|
149
|
+
|
|
150
|
+
An agent in **any** project gets:
|
|
151
|
+
1. Universal hard rules (from global settings) — automatically
|
|
152
|
+
2. That project's stack and architecture decisions (from `.windsurfrules`) — from the repo
|
|
153
|
+
3. Design system (from Prism skill or CLAUDE.md reference) — on demand
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Keeping rules in sync
|
|
158
|
+
|
|
159
|
+
When guidelines change (new architectural decision, updated security rule, etc.):
|
|
160
|
+
|
|
161
|
+
1. Update the source file in `guidelines/` or `design/`
|
|
162
|
+
2. Update the relevant section in `windsurfrules`, `copilot-instructions.md`, and `CLAUDE.md`
|
|
163
|
+
3. If you used Windsurf global rules, re-paste the updated content into settings
|
|
164
|
+
|
|
165
|
+
The distillation files should always reflect the most critical rules from the full guidelines. If a rule is important enough to be in the guidelines, it's important enough to be in the distillation.
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## New project checklist
|
|
170
|
+
|
|
171
|
+
When starting a new project (Anti Gravity, anything else):
|
|
172
|
+
|
|
173
|
+
- [ ] Windsurf global rules already set — nothing to do
|
|
174
|
+
- [ ] Copy `project-templates/windsurfrules-blank` → `.windsurfrules` in project root
|
|
175
|
+
- [ ] Fill in: stack, architecture decisions, repo structure, current focus
|
|
176
|
+
- [ ] Copy `copilot-instructions.md` → `.github/copilot-instructions.md`
|
|
177
|
+
- [ ] Copy `CLAUDE.md` → project root `CLAUDE.md`
|
|
178
|
+
- [ ] Commit all three so teammates get them automatically
|
|
179
|
+
|
|
180
|
+
## Adding a new IDE or coding LLM
|
|
181
|
+
|
|
182
|
+
The universal rules (security, quality, performance, design system) are written in plain markdown — they work in any tool that accepts a system prompt or rules file:
|
|
183
|
+
|
|
184
|
+
| Tool | Where to paste `windsurfrules-global` |
|
|
185
|
+
|---|---|
|
|
186
|
+
| Windsurf | Settings → Edit Global Rules |
|
|
187
|
+
| Cursor | Settings → Rules for AI (global) or `.cursorrules` in project root |
|
|
188
|
+
| Cline (VS Code) | Extension settings → System Prompt |
|
|
189
|
+
| Aider | `--system-prompt` flag or `.aider.conf.yml` |
|
|
190
|
+
| GitHub Copilot | `.github/copilot-instructions.md` or user settings.json |
|
|
191
|
+
| Claude Code | `~/.claude/CLAUDE.md` (global) or `CLAUDE.md` (project) |
|
|
192
|
+
| Any chat-based LLM | Paste as the first message or system prompt |
|
|
193
|
+
|
|
194
|
+
For any new tool: paste `windsurfrules-global` as the system/global rules, then add project context from the relevant `.windsurfrules` template.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Project-specific rules — [PROJECT NAME]
|
|
2
|
+
# Copy to .windsurfrules in the project root
|
|
3
|
+
# Global rules apply on top of these via Windsurf settings
|
|
4
|
+
|
|
5
|
+
## Stack
|
|
6
|
+
[e.g. TypeScript + Next.js + Supabase + Vercel]
|
|
7
|
+
[e.g. Python + FastAPI + SQLAlchemy + PostgreSQL]
|
|
8
|
+
[e.g. Go + Gin + GORM + MySQL]
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Architecture decisions made for this project
|
|
13
|
+
|
|
14
|
+
| Decision | Choice | Reason |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| Database | | |
|
|
17
|
+
| Auth | | |
|
|
18
|
+
| Queue / async | | |
|
|
19
|
+
| Primary keys | | |
|
|
20
|
+
| API style | | |
|
|
21
|
+
| Deployment | | |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Project-specific hard rules
|
|
26
|
+
|
|
27
|
+
[Add rules specific to this codebase here — things that differ from the global defaults]
|
|
28
|
+
[e.g. "This project uses Supabase RLS instead of app-level tenancy filtering"]
|
|
29
|
+
[e.g. "All API routes are in /app/api/ — never in /pages/api/"]
|
|
30
|
+
[e.g. "Use server actions for mutations, not API routes"]
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Current focus / context
|
|
35
|
+
|
|
36
|
+
[Optional: add sprint/task context here to help the agent stay relevant]
|
|
37
|
+
[e.g. "Currently building the billing module — Stripe webhooks + subscription state machine"]
|
|
38
|
+
[e.g. "Do not touch the auth module — it's being refactored in a separate branch"]
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Repo structure
|
|
43
|
+
|
|
44
|
+
[Brief map of the repo so the agent doesn't guess]
|
|
45
|
+
[e.g.]
|
|
46
|
+
[src/]
|
|
47
|
+
[ app/ — Next.js App Router pages]
|
|
48
|
+
[ components/ — Shared React components (use Prism design system)]
|
|
49
|
+
[ lib/ — Server-side utilities, DB client, auth helpers]
|
|
50
|
+
[ types/ — Shared TypeScript types]
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Project-specific rules — Node.js + Prisma + PostgreSQL + BullMQ
|
|
2
|
+
# Copy to .windsurfrules in the project root
|
|
3
|
+
# Global rules (windsurfrules-global) apply on top of these via Windsurf settings
|
|
4
|
+
|
|
5
|
+
## Stack
|
|
6
|
+
TypeScript strict + Node.js + Express + Prisma + PostgreSQL + Redis + BullMQ.
|
|
7
|
+
AI service: Python 3.12 + FastAPI (separate process, separate failure domain).
|
|
8
|
+
Frontend: Next.js + React + Prism design system.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Multi-tenancy (existential — never bypass)
|
|
13
|
+
- Every Prisma query on tenant-scoped data MUST filter by `tenantId` — enforced by middleware, but always include explicitly
|
|
14
|
+
- `tenantId` comes from the authenticated session — never from URL params or request body
|
|
15
|
+
- Shared database, shared schema, `tenantId` column — not schema-per-tenant
|
|
16
|
+
- Soft deletes only — `deletedAt` timestamp, never hard DELETE on tenant data
|
|
17
|
+
- No `ON DELETE CASCADE` on tenant-scoped tables
|
|
18
|
+
- Unauthorized reads return 404 not 403 — prevents existence leak
|
|
19
|
+
|
|
20
|
+
## IDs & pagination
|
|
21
|
+
- ULIDs for all primary keys — not auto-increment integers, not UUIDs
|
|
22
|
+
- Cursor-based pagination only — never offset/limit on large tables
|
|
23
|
+
- Max page size 100 items, default 25
|
|
24
|
+
|
|
25
|
+
## Database
|
|
26
|
+
- All DB access via Prisma — no raw SQL except `$queryRaw` with tagged templates (requires ticket)
|
|
27
|
+
- Migrations: expand/contract pattern — additive first, destructive deferred to a later deploy
|
|
28
|
+
- Run `CONCURRENTLY` for index creation on large tables
|
|
29
|
+
- No N+1 — use Prisma `include/select`, never query inside a loop
|
|
30
|
+
- Slow query threshold: 50ms dev, 500ms prod
|
|
31
|
+
|
|
32
|
+
## Queuing
|
|
33
|
+
- All async work via BullMQ on Redis — not Kafka, SQS, RabbitMQ
|
|
34
|
+
- Outbox pattern: write event to DB first, worker picks it up — never `queue.add()` directly from HTTP handler
|
|
35
|
+
- Job defaults: 5 retries, exponential backoff (2s base), idempotent
|
|
36
|
+
- Circuit breaker: open after 5 failures in 10s, stay open 30s
|
|
37
|
+
|
|
38
|
+
## Auth
|
|
39
|
+
- Argon2id for passwords: `time=3, memory=64MB, parallelism=4`
|
|
40
|
+
- Argon2id for API keys — hashed before storage, shown once only
|
|
41
|
+
- Opaque 256-bit session tokens in Redis — NOT JWTs for user sessions
|
|
42
|
+
- MFA required for `owner` and `admin` roles (TOTP, RFC 6238)
|
|
43
|
+
- Rate limits: 100 req/60s per user (default), 5/60s for login + password-reset
|
|
44
|
+
|
|
45
|
+
## API design
|
|
46
|
+
- REST + JSON — no GraphQL
|
|
47
|
+
- URL versioning: `/api/v1/`, `/api/v2/`
|
|
48
|
+
- Standard error envelope: `{ code, message, correlationId, details }`
|
|
49
|
+
- Every endpoint: timeout, rate limit, Zod input validation
|
|
50
|
+
|
|
51
|
+
## Config
|
|
52
|
+
- One place reads `process.env`: `shared/config.ts` with Zod schema
|
|
53
|
+
- All secrets in Doppler — never `.env` files committed, never in code
|
|
54
|
+
|
|
55
|
+
## Timeouts
|
|
56
|
+
- Internal HTTP calls: 10s
|
|
57
|
+
- Fast external APIs: 5s
|
|
58
|
+
- Slow external APIs: 30s
|
|
59
|
+
- AI calls (async only): 60s
|
|
60
|
+
- Prisma queries: 15s
|
|
61
|
+
|
|
62
|
+
## Decisions already made — don't reopen
|
|
63
|
+
| Decision | Choice |
|
|
64
|
+
|---|---|
|
|
65
|
+
| DB access | Prisma only |
|
|
66
|
+
| Queue | BullMQ on Redis |
|
|
67
|
+
| Sessions | Opaque tokens in Redis (not JWTs) |
|
|
68
|
+
| Primary keys | ULIDs |
|
|
69
|
+
| Search | PostgreSQL FTS (Typesense at 100k+ users) |
|
|
70
|
+
| API style | REST + JSON |
|
|
71
|
+
| Passwords | Argon2id |
|
|
72
|
+
| Deployment | Fly Machines → ECS → K8s (only with SRE) |
|
|
73
|
+
| Tenancy | Shared DB, shared schema, tenantId column |
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Universal coding rules — applies to all projects
|
|
2
|
+
|
|
3
|
+
These rules are tool-agnostic, stack-agnostic hard constraints.
|
|
4
|
+
Project-specific stack decisions live in .windsurfrules at the project root.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## SECURITY — never negotiate these
|
|
9
|
+
|
|
10
|
+
- Validate every input at every system boundary — HTTP, queue, file upload, CLI args
|
|
11
|
+
- All strings have a max length — no unbounded input
|
|
12
|
+
- Passwords: Argon2id only — never bcrypt, MD5, SHA-1, or SHA-256 for passwords
|
|
13
|
+
- Secrets in a secrets manager (Doppler, AWS Secrets Manager, Vault) — never in code, env files, or logs
|
|
14
|
+
- One place reads environment variables — a config module with schema validation
|
|
15
|
+
- Never reveal whether a user/email/resource exists to an unauthenticated caller
|
|
16
|
+
- Unauthorised reads return 404, not 403 — prevents existence leak
|
|
17
|
+
- Never log secrets, tokens, PII, or raw passwords — redact at the transport layer
|
|
18
|
+
- Session tokens rotate on: login, logout, privilege change
|
|
19
|
+
- File uploads: validate by magic number (not extension), scan for malware, strip metadata
|
|
20
|
+
- SSRF: DNS-resolve before fetching, reject private/loopback IPs
|
|
21
|
+
- Every outbound network call has a hard timeout
|
|
22
|
+
- Retries only on 5xx and network errors — never on 4xx
|
|
23
|
+
- Rate-limit authentication endpoints (login, password reset, MFA)
|
|
24
|
+
- CORS: explicit allowlist — never wildcard `*` in production
|
|
25
|
+
- Security headers on every response: HSTS, X-Frame-Options, CSP
|
|
26
|
+
- TLS 1.2+ everywhere
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## CODE QUALITY — language-agnostic rules
|
|
31
|
+
|
|
32
|
+
- Use the strictest type-checking mode available for your language
|
|
33
|
+
- Never use the "any" escape hatch (TypeScript `any`, Python `Any` without bounds, Go `interface{}` without assertion)
|
|
34
|
+
- Functions ≤ 80 lines (aim ≤ 30); files ≤ 500 lines (aim ≤ 300)
|
|
35
|
+
- No `console.log` / `print` in committed code — use a structured logger
|
|
36
|
+
- No commented-out code — delete it; use git history
|
|
37
|
+
- No TODO without author and date; CI should fail if TODOs accumulate
|
|
38
|
+
- Boolean variables use `is/has/can/should` prefix
|
|
39
|
+
- Error handling: throw/panic for programming errors (bugs); return typed errors/Result for expected failures (validation, not-found, rate-limit)
|
|
40
|
+
- Async/await always — never raw promise chains or callbacks
|
|
41
|
+
- Parallelise independent async work — don't await sequentially when parallel is safe
|
|
42
|
+
- No N+1 queries — use eager loading, joins, or batching
|
|
43
|
+
- No circular imports — signals wrong module boundaries
|
|
44
|
+
- PR size ≤ 400 lines unless generated — split larger changes
|
|
45
|
+
- Refactoring and feature work never in the same PR
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## PERFORMANCE — hard budgets
|
|
50
|
+
|
|
51
|
+
| Interaction | Budget |
|
|
52
|
+
|---|---|
|
|
53
|
+
| UI response (click, hover, keypress) | ≤ 100ms |
|
|
54
|
+
| Page / view transition | ≤ 200ms |
|
|
55
|
+
| API read (cached) p95 | < 200ms |
|
|
56
|
+
| API read (list) p95 | < 300ms |
|
|
57
|
+
| API write p95 | < 300ms |
|
|
58
|
+
| Anything > 1s | Show progress indicator; consider async |
|
|
59
|
+
| Anything > 10s | Must be async with completion notification |
|
|
60
|
+
| LCP | ≤ 2.5s (p75) |
|
|
61
|
+
| INP | ≤ 200ms (p75) |
|
|
62
|
+
| CLS | ≤ 0.1 (p75) |
|
|
63
|
+
| JS bundle gzipped | ≤ 170KB |
|
|
64
|
+
| CSS bundle gzipped | ≤ 30KB |
|
|
65
|
+
| DB indexed point lookup | ≤ 10ms |
|
|
66
|
+
| DB list query | ≤ 200ms |
|
|
67
|
+
|
|
68
|
+
- Profile before optimising — never optimise by intuition
|
|
69
|
+
- Every query must hit an index — no sequential scans on large tables
|
|
70
|
+
- Cache keys must include tenant/user scope — never serve one user's cached data to another
|
|
71
|
+
- TTL on every cache entry — no infinite caches
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## OBSERVABILITY — always
|
|
76
|
+
|
|
77
|
+
- Structured JSON logs — required fields: `timestamp`, `level`, `service`, `correlationId`, `message`
|
|
78
|
+
- Correlation ID on every log line, every async job, every cross-service call
|
|
79
|
+
- Every HTTP route emits request count + duration metrics
|
|
80
|
+
- Slow queries logged automatically — threshold: 50ms dev, 200ms staging, 500ms prod
|
|
81
|
+
- Audit logs for any action that changes permissions, deletes data, or touches billing — append-only, never editable
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## PRISM DESIGN SYSTEM — applies to all UI work
|
|
86
|
+
|
|
87
|
+
- Never hardcode colours, radii, or font names — use CSS tokens (`var(--token-name)`)
|
|
88
|
+
- Never use pure `#000` or `#fff` as text — use `var(--text-default)` (warm off-black)
|
|
89
|
+
- Three colour layers: neutrals (90% of pixels) · product accent (`--accent`) · AI gradient (`--ai-grad`) — never mix
|
|
90
|
+
- Sparkle star is the only AI glyph — no robots, brains, lightbulbs, wands
|
|
91
|
+
- Never import Tailwind, Radix defaults, or shadcn themes — use `components.tsx` from the design system
|
|
92
|
+
- Touch targets: 44×44px minimum on mobile
|
|
93
|
+
- Mobile inputs: `font-size ≥ 16px` — iOS Safari zooms on focus otherwise
|
|
94
|
+
- Dark mode: `[data-theme="dark"]` selector overrides — never `@media (prefers-color-scheme: dark)` in component CSS
|
|
95
|
+
- Spacing: multiples of 4px only — allowed: 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48, 56, 64
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## DOCUMENTATION — always
|
|
100
|
+
|
|
101
|
+
- ADR for every irreversible architectural decision — written before code merges
|
|
102
|
+
- Every public API documented (OpenAPI 3.1 for HTTP, equivalent for others)
|
|
103
|
+
- README passes the "5 minutes to running" test
|
|
104
|
+
- Every migration is reversible or explicitly documented as one-way
|
|
105
|
+
- Diagrams in code (Mermaid preferred) — never in external tools that drift
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## ASYNC WORK — any language, any queue
|
|
110
|
+
|
|
111
|
+
- Any work > 1 second belongs in a background job — never block an HTTP handler
|
|
112
|
+
- Every job is idempotent — safe to retry without double side effects
|
|
113
|
+
- Idempotency keys on mutations with external side effects (email, payment, webhook)
|
|
114
|
+
- Jobs have a retry limit with exponential backoff
|
|
115
|
+
- Job failure is observable — dead-letter queue or failure log
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## WHEN TO CHECK FULL DOCS
|
|
120
|
+
|
|
121
|
+
Full guidelines live in the Obsidian Skills vault:
|
|
122
|
+
- Any UI work → load `prism-design` skill
|
|
123
|
+
- Architecture, service boundaries, DB design → `guidelines/architecture-guidelines.md`
|
|
124
|
+
- Auth, file upload, external APIs, AI features → `guidelines/security-guidelines.md`
|
|
125
|
+
- Tests, refactoring, PR review → `guidelines/code-quality-guidelines.md`
|
|
126
|
+
- Performance, caching, queries → `guidelines/performance-guidelines.md`
|
|
127
|
+
- ADRs, READMEs, API docs → `guidelines/documentation-guidelines.md`
|
|
128
|
+
- New component from scratch → `design/implementation-guide.md`
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# Codebase rules — read before every response
|
|
2
|
+
|
|
3
|
+
## Stack
|
|
4
|
+
TypeScript (strict) + Node.js + Express + Prisma + PostgreSQL + Redis + BullMQ.
|
|
5
|
+
AI service: Python 3.12 + FastAPI (separate process).
|
|
6
|
+
Frontend: Next.js + React.
|
|
7
|
+
Design system: Prism (tokens.css + components.tsx — see design/ skill folder).
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## HARD RULES — never violate these
|
|
12
|
+
|
|
13
|
+
### Data & multi-tenancy (existential)
|
|
14
|
+
- Every Prisma query that touches tenant data MUST filter by `tenantId` — enforced by middleware, but always verify
|
|
15
|
+
- Never use `$queryRaw` or `$executeRaw` unless explicitly reviewed — use parameterised Prisma queries only
|
|
16
|
+
- Shared database, shared schema, `tenantId` column — never schema-per-tenant
|
|
17
|
+
- Soft deletes only — never hard-delete tenant data (`deletedAt` timestamp)
|
|
18
|
+
- No `ON DELETE CASCADE` on tenant-scoped tables
|
|
19
|
+
- Unauthorised reads return 404, not 403 — prevents existence leak
|
|
20
|
+
- `tenantId` comes from the session, never from URL params or request body
|
|
21
|
+
|
|
22
|
+
### IDs & pagination
|
|
23
|
+
- ULIDs for all primary keys — not auto-increment integers, not UUIDs
|
|
24
|
+
- Cursor-based pagination only — never offset/limit on large tables
|
|
25
|
+
- Max page size: 100 items, default: 25
|
|
26
|
+
|
|
27
|
+
### Async & queuing
|
|
28
|
+
- Any operation > 1 second must be async via BullMQ — never block an HTTP handler
|
|
29
|
+
- Only queue: BullMQ on Redis — not Kafka, SQS, RabbitMQ
|
|
30
|
+
- Use outbox pattern for events (write to DB first, worker publishes) — never `queue.add()` directly from HTTP handlers
|
|
31
|
+
- Idempotency keys on every mutation that has external side effects
|
|
32
|
+
- Every async job: 5 retries max, exponential backoff (2s base), idempotent
|
|
33
|
+
|
|
34
|
+
### Network & timeouts
|
|
35
|
+
- Every network call has a timeout: 10s (internal HTTP), 5s (fast external APIs), 30s (slow), 60s (AI — async only)
|
|
36
|
+
- Retries only on 5xx and network errors — NEVER retry 4xx
|
|
37
|
+
- Circuit breaker: open after 5 failures in 10s, stay open 30s
|
|
38
|
+
|
|
39
|
+
### Auth & security
|
|
40
|
+
- Passwords: Argon2id only (`time=3, memory=64MB, parallelism=4`) — never bcrypt, never MD5, never SHA-1
|
|
41
|
+
- API keys: Argon2id hashed before storage, displayed once only
|
|
42
|
+
- Sessions: opaque 256-bit random tokens stored in Redis — NOT JWTs for user sessions
|
|
43
|
+
- Session rotation on: login, logout, MFA completion, role change
|
|
44
|
+
- Password reset does NOT log the user in — they re-authenticate after
|
|
45
|
+
- Never reveal whether an email exists — always respond `200 RESET_EMAIL_SENT_IF_EXISTS`
|
|
46
|
+
- Failed logins: lock account after 10 failures, rate-limit 5/hour per account
|
|
47
|
+
- MFA required for `owner` and `admin` roles (TOTP, RFC 6238)
|
|
48
|
+
- Role changes require dedicated endpoint — never via generic PATCH, user cannot change own role
|
|
49
|
+
- Admin impersonation TTL: 1 hour max
|
|
50
|
+
|
|
51
|
+
### Input & output
|
|
52
|
+
- Validate every input at every boundary with Zod (TypeScript) or Pydantic `.strict()` (Python)
|
|
53
|
+
- All strings must have max length — prevents DoS
|
|
54
|
+
- File uploads: magic-number type validation, ClamAV virus scan, re-encode images (strips EXIF), store on object storage only (signed URLs)
|
|
55
|
+
- Never use `dangerouslySetInnerHTML` without DOMPurify + explicit code-review tag
|
|
56
|
+
- AI output: validate with Zod schema before use, never trust for authorisation decisions
|
|
57
|
+
- SSRF: DNS-resolve before fetching, reject private IPs
|
|
58
|
+
|
|
59
|
+
### Secrets & config
|
|
60
|
+
- All secrets in Doppler or AWS Secrets Manager — never in code, never in `.env` files committed to git
|
|
61
|
+
- One place reads `process.env`: `shared/config.ts` with Zod schema — nowhere else
|
|
62
|
+
- No secrets in logs, errors, or API responses
|
|
63
|
+
- Secrets rotated quarterly — dual-key rotation window
|
|
64
|
+
|
|
65
|
+
### Logging & observability
|
|
66
|
+
- Structured JSON logs only — required fields: `timestamp`, `level`, `service`, `correlationId`, `tenantId`, `userId`, `message`
|
|
67
|
+
- Correlation ID propagates through all logs, queue jobs, cross-service calls, and audit entries
|
|
68
|
+
- Audit log is append-only — 7-year retention, no UPDATE/DELETE at DB role level
|
|
69
|
+
- Every route emits: `http_requests_total`, `http_request_duration_seconds`
|
|
70
|
+
|
|
71
|
+
### API design
|
|
72
|
+
- REST + JSON — no GraphQL unless multiple first-party clients with wildly different data needs
|
|
73
|
+
- URL versioning: `/api/v1/`, `/api/v2/` — not header-based
|
|
74
|
+
- Standard error envelope: `{ code, message, correlationId, details }`
|
|
75
|
+
- Rate limits: 100 req/60s per user (default), 5/60s for login and password-reset
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## CODE QUALITY RULES
|
|
80
|
+
|
|
81
|
+
- TypeScript `strict: true` + `noUncheckedIndexedAccess` + `noImplicitOverride` — no exceptions
|
|
82
|
+
- Never use `any` — use `unknown` with type narrowing
|
|
83
|
+
- Never use TypeScript `enum` — use string literal unions or `as const` objects
|
|
84
|
+
- Functions ≤ 80 lines (aim ≤ 30), files ≤ 500 lines (aim ≤ 300)
|
|
85
|
+
- No `console.log` — use the structured logger
|
|
86
|
+
- No commented-out code — delete it or put it in a ticket
|
|
87
|
+
- Boolean variables: `is/has/can/should` prefix
|
|
88
|
+
- No N+1 queries — always use Prisma `include/select` or a JOIN
|
|
89
|
+
- Error handling: throw exceptions for programming errors, return Result types for expected failures (validation, not-found, rate-limit)
|
|
90
|
+
- Async/await always — never raw `.then()` chains
|
|
91
|
+
- PR size: ≤ 400 lines unless generated code — split larger changes
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## PERFORMANCE BUDGETS (hard caps)
|
|
96
|
+
|
|
97
|
+
| Interaction | Target |
|
|
98
|
+
|---|---|
|
|
99
|
+
| UI response (click, hover) | ≤ 100ms |
|
|
100
|
+
| API read (cached, single) | p95 < 200ms |
|
|
101
|
+
| API read (list, paginated) | p95 < 300ms |
|
|
102
|
+
| API write | p95 < 300ms |
|
|
103
|
+
| LCP | ≤ 2.5s (p75) |
|
|
104
|
+
| INP | ≤ 200ms (p75) |
|
|
105
|
+
| CLS | ≤ 0.1 (p75) |
|
|
106
|
+
| JS bundle (gzipped) | ≤ 170KB |
|
|
107
|
+
| CSS bundle (gzipped) | ≤ 30KB |
|
|
108
|
+
| DB query (indexed lookup) | ≤ 10ms |
|
|
109
|
+
| DB query (list with joins) | ≤ 200ms |
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## PRISM DESIGN SYSTEM RULES
|
|
114
|
+
|
|
115
|
+
- Never hardcode colours, radii, or font names — use CSS tokens (`var(--token-name)`)
|
|
116
|
+
- Never use pure `#000` or `#fff` as text — use `rgb(55, 53, 47)` (off-black) via `var(--text-default)`
|
|
117
|
+
- Three colour layers: neutrals (90% of pixels), product accent (`--accent`), AI gradient (`--ai-grad`) — never mix them
|
|
118
|
+
- Sparkle star is the ONLY AI glyph — no robots, brains, lightbulbs, or wands
|
|
119
|
+
- Never import Tailwind, Radix defaults, or shadcn themes — use components.tsx from the design system
|
|
120
|
+
- Touch targets: 44×44px minimum on mobile
|
|
121
|
+
- Never use `font-size` < 16px on mobile inputs — iOS Safari zooms on focus
|
|
122
|
+
- Dark mode: use `[data-theme="dark"]` selector overrides — never `@media (prefers-color-scheme: dark)` in component CSS
|
|
123
|
+
- Every component must work in light AND dark mode
|
|
124
|
+
- Spacing: multiples of 4px only — allowed values: 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48, 56, 64
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## WHEN TO CHECK FULL DOCS
|
|
129
|
+
|
|
130
|
+
Full guidelines live in the Skills folder. Load them when:
|
|
131
|
+
|
|
132
|
+
| Situation | Read |
|
|
133
|
+
|---|---|
|
|
134
|
+
| Building any UI component or screen | `design/SKILL.md` → then the relevant `patterns-*.md` |
|
|
135
|
+
| Adding auth, tenant logic, or a new service | `guidelines/architecture-guidelines.md` |
|
|
136
|
+
| Adding file upload, external API, or AI feature | `guidelines/security-guidelines.md` |
|
|
137
|
+
| Writing tests or refactoring | `guidelines/code-quality-guidelines.md` |
|
|
138
|
+
| Slow queries, caching, bundle size | `guidelines/performance-guidelines.md` |
|
|
139
|
+
| Writing an ADR or README | `guidelines/documentation-guidelines.md` |
|
|
140
|
+
| Building a new component from scratch | `design/implementation-guide.md` |
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## ARCHITECTURE DECISIONS ALREADY MADE (don't re-litigate)
|
|
145
|
+
|
|
146
|
+
| Decision | Choice | Reason |
|
|
147
|
+
|---|---|---|
|
|
148
|
+
| DB access | Prisma only | Parameterised by default, tenant middleware |
|
|
149
|
+
| Queue | BullMQ on Redis | Single system, battle-tested at this scale |
|
|
150
|
+
| Sessions | Opaque tokens in Redis | Revocable, no JWT signature key management |
|
|
151
|
+
| Search | PostgreSQL FTS | Sufficient to 100k users; extract to Typesense at scale |
|
|
152
|
+
| DB topology | Shared Postgres, tenant_id column | Schema-per-tenant impossible at scale for migrations |
|
|
153
|
+
| API style | REST + JSON | Debuggable, works across Node + Python |
|
|
154
|
+
| Passwords | Argon2id | bcrypt is deprecated for this use case |
|
|
155
|
+
| Deployment | Fly Machines (preferred) → ECS → K8s (only with SRE) | Operational complexity ladder |
|