create-standards 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/README.md +89 -0
- package/bin/create-standards.js +3 -0
- package/package.json +32 -0
- package/src/cli.js +355 -0
- package/src/discover.js +113 -0
- package/src/ide-config.js +57 -0
- package/src/install.js +77 -0
- package/standards/nodejs-express-standards/README.md +59 -0
- package/standards/nodejs-express-standards/antigravity/.agents/skills/nodejs-express-standards/SKILL.md +40 -0
- package/standards/nodejs-express-standards/antigravity/.agents/skills/nodejs-express-standards/references/01-project-structure.md +33 -0
- package/standards/nodejs-express-standards/antigravity/.agents/skills/nodejs-express-standards/references/02-api-design-standards.md +41 -0
- package/standards/nodejs-express-standards/antigravity/.agents/skills/nodejs-express-standards/references/03-error-handling-validation.md +27 -0
- package/standards/nodejs-express-standards/antigravity/.agents/skills/nodejs-express-standards/references/04-security-standards.md +17 -0
- package/standards/nodejs-express-standards/antigravity/.agents/skills/nodejs-express-standards/references/05-database-model-standards.md +10 -0
- package/standards/nodejs-express-standards/antigravity/.agents/skills/nodejs-express-standards/references/06-testing-standards.md +10 -0
- package/standards/nodejs-express-standards/antigravity/.agents/skills/nodejs-express-standards/references/07-new-component-checklist.md +16 -0
- package/standards/nodejs-express-standards/antigravity/.agents/skills/nodejs-express-standards/references/08-code-style-general.md +9 -0
- package/standards/nodejs-express-standards/claude-code/.claude/skills/nodejs-express-standards/SKILL.md +40 -0
- package/standards/nodejs-express-standards/claude-code/.claude/skills/nodejs-express-standards/references/01-project-structure.md +33 -0
- package/standards/nodejs-express-standards/claude-code/.claude/skills/nodejs-express-standards/references/02-api-design-standards.md +41 -0
- package/standards/nodejs-express-standards/claude-code/.claude/skills/nodejs-express-standards/references/03-error-handling-validation.md +27 -0
- package/standards/nodejs-express-standards/claude-code/.claude/skills/nodejs-express-standards/references/04-security-standards.md +17 -0
- package/standards/nodejs-express-standards/claude-code/.claude/skills/nodejs-express-standards/references/05-database-model-standards.md +10 -0
- package/standards/nodejs-express-standards/claude-code/.claude/skills/nodejs-express-standards/references/06-testing-standards.md +10 -0
- package/standards/nodejs-express-standards/claude-code/.claude/skills/nodejs-express-standards/references/07-new-component-checklist.md +16 -0
- package/standards/nodejs-express-standards/claude-code/.claude/skills/nodejs-express-standards/references/08-code-style-general.md +9 -0
- package/standards/nodejs-express-standards/cursor/.cursor/rules/00-index.mdc +25 -0
- package/standards/nodejs-express-standards/cursor/.cursor/rules/01-project-structure.mdc +38 -0
- package/standards/nodejs-express-standards/cursor/.cursor/rules/02-api-design.mdc +46 -0
- package/standards/nodejs-express-standards/cursor/.cursor/rules/03-error-handling-validation.mdc +32 -0
- package/standards/nodejs-express-standards/cursor/.cursor/rules/04-security.mdc +22 -0
- package/standards/nodejs-express-standards/cursor/.cursor/rules/05-database-models.mdc +15 -0
- package/standards/nodejs-express-standards/cursor/.cursor/rules/06-testing.mdc +15 -0
- package/standards/nodejs-express-standards/cursor/.cursor/rules/07-new-component-checklist.mdc +21 -0
- package/standards/nodejs-express-standards/cursor/.cursor/rules/08-code-style.mdc +14 -0
- package/standards/nodejs-express-standards/shared-reference/01-project-structure.md +33 -0
- package/standards/nodejs-express-standards/shared-reference/02-api-design-standards.md +41 -0
- package/standards/nodejs-express-standards/shared-reference/03-error-handling-validation.md +27 -0
- package/standards/nodejs-express-standards/shared-reference/04-security-standards.md +17 -0
- package/standards/nodejs-express-standards/shared-reference/05-database-model-standards.md +10 -0
- package/standards/nodejs-express-standards/shared-reference/06-testing-standards.md +10 -0
- package/standards/nodejs-express-standards/shared-reference/07-new-component-checklist.md +16 -0
- package/standards/nodejs-express-standards/shared-reference/08-code-style-general.md +8 -0
- package/standards/rails-standards/README.md +86 -0
- package/standards/rails-standards/antigravity/.agents/skills/rails-standards/SKILL.md +66 -0
- package/standards/rails-standards/antigravity/.agents/skills/rails-standards/references/00-quick-scaffold.md +83 -0
- package/standards/rails-standards/antigravity/.agents/skills/rails-standards/references/01-project-structure.md +44 -0
- package/standards/rails-standards/antigravity/.agents/skills/rails-standards/references/02-api-design-standards.md +46 -0
- package/standards/rails-standards/antigravity/.agents/skills/rails-standards/references/03-error-handling-validation.md +35 -0
- package/standards/rails-standards/antigravity/.agents/skills/rails-standards/references/04-security-standards.md +32 -0
- package/standards/rails-standards/antigravity/.agents/skills/rails-standards/references/05-database-model-standards.md +25 -0
- package/standards/rails-standards/antigravity/.agents/skills/rails-standards/references/06-testing-standards.md +26 -0
- package/standards/rails-standards/antigravity/.agents/skills/rails-standards/references/07-new-component-checklist.md +26 -0
- package/standards/rails-standards/antigravity/.agents/skills/rails-standards/references/08-code-style-general.md +47 -0
- package/standards/rails-standards/claude-code/.claude/skills/rails-standards/SKILL.md +66 -0
- package/standards/rails-standards/claude-code/.claude/skills/rails-standards/references/00-quick-scaffold.md +83 -0
- package/standards/rails-standards/claude-code/.claude/skills/rails-standards/references/01-project-structure.md +44 -0
- package/standards/rails-standards/claude-code/.claude/skills/rails-standards/references/02-api-design-standards.md +46 -0
- package/standards/rails-standards/claude-code/.claude/skills/rails-standards/references/03-error-handling-validation.md +35 -0
- package/standards/rails-standards/claude-code/.claude/skills/rails-standards/references/04-security-standards.md +32 -0
- package/standards/rails-standards/claude-code/.claude/skills/rails-standards/references/05-database-model-standards.md +25 -0
- package/standards/rails-standards/claude-code/.claude/skills/rails-standards/references/06-testing-standards.md +26 -0
- package/standards/rails-standards/claude-code/.claude/skills/rails-standards/references/07-new-component-checklist.md +26 -0
- package/standards/rails-standards/claude-code/.claude/skills/rails-standards/references/08-code-style-general.md +47 -0
- package/standards/rails-standards/cursor/.cursor/rules/00-always-on.mdc +26 -0
- package/standards/rails-standards/cursor/.cursor/rules/01-project-structure.mdc +49 -0
- package/standards/rails-standards/cursor/.cursor/rules/02-api-design.mdc +51 -0
- package/standards/rails-standards/cursor/.cursor/rules/03-error-handling-validation.mdc +40 -0
- package/standards/rails-standards/cursor/.cursor/rules/04-security.mdc +37 -0
- package/standards/rails-standards/cursor/.cursor/rules/05-database-models.mdc +30 -0
- package/standards/rails-standards/cursor/.cursor/rules/06-testing.mdc +31 -0
- package/standards/rails-standards/cursor/.cursor/rules/07-new-component-checklist.mdc +31 -0
- package/standards/rails-standards/cursor/.cursor/rules/08-code-style.mdc +52 -0
- package/standards/rails-standards/cursor/.cursor/rules/09-quick-scaffold.mdc +88 -0
- package/standards/rails-standards/shared-reference/00-quick-scaffold.md +83 -0
- package/standards/rails-standards/shared-reference/01-project-structure.md +44 -0
- package/standards/rails-standards/shared-reference/02-api-design-standards.md +46 -0
- package/standards/rails-standards/shared-reference/03-error-handling-validation.md +35 -0
- package/standards/rails-standards/shared-reference/04-security-standards.md +32 -0
- package/standards/rails-standards/shared-reference/05-database-model-standards.md +25 -0
- package/standards/rails-standards/shared-reference/06-testing-standards.md +26 -0
- package/standards/rails-standards/shared-reference/07-new-component-checklist.md +26 -0
- package/standards/rails-standards/shared-reference/08-code-style-general.md +47 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Project structure and layered architecture rules for this Node/Express codebase
|
|
3
|
+
globs: src/**/*.js,src/**/*.ts
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
# Project Structure Standards (Node.js + Express)
|
|
7
|
+
|
|
8
|
+
## Standard folder layout
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
src/
|
|
12
|
+
config/ # env loading + validation, db config, third-party config
|
|
13
|
+
routes/ # express.Router() definitions only — no logic
|
|
14
|
+
controllers/ # HTTP layer: parse req, call service, shape res
|
|
15
|
+
services/ # business logic, orchestration — framework-agnostic
|
|
16
|
+
repositories/ # data access layer (DB queries), one per model/table
|
|
17
|
+
models/ # ORM/schema definitions
|
|
18
|
+
validators/ # request schema validation (zod/joi/celebrate)
|
|
19
|
+
middlewares/ # auth, error handler, rate limit, logging
|
|
20
|
+
utils/ # pure helper functions
|
|
21
|
+
jobs/ # cron / queue workers
|
|
22
|
+
events/ # event emitters / pub-sub handlers
|
|
23
|
+
constants/ # enums, error codes, status strings
|
|
24
|
+
app.js # express app assembly (middleware + routes), NO app.listen()
|
|
25
|
+
server.js # imports app.js, calls app.listen(), handles graceful shutdown
|
|
26
|
+
tests/
|
|
27
|
+
unit/
|
|
28
|
+
integration/
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Rules
|
|
32
|
+
|
|
33
|
+
- **Layered architecture is mandatory**: `route → controller → service → repository → model`. A controller never talks to the DB directly, and a service never touches `req`/`res`.
|
|
34
|
+
- Split `app.js` (the Express app object) from `server.js` (the process/listener) so the app can be imported into supertest without binding a port.
|
|
35
|
+
- Config must be loaded and **validated at startup** (e.g. with `envalid`, `zod`, or `joi`) — fail fast if a required env var is missing, don't let it fail later at runtime.
|
|
36
|
+
- No business logic in `routes/`. Routes only wire `path + method → middleware chain → controller`.
|
|
37
|
+
- One repository per aggregate/model. Repositories are the only files allowed to import the ORM/query builder directly.
|
|
38
|
+
- Barrel files (`index.js`) per folder are optional but if used, keep them to re-exports only — no logic.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: REST API design conventions — use when creating or editing routes/controllers
|
|
3
|
+
globs: src/routes/**/*.js,src/controllers/**/*.js
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
# REST API Design Standards
|
|
7
|
+
|
|
8
|
+
## Resource naming & routing
|
|
9
|
+
|
|
10
|
+
- Use plural nouns for resources: `/users`, `/orders`, not `/user` or `/getUsers`.
|
|
11
|
+
- Nest resources only one level deep: `/orders/:orderId/items`, avoid deeper nesting.
|
|
12
|
+
- Version the API from day one: `/api/v1/...`. Never ship an unversioned public API.
|
|
13
|
+
- Use HTTP verbs correctly, never verbs in the path:
|
|
14
|
+
|
|
15
|
+
| Verb | Path | Action |
|
|
16
|
+
|--------|-------------------|-------------------------|
|
|
17
|
+
| GET | /users | list |
|
|
18
|
+
| GET | /users/:id | read one |
|
|
19
|
+
| POST | /users | create |
|
|
20
|
+
| PUT | /users/:id | full replace |
|
|
21
|
+
| PATCH | /users/:id | partial update |
|
|
22
|
+
| DELETE | /users/:id | delete |
|
|
23
|
+
|
|
24
|
+
## Status codes
|
|
25
|
+
|
|
26
|
+
- `200` OK (read/update), `201` Created (with `Location` header), `204` No Content (delete/no body).
|
|
27
|
+
- `400` validation error, `401` unauthenticated, `403` unauthorized, `404` not found, `409` conflict, `422` semantically invalid, `429` rate-limited, `500` unhandled server error.
|
|
28
|
+
- Never return `200` with an error payload — the HTTP status must reflect the outcome.
|
|
29
|
+
|
|
30
|
+
## Response envelope (consistent across all endpoints)
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
// success
|
|
34
|
+
{ "success": true, "data": { }, "meta": { "page": 1, "totalPages": 4 } }
|
|
35
|
+
|
|
36
|
+
// error
|
|
37
|
+
{ "success": false, "error": { "code": "VALIDATION_ERROR", "message": "email is required", "details": [] } }
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Other requirements
|
|
41
|
+
|
|
42
|
+
- **Pagination** is required on every list endpoint (`?page=&limit=` or cursor-based `?cursor=`) — never return an unbounded array.
|
|
43
|
+
- **Filtering/sorting** via query params (`?status=active&sort=-createdAt`), validated against an allow-list of fields (never pass raw query straight into a DB `WHERE`/`ORDER BY`).
|
|
44
|
+
- **Idempotency**: `PUT`/`DELETE` must be idempotent. For `POST` on payment/order-creation style endpoints, support an `Idempotency-Key` header.
|
|
45
|
+
- **Document every endpoint** with OpenAPI/Swagger (`swagger-jsdoc` or a maintained `openapi.yaml`) — a new endpoint is not done until it's documented.
|
|
46
|
+
- Never expose internal DB IDs/structure verbatim if it leaks implementation details; DTOs/serializers shape what the client sees.
|
package/standards/nodejs-express-standards/cursor/.cursor/rules/03-error-handling-validation.mdc
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Error handling and request validation conventions
|
|
3
|
+
globs: src/middlewares/**/*.js,src/validators/**/*.js,src/controllers/**/*.js
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
# Error Handling & Validation Standards
|
|
7
|
+
|
|
8
|
+
## Custom error class
|
|
9
|
+
|
|
10
|
+
```js
|
|
11
|
+
class AppError extends Error {
|
|
12
|
+
constructor(message, statusCode, code) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.statusCode = statusCode;
|
|
15
|
+
this.code = code;
|
|
16
|
+
this.isOperational = true; // distinguishes expected errors from bugs
|
|
17
|
+
Error.captureStackTrace(this, this.constructor);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Rules
|
|
23
|
+
|
|
24
|
+
- **Never use raw `try/catch` scattered in controllers.** Wrap async route handlers with a `catchAsync`/`asyncHandler` utility that forwards rejected promises to `next(err)`.
|
|
25
|
+
- **One centralized error-handling middleware**, registered last in `app.js`, that:
|
|
26
|
+
- Logs the error (with request id / correlation id).
|
|
27
|
+
- Returns the standard error envelope.
|
|
28
|
+
- Hides stack traces and internal messages in production (`isOperational === false` → generic "Something went wrong").
|
|
29
|
+
- **Validate every request at the boundary**, before it reaches the controller body — use a schema library (`zod`, `joi`, or `celebrate`) as route middleware, not manual `if` checks sprinkled through the controller.
|
|
30
|
+
- Validation errors return `400`/`422` with a `details` array listing each failing field.
|
|
31
|
+
- Distinguish **operational errors** (bad input, not found, auth failure — expected, safe to show a message) from **programmer errors** (bugs — log, alert, return generic 500).
|
|
32
|
+
- Async code must never produce an unhandled promise rejection — catch at the boundary, always.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Security defaults required on every Express service — auth, secrets, rate limiting, sanitization
|
|
3
|
+
globs:
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
# Security Standards
|
|
7
|
+
|
|
8
|
+
Apply all of these by default on every new Express service — don't wait to be asked:
|
|
9
|
+
|
|
10
|
+
- **Helmet**: `app.use(helmet())` for secure headers (CSP, HSTS, X-Frame-Options, etc.) — configure CSP explicitly rather than leaving it wide open.
|
|
11
|
+
- **CORS**: explicit origin allow-list via the `cors` package, never `origin: '*'` on an authenticated API.
|
|
12
|
+
- **Rate limiting**: `express-rate-limit` (or a Redis-backed store in multi-instance deployments) on all public endpoints, stricter limits on auth endpoints (`/login`, `/register`, `/forgot-password`).
|
|
13
|
+
- **Input sanitization**: strip/escape untrusted input against NoSQL/SQL injection and XSS (`express-mongo-sanitize`, parameterized queries/ORM query builders — never string-concatenate SQL).
|
|
14
|
+
- **AuthN/AuthZ**:
|
|
15
|
+
- Short-lived JWT access tokens + refresh token rotation, or session cookies with `httpOnly`, `secure`, `sameSite`.
|
|
16
|
+
- Passwords hashed with `bcrypt`/`argon2`, never stored or logged in plaintext.
|
|
17
|
+
- Role/permission checks live in middleware, applied per-route, not scattered inside controller `if` statements.
|
|
18
|
+
- **Secrets**: only via environment variables / a secrets manager. Never commit `.env`, never hardcode API keys or DB credentials.
|
|
19
|
+
- **Request limits**: `express.json({ limit: '10kb' })` (or an appropriate cap) to prevent payload-based DoS.
|
|
20
|
+
- **Dependency hygiene**: run `npm audit` (or Snyk/Dependabot) as part of CI; block merges on high/critical vulnerabilities.
|
|
21
|
+
- **HTTPS only** in production; redirect HTTP → HTTPS at the load balancer/proxy layer.
|
|
22
|
+
- Never leak stack traces, internal file paths, or library versions in API responses or headers.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Database, ORM, and model conventions — use when creating or editing models/repositories/migrations
|
|
3
|
+
globs: src/models/**/*.js,src/repositories/**/*.js,migrations/**/*.js
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
# Database & Model Standards
|
|
7
|
+
|
|
8
|
+
- **Repository pattern**: all DB queries live in `repositories/`, never directly inside services or controllers. Services call repository methods; they don't know it's Postgres/Mongo/etc.
|
|
9
|
+
- **Migrations are mandatory** for schema changes (e.g. `knex`, `sequelize-cli`, `prisma migrate`, `typeorm migration`). Never use `sync({ alter: true })` or manual schema edits against a shared/production DB.
|
|
10
|
+
- Every table/collection gets `createdAt` and `updatedAt` timestamps by default.
|
|
11
|
+
- Prefer **soft deletes** (`deletedAt` column + default query scope excluding it) over hard deletes for user-facing/business-critical records; hard-delete only where there's a clear compliance/retention reason.
|
|
12
|
+
- Index every foreign key and every column used in a frequent `WHERE`/`sort` — check the query plan (`EXPLAIN`) for anything added to a hot path.
|
|
13
|
+
- **Transactions** wrap any operation that writes to more than one table/collection, so a partial failure can't leave data inconsistent.
|
|
14
|
+
- Naming: `snake_case` for DB columns/tables, `camelCase` in JS — handle the mapping in the ORM config, don't hand-convert per query.
|
|
15
|
+
- Never return raw ORM model instances straight from a controller — map to a DTO/serializer so DB shape and API shape can evolve independently.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Testing requirements — use when writing or reviewing tests
|
|
3
|
+
globs: tests/**/*.js,**/*.test.js,**/*.spec.js
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
# Testing Standards
|
|
7
|
+
|
|
8
|
+
- **Unit tests** (Jest/Vitest) for every service function — mock the repository layer, test business logic in isolation.
|
|
9
|
+
- **Integration tests** (Supertest against the exported `app.js`, not a running server) for every route — exercise the real middleware chain, validation, and error handler.
|
|
10
|
+
- Use a dedicated test database (or transactional rollback per test) — tests must never touch dev/prod data, and must be safely re-runnable/parallelizable.
|
|
11
|
+
- Follow **Arrange–Act–Assert** structure in every test; one logical assertion focus per test case.
|
|
12
|
+
- Mock external services/network calls (payment providers, email, third-party APIs) — tests must not depend on network access.
|
|
13
|
+
- Minimum coverage threshold: **80%** on services and controllers, enforced in CI (fail the build below threshold).
|
|
14
|
+
- Every new endpoint or model ships with at least: one happy-path integration test, one validation-failure test, one auth-failure test (if protected).
|
|
15
|
+
- CI must run lint → unit → integration → coverage gate, in that order, before a PR can merge.
|
package/standards/nodejs-express-standards/cursor/.cursor/rules/07-new-component-checklist.mdc
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Manual checklist — invoke with @07-new-component-checklist before scaffolding any new model, route, or component
|
|
3
|
+
globs:
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
# Checklist: Before Creating Any New Model, Route, or Component
|
|
7
|
+
|
|
8
|
+
Run through this before writing code for a new feature — this is what a senior architect reviews for in a PR:
|
|
9
|
+
|
|
10
|
+
1. **Check for an existing pattern first.** Look at a similar existing model/route/service in the codebase and follow its shape — don't introduce a new pattern for something that already has one.
|
|
11
|
+
2. **Confirm the layer boundaries**: route (wiring only) → validator (schema) → controller (HTTP glue) → service (logic) → repository (DB) → model. No shortcuts (e.g. controller querying the DB directly).
|
|
12
|
+
3. **Write the validation schema** for every input (body/params/query) before writing the controller.
|
|
13
|
+
4. **Define the DB migration** (not a live schema edit) if a new table/column is needed, with indexes on any FK/frequently-queried column.
|
|
14
|
+
5. **Handle errors explicitly**: use `AppError`/`catchAsync`, no bare `try/catch` with silent `console.log`.
|
|
15
|
+
6. **Add authorization checks** if the resource is user/role-scoped — don't rely on the client to hide UI for unauthorized actions.
|
|
16
|
+
7. **Write tests**: at minimum one integration test (happy path) and one validation/error-path test.
|
|
17
|
+
8. **Update API documentation** (OpenAPI/Swagger) for any new or changed endpoint.
|
|
18
|
+
9. **Run lint + format** (ESLint + Prettier) — no new lint warnings introduced.
|
|
19
|
+
10. **No secrets, no hardcoded config** — anything environment-specific goes through `config/`.
|
|
20
|
+
11. **Consider pagination/rate-limits** if it's a list endpoint or public-facing.
|
|
21
|
+
12. Keep the diff focused — one feature/concern per PR/commit.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: General code style, lint, logging, and commit conventions
|
|
3
|
+
globs:
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
# General Code Style Standards
|
|
7
|
+
|
|
8
|
+
- ESLint (Airbnb-base or `eslint-config-standard`) + Prettier, enforced via a pre-commit hook (`husky` + `lint-staged`) and in CI — not just "run it locally sometimes."
|
|
9
|
+
- `async/await` everywhere; no mixing with raw `.then()` chains or callback-style APIs in new code.
|
|
10
|
+
- No `console.log` in committed code — use a structured logger (`pino` or `winston`) with log levels, and include a request/correlation id in every log line.
|
|
11
|
+
- One export/responsibility per file; avoid god-files that mix routing, business logic, and DB access.
|
|
12
|
+
- Environment-based configuration only (`dotenv` + a validated config schema) — never branch behavior on `NODE_ENV` scattered through business logic; centralize environment differences in `config/`.
|
|
13
|
+
- Commit messages follow Conventional Commits (`feat:`, `fix:`, `refactor:`, `test:`, `chore:`) so history and changelogs stay meaningful.
|
|
14
|
+
- Prefer explicit, readable code over clever one-liners — this codebase is read far more often than it's written.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Project Structure Standards (Node.js + Express)
|
|
2
|
+
|
|
3
|
+
## Standard folder layout
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
src/
|
|
7
|
+
config/ # env loading + validation, db config, third-party config
|
|
8
|
+
routes/ # express.Router() definitions only — no logic
|
|
9
|
+
controllers/ # HTTP layer: parse req, call service, shape res
|
|
10
|
+
services/ # business logic, orchestration — framework-agnostic
|
|
11
|
+
repositories/ # data access layer (DB queries), one per model/table
|
|
12
|
+
models/ # ORM/schema definitions
|
|
13
|
+
validators/ # request schema validation (zod/joi/celebrate)
|
|
14
|
+
middlewares/ # auth, error handler, rate limit, logging
|
|
15
|
+
utils/ # pure helper functions
|
|
16
|
+
jobs/ # cron / queue workers
|
|
17
|
+
events/ # event emitters / pub-sub handlers
|
|
18
|
+
constants/ # enums, error codes, status strings
|
|
19
|
+
app.js # express app assembly (middleware + routes), NO app.listen()
|
|
20
|
+
server.js # imports app.js, calls app.listen(), handles graceful shutdown
|
|
21
|
+
tests/
|
|
22
|
+
unit/
|
|
23
|
+
integration/
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Rules
|
|
27
|
+
|
|
28
|
+
- **Layered architecture is mandatory**: `route → controller → service → repository → model`. A controller never talks to the DB directly, and a service never touches `req`/`res`.
|
|
29
|
+
- Split `app.js` (the Express app object) from `server.js` (the process/listener) so the app can be imported into supertest without binding a port.
|
|
30
|
+
- Config must be loaded and **validated at startup** (e.g. with `envalid`, `zod`, or `joi`) — fail fast if a required env var is missing, don't let it fail later at runtime.
|
|
31
|
+
- No business logic in `routes/`. Routes only wire `path + method → middleware chain → controller`.
|
|
32
|
+
- One repository per aggregate/model. Repositories are the only files allowed to import the ORM/query builder directly.
|
|
33
|
+
- Barrel files (`index.js`) per folder are optional but if used, keep them to re-exports only — no logic.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# REST API Design Standards
|
|
2
|
+
|
|
3
|
+
## Resource naming & routing
|
|
4
|
+
|
|
5
|
+
- Use plural nouns for resources: `/users`, `/orders`, not `/user` or `/getUsers`.
|
|
6
|
+
- Nest resources only one level deep: `/orders/:orderId/items`, avoid deeper nesting.
|
|
7
|
+
- Version the API from day one: `/api/v1/...`. Never ship an unversioned public API.
|
|
8
|
+
- Use HTTP verbs correctly, never verbs in the path:
|
|
9
|
+
|
|
10
|
+
| Verb | Path | Action |
|
|
11
|
+
|--------|-------------------|-------------------------|
|
|
12
|
+
| GET | /users | list |
|
|
13
|
+
| GET | /users/:id | read one |
|
|
14
|
+
| POST | /users | create |
|
|
15
|
+
| PUT | /users/:id | full replace |
|
|
16
|
+
| PATCH | /users/:id | partial update |
|
|
17
|
+
| DELETE | /users/:id | delete |
|
|
18
|
+
|
|
19
|
+
## Status codes
|
|
20
|
+
|
|
21
|
+
- `200` OK (read/update), `201` Created (with `Location` header), `204` No Content (delete/no body).
|
|
22
|
+
- `400` validation error, `401` unauthenticated, `403` unauthorized, `404` not found, `409` conflict, `422` semantically invalid, `429` rate-limited, `500` unhandled server error.
|
|
23
|
+
- Never return `200` with an error payload — the HTTP status must reflect the outcome.
|
|
24
|
+
|
|
25
|
+
## Response envelope (consistent across all endpoints)
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
// success
|
|
29
|
+
{ "success": true, "data": { }, "meta": { "page": 1, "totalPages": 4 } }
|
|
30
|
+
|
|
31
|
+
// error
|
|
32
|
+
{ "success": false, "error": { "code": "VALIDATION_ERROR", "message": "email is required", "details": [] } }
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Other requirements
|
|
36
|
+
|
|
37
|
+
- **Pagination** is required on every list endpoint (`?page=&limit=` or cursor-based `?cursor=`) — never return an unbounded array.
|
|
38
|
+
- **Filtering/sorting** via query params (`?status=active&sort=-createdAt`), validated against an allow-list of fields (never pass raw query straight into a DB `WHERE`/`ORDER BY`).
|
|
39
|
+
- **Idempotency**: `PUT`/`DELETE` must be idempotent. For `POST` on payment/order-creation style endpoints, support an `Idempotency-Key` header.
|
|
40
|
+
- **Document every endpoint** with OpenAPI/Swagger (`swagger-jsdoc` or a maintained `openapi.yaml`) — a new endpoint is not done until it's documented.
|
|
41
|
+
- Never expose internal DB IDs/structure verbatim if it leaks implementation details; DTOs/serializers shape what the client sees.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Error Handling & Validation Standards
|
|
2
|
+
|
|
3
|
+
## Custom error class
|
|
4
|
+
|
|
5
|
+
```js
|
|
6
|
+
class AppError extends Error {
|
|
7
|
+
constructor(message, statusCode, code) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.statusCode = statusCode;
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.isOperational = true; // distinguishes expected errors from bugs
|
|
12
|
+
Error.captureStackTrace(this, this.constructor);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Rules
|
|
18
|
+
|
|
19
|
+
- **Never use raw `try/catch` scattered in controllers.** Wrap async route handlers with a `catchAsync`/`asyncHandler` utility that forwards rejected promises to `next(err)`.
|
|
20
|
+
- **One centralized error-handling middleware**, registered last in `app.js`, that:
|
|
21
|
+
- Logs the error (with request id / correlation id).
|
|
22
|
+
- Returns the standard error envelope.
|
|
23
|
+
- Hides stack traces and internal messages in production (`isOperational === false` → generic "Something went wrong").
|
|
24
|
+
- **Validate every request at the boundary**, before it reaches the controller body — use a schema library (`zod`, `joi`, or `celebrate`) as route middleware, not manual `if` checks sprinkled through the controller.
|
|
25
|
+
- Validation errors return `400`/`422` with a `details` array listing each failing field.
|
|
26
|
+
- Distinguish **operational errors** (bad input, not found, auth failure — expected, safe to show a message) from **programmer errors** (bugs — log, alert, return generic 500).
|
|
27
|
+
- Async code must never produce an unhandled promise rejection — catch at the boundary, always.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Security Standards
|
|
2
|
+
|
|
3
|
+
Apply all of these by default on every new Express service — don't wait to be asked:
|
|
4
|
+
|
|
5
|
+
- **Helmet**: `app.use(helmet())` for secure headers (CSP, HSTS, X-Frame-Options, etc.) — configure CSP explicitly rather than leaving it wide open.
|
|
6
|
+
- **CORS**: explicit origin allow-list via the `cors` package, never `origin: '*'` on an authenticated API.
|
|
7
|
+
- **Rate limiting**: `express-rate-limit` (or a Redis-backed store in multi-instance deployments) on all public endpoints, stricter limits on auth endpoints (`/login`, `/register`, `/forgot-password`).
|
|
8
|
+
- **Input sanitization**: strip/escape untrusted input against NoSQL/SQL injection and XSS (`express-mongo-sanitize`, parameterized queries/ORM query builders — never string-concatenate SQL).
|
|
9
|
+
- **AuthN/AuthZ**:
|
|
10
|
+
- Short-lived JWT access tokens + refresh token rotation, or session cookies with `httpOnly`, `secure`, `sameSite`.
|
|
11
|
+
- Passwords hashed with `bcrypt`/`argon2`, never stored or logged in plaintext.
|
|
12
|
+
- Role/permission checks live in middleware, applied per-route, not scattered inside controller `if` statements.
|
|
13
|
+
- **Secrets**: only via environment variables / a secrets manager. Never commit `.env`, never hardcode API keys or DB credentials.
|
|
14
|
+
- **Request limits**: `express.json({ limit: '10kb' })` (or an appropriate cap) to prevent payload-based DoS.
|
|
15
|
+
- **Dependency hygiene**: run `npm audit` (or Snyk/Dependabot) as part of CI; block merges on high/critical vulnerabilities.
|
|
16
|
+
- **HTTPS only** in production; redirect HTTP → HTTPS at the load balancer/proxy layer.
|
|
17
|
+
- Never leak stack traces, internal file paths, or library versions in API responses or headers.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Database & Model Standards
|
|
2
|
+
|
|
3
|
+
- **Repository pattern**: all DB queries live in `repositories/`, never directly inside services or controllers. Services call repository methods; they don't know it's Postgres/Mongo/etc.
|
|
4
|
+
- **Migrations are mandatory** for schema changes (e.g. `knex`, `sequelize-cli`, `prisma migrate`, `typeorm migration`). Never use `sync({ alter: true })` or manual schema edits against a shared/production DB.
|
|
5
|
+
- Every table/collection gets `createdAt` and `updatedAt` timestamps by default.
|
|
6
|
+
- Prefer **soft deletes** (`deletedAt` column + default query scope excluding it) over hard deletes for user-facing/business-critical records; hard-delete only where there's a clear compliance/retention reason.
|
|
7
|
+
- Index every foreign key and every column used in a frequent `WHERE`/`sort` — check the query plan (`EXPLAIN`) for anything added to a hot path.
|
|
8
|
+
- **Transactions** wrap any operation that writes to more than one table/collection, so a partial failure can't leave data inconsistent.
|
|
9
|
+
- Naming: `snake_case` for DB columns/tables, `camelCase` in JS — handle the mapping in the ORM config, don't hand-convert per query.
|
|
10
|
+
- Never return raw ORM model instances straight from a controller — map to a DTO/serializer so DB shape and API shape can evolve independently.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Testing Standards
|
|
2
|
+
|
|
3
|
+
- **Unit tests** (Jest/Vitest) for every service function — mock the repository layer, test business logic in isolation.
|
|
4
|
+
- **Integration tests** (Supertest against the exported `app.js`, not a running server) for every route — exercise the real middleware chain, validation, and error handler.
|
|
5
|
+
- Use a dedicated test database (or transactional rollback per test) — tests must never touch dev/prod data, and must be safely re-runnable/parallelizable.
|
|
6
|
+
- Follow **Arrange–Act–Assert** structure in every test; one logical assertion focus per test case.
|
|
7
|
+
- Mock external services/network calls (payment providers, email, third-party APIs) — tests must not depend on network access.
|
|
8
|
+
- Minimum coverage threshold: **80%** on services and controllers, enforced in CI (fail the build below threshold).
|
|
9
|
+
- Every new endpoint or model ships with at least: one happy-path integration test, one validation-failure test, one auth-failure test (if protected).
|
|
10
|
+
- CI must run lint → unit → integration → coverage gate, in that order, before a PR can merge.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Checklist: Before Creating Any New Model, Route, or Component
|
|
2
|
+
|
|
3
|
+
Run through this before writing code for a new feature — this is what a senior architect reviews for in a PR:
|
|
4
|
+
|
|
5
|
+
1. **Check for an existing pattern first.** Look at a similar existing model/route/service in the codebase and follow its shape — don't introduce a new pattern for something that already has one.
|
|
6
|
+
2. **Confirm the layer boundaries**: route (wiring only) → validator (schema) → controller (HTTP glue) → service (logic) → repository (DB) → model. No shortcuts (e.g. controller querying the DB directly).
|
|
7
|
+
3. **Write the validation schema** for every input (body/params/query) before writing the controller.
|
|
8
|
+
4. **Define the DB migration** (not a live schema edit) if a new table/column is needed, with indexes on any FK/frequently-queried column.
|
|
9
|
+
5. **Handle errors explicitly**: use `AppError`/`catchAsync`, no bare `try/catch` with silent `console.log`.
|
|
10
|
+
6. **Add authorization checks** if the resource is user/role-scoped — don't rely on the client to hide UI for unauthorized actions.
|
|
11
|
+
7. **Write tests**: at minimum one integration test (happy path) and one validation/error-path test.
|
|
12
|
+
8. **Update API documentation** (OpenAPI/Swagger) for any new or changed endpoint.
|
|
13
|
+
9. **Run lint + format** (ESLint + Prettier) — no new lint warnings introduced.
|
|
14
|
+
10. **No secrets, no hardcoded config** — anything environment-specific goes through `config/`.
|
|
15
|
+
11. **Consider pagination/rate-limits** if it's a list endpoint or public-facing.
|
|
16
|
+
12. Keep the diff focused — one feature/concern per PR/commit.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# General Code Style Standards
|
|
2
|
+
|
|
3
|
+
- `async/await` everywhere; no mixing with raw `.then()` chains or callback-style APIs in new code.
|
|
4
|
+
- No `console.log` in committed code — use a structured logger (`pino` or `winston`) with log levels, and include a request/correlation id in every log line.
|
|
5
|
+
- One export/responsibility per file; avoid god-files that mix routing, business logic, and DB access.
|
|
6
|
+
- Environment-based configuration only (`dotenv` + a validated config schema) — never branch behavior on `NODE_ENV` scattered through business logic; centralize environment differences in `config/`.
|
|
7
|
+
- Commit messages follow Conventional Commits (`feat:`, `fix:`, `refactor:`, `test:`, `chore:`) so history and changelogs stay meaningful.
|
|
8
|
+
- Prefer explicit, readable code over clever one-liners — this codebase is read far more often than it's written.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Ruby on Rails Standards — Skills Pack
|
|
2
|
+
|
|
3
|
+
Standards for professional Rails backend work, built around one core idea: **match this specific
|
|
4
|
+
codebase's existing conventions instead of assuming a generic stack.** It's designed for editing
|
|
5
|
+
and extending existing Rails apps as much as for greenfield work — most real tasks are the former.
|
|
6
|
+
|
|
7
|
+
## What's inside
|
|
8
|
+
|
|
9
|
+
- **`shared-reference/`** — the master content: one condensed cheat sheet (`00-quick-scaffold.md`)
|
|
10
|
+
plus 8 full topic files. Source of truth; the other three folders repackage this into each
|
|
11
|
+
tool's native format.
|
|
12
|
+
- **`cursor/.cursor/rules/`** — Cursor `.mdc` rule files.
|
|
13
|
+
- **`claude-code/.claude/skills/rails-standards/`** — a Claude Code Skill (`SKILL.md` + `references/`).
|
|
14
|
+
- **`antigravity/.agents/skills/rails-standards/`** — an Antigravity Skill, same `SKILL.md` format.
|
|
15
|
+
|
|
16
|
+
## Detect → match → ask, not "use Pundit / use Blueprinter"
|
|
17
|
+
|
|
18
|
+
Earlier drafts of this pack hard-coded specific gems (Pundit for auth, Blueprinter for
|
|
19
|
+
serialization, etc.), which is wrong for a codebase that already made a different choice — plenty
|
|
20
|
+
of real apps use CanCanCan, jsonapi-rb, Jbuilder, or something custom. This version doesn't assume:
|
|
21
|
+
|
|
22
|
+
1. **Graceful search, not a full scan.** Before writing anything, read `Gemfile`/`Gemfile.lock`
|
|
23
|
+
once, and open **one** existing file of the same kind near where you're adding code (one
|
|
24
|
+
controller, one model, one spec). That's enough to detect the convention — no need to scan the
|
|
25
|
+
whole `app/` tree.
|
|
26
|
+
2. **If a convention is detectable, follow it, no need to ask** — Gemfile + one real example
|
|
27
|
+
agreeing is a detected fact, not a guess.
|
|
28
|
+
3. **If a real architectural choice isn't detectable and matters for the task, ask a single
|
|
29
|
+
question with the common options** instead of silently picking one. The trigger list (in
|
|
30
|
+
`00-quick-scaffold.md` and `SKILL.md`) covers: authorization library, serialization approach,
|
|
31
|
+
pagination, background jobs, soft-delete strategy, test framework, rate limiting, API
|
|
32
|
+
versioning.
|
|
33
|
+
4. **Never skip looking at existing code when the codebase is non-empty.** Writing from a generic
|
|
34
|
+
template while ignoring what's already there is the specific failure mode this pack is built to
|
|
35
|
+
prevent.
|
|
36
|
+
|
|
37
|
+
Every reference file (`01`–`08`) follows this same pattern: hold the things that are genuinely
|
|
38
|
+
non-negotiable regardless of gem choice (strong params, parameterized queries, migrations over
|
|
39
|
+
schema edits), and explicitly defer everything else to "detect it / match it / ask if it's not
|
|
40
|
+
there."
|
|
41
|
+
|
|
42
|
+
## Built to minimize token usage during scaffolding
|
|
43
|
+
|
|
44
|
+
Same three-layer design used throughout this pack:
|
|
45
|
+
|
|
46
|
+
1. **A tiny always-on baseline** (~200 words) — the detect/match/ask instruction, restraint
|
|
47
|
+
principle, and layering, present in every request.
|
|
48
|
+
2. **One condensed cheat sheet** (`00-quick-scaffold.md`) — the default file for scaffolding
|
|
49
|
+
something new, instead of loading several full references.
|
|
50
|
+
3. **Full topic references** (`01`–`08`), scoped to load only when actually relevant.
|
|
51
|
+
|
|
52
|
+
## Built to prevent AI over-generation on small changes
|
|
53
|
+
|
|
54
|
+
- No unrelated refactors "while I'm here," no speculative abstractions for requirements that
|
|
55
|
+
weren't asked for (YAGNI), no scaffolding beyond what the task needs.
|
|
56
|
+
- Prefer a small edit to an existing file over generating a new file/class to avoid it.
|
|
57
|
+
- **Comments**: short, explain *why* not *what*, only where the code isn't already self-evident,
|
|
58
|
+
matched to the existing codebase's comment density rather than a fixed rule of "comment
|
|
59
|
+
everything."
|
|
60
|
+
|
|
61
|
+
## How to install per tool
|
|
62
|
+
|
|
63
|
+
### Cursor
|
|
64
|
+
Copy `cursor/.cursor/` into your project root → `your-project/.cursor/rules/*.mdc`.
|
|
65
|
+
- `00-always-on.mdc` is the only always-applied rule (~200 words).
|
|
66
|
+
- `01`, `02`, `03`, `05`, `06` auto-attach based on the file glob you're editing.
|
|
67
|
+
- `04-security.mdc` and `08-code-style.mdc` are full detail, loaded on request.
|
|
68
|
+
- `09-quick-scaffold.mdc` is the one to reach for when creating something new.
|
|
69
|
+
- `07-new-component-checklist.mdc` is the fuller, manual-only checklist — `@07-new-component-checklist`.
|
|
70
|
+
|
|
71
|
+
### Claude Code
|
|
72
|
+
Copy `claude-code/.claude/` into your project root (or `~/.claude/` for global) →
|
|
73
|
+
`your-project/.claude/skills/rails-standards/SKILL.md`. Discovered automatically, or invoke
|
|
74
|
+
explicitly: *"Follow the rails-standards skill — check how we already handle authorization before
|
|
75
|
+
adding this."*
|
|
76
|
+
|
|
77
|
+
### Antigravity
|
|
78
|
+
Copy `antigravity/.agents/` into your project root (or `~/.gemini/config/skills/` for global) →
|
|
79
|
+
`your-project/.agents/skills/rails-standards/SKILL.md`. Same behavior as Claude Code above; check
|
|
80
|
+
with `/skills` if unsure it loaded.
|
|
81
|
+
|
|
82
|
+
## Editing the standards
|
|
83
|
+
|
|
84
|
+
Treat `shared-reference/` as the source of truth. If you update a rule there, copy the change into
|
|
85
|
+
the corresponding `cursor/*.mdc` file and into both `references/` copies under `claude-code/` and
|
|
86
|
+
`antigravity/` so all three tools stay in sync.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rails-standards
|
|
3
|
+
description: Standards for Ruby on Rails backend work that detect and match THIS codebase's existing conventions (auth library, serialization approach, project structure, error handling, tests) rather than assuming a generic stack, and ask a clarifying question when a real architectural choice can't be detected. Use this skill whenever creating, editing, or reviewing any Rails model, controller, service, migration, or API endpoint, or before scaffolding any new module/component, even if the user doesn't explicitly ask for "standards" or "best practices."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Rails Standards
|
|
7
|
+
|
|
8
|
+
This skill's job is to make new code look like it was written by the same person who wrote the
|
|
9
|
+
rest of the codebase — not to impose a generic "senior architect" stack on top of it. Detecting
|
|
10
|
+
and matching existing conventions is the primary behavior; the reference files below are fallback
|
|
11
|
+
guidance for when no existing convention is detectable.
|
|
12
|
+
|
|
13
|
+
## Detect → match → ask (do this before writing code, every time)
|
|
14
|
+
|
|
15
|
+
1. **Graceful search, not a full scan.** Read `Gemfile`/`Gemfile.lock` once for the relevant gem
|
|
16
|
+
category. That's it for step 1 — don't grep the whole repo.
|
|
17
|
+
2. Open **one** existing file of the same kind near where you're adding code (one controller, one
|
|
18
|
+
model, one spec) and mirror its structure, naming, error handling, and comment density.
|
|
19
|
+
3. If Gemfile + the example agree, use that — it's detected, not assumed.
|
|
20
|
+
4. **If nothing exists to detect from and the choice materially affects the code** (authorization
|
|
21
|
+
library, serialization approach, pagination, background jobs, soft-delete strategy, test
|
|
22
|
+
framework, rate limiting, API versioning) — **ask one question with the common options** rather
|
|
23
|
+
than silently defaulting to a specific gem.
|
|
24
|
+
5. Never skip step 2 when the codebase is non-empty — overlooking existing code and writing from a
|
|
25
|
+
generic template is the failure mode this skill exists to prevent.
|
|
26
|
+
|
|
27
|
+
## Token discipline — read this before opening any reference file
|
|
28
|
+
|
|
29
|
+
- **New model / controller / service / endpoint** → after doing the detect-match-ask steps above,
|
|
30
|
+
read **only** `references/00-quick-scaffold.md` for anything not resolved by what you found.
|
|
31
|
+
- **Deep dive on one specific concern** → read the one matching full reference file, not the
|
|
32
|
+
others.
|
|
33
|
+
- **Full audit / reviewing an existing large PR** → the only case that justifies reading
|
|
34
|
+
multiple/all reference files.
|
|
35
|
+
|
|
36
|
+
| Task involves... | Read |
|
|
37
|
+
|--------------------------------------------|------------------------------------------------|
|
|
38
|
+
| Scaffolding anything new (default case) | `references/00-quick-scaffold.md` **(start here)** |
|
|
39
|
+
| Deep dive: overall app layout | `references/01-project-structure.md` |
|
|
40
|
+
| Deep dive: routes/controllers/serializers | `references/02-api-design-standards.md` |
|
|
41
|
+
| Deep dive: error handling/validation | `references/03-error-handling-validation.md` |
|
|
42
|
+
| Deep dive: auth/security | `references/04-security-standards.md` |
|
|
43
|
+
| Deep dive: models/migrations/query objects | `references/05-database-model-standards.md` |
|
|
44
|
+
| Deep dive: tests | `references/06-testing-standards.md` |
|
|
45
|
+
| Full pre-scaffold checklist (verbose form) | `references/07-new-component-checklist.md` |
|
|
46
|
+
| Deep dive: style/restraint/comments | `references/08-code-style-general.md` |
|
|
47
|
+
|
|
48
|
+
## Core non-negotiables (apply even without reading further)
|
|
49
|
+
|
|
50
|
+
- Detect and match existing conventions before applying any generic default; ask rather than
|
|
51
|
+
assume when a real architectural choice isn't detectable.
|
|
52
|
+
- No business logic in controllers or views; strong params on every write action.
|
|
53
|
+
- Every error flows through whatever centralized error-handling pattern the codebase already has
|
|
54
|
+
(or a `rescue_from` chain if none exists — flagged as new).
|
|
55
|
+
- **Restraint, always**: make the smallest correct change for the task asked. No speculative
|
|
56
|
+
abstractions, no unrelated refactors, no scaffolding beyond what's needed. Comments are short,
|
|
57
|
+
explain *why* not *what*, and only appear where the code isn't already self-evident.
|
|
58
|
+
|
|
59
|
+
## Workflow for a new feature (token-efficient path)
|
|
60
|
+
|
|
61
|
+
1. Do the detect → match → ask steps above.
|
|
62
|
+
2. Read `references/00-quick-scaffold.md` for anything the detection step didn't resolve.
|
|
63
|
+
3. Only pull in a full reference file if the quick-scaffold section on that topic isn't detailed
|
|
64
|
+
enough, or the task is a deep dive on one area.
|
|
65
|
+
4. Write the smallest diff that satisfies the task; run whatever lint/static-analysis tools are
|
|
66
|
+
already configured before considering it done.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Quick Scaffold Cheat Sheet — New Model / Controller / Service (Rails)
|
|
2
|
+
|
|
3
|
+
Read this file first for "create/add a new X" tasks — it's the condensed version of the full pack.
|
|
4
|
+
|
|
5
|
+
## 0. Understand before you write (always — this is the point of this skill)
|
|
6
|
+
|
|
7
|
+
This skill exists to match how **this specific codebase** already writes code, not to impose a
|
|
8
|
+
generic opinion or assume a from-scratch build. Before writing anything:
|
|
9
|
+
|
|
10
|
+
1. **Graceful search, not a full scan.** Read `Gemfile`/`Gemfile.lock` once (one file) for the
|
|
11
|
+
relevant gem category (auth, serialization, pagination, jobs, testing).
|
|
12
|
+
2. Open **one** existing file of the same kind, near where you're adding code (one existing
|
|
13
|
+
controller, one existing model, one existing spec). Mimic its structure, naming, error-handling
|
|
14
|
+
shape, and comment density. One representative example is enough — don't scan the whole `app/`
|
|
15
|
+
tree.
|
|
16
|
+
3. If Gemfile + the example file agree on an approach, **use it, don't ask** — that's a detected
|
|
17
|
+
convention, not a guess.
|
|
18
|
+
4. **If there's no existing example and the choice materially affects the code, ask one question
|
|
19
|
+
with the common options** — don't silently default to "the popular gem" as if it were a rule.
|
|
20
|
+
5. Low-stakes style details (indentation, private-method order) — just mirror the nearest file, no
|
|
21
|
+
need to ask.
|
|
22
|
+
|
|
23
|
+
### Ask, don't assume, when these aren't already evident in the codebase:
|
|
24
|
+
- Authorization (Pundit / CanCanCan / custom / none)
|
|
25
|
+
- Response/serialization approach (Blueprinter / ActiveModel::Serializer / jsonapi-rb / Jbuilder / plain `as_json`)
|
|
26
|
+
- Pagination (Kaminari / Pagy / will_paginate / none needed)
|
|
27
|
+
- Background jobs (Sidekiq / plain ActiveJob / Resque / none needed)
|
|
28
|
+
- Soft delete vs hard delete, and which gem if soft
|
|
29
|
+
- Test framework (RSpec / Minitest) — usually obvious from `spec/` vs `test/`, confirm if not
|
|
30
|
+
- Rate limiting (rack-attack / none needed)
|
|
31
|
+
- API versioning scheme, if this is the first versioned endpoint
|
|
32
|
+
|
|
33
|
+
## 1. Layering (holds regardless of gem choices)
|
|
34
|
+
|
|
35
|
+
model (persistence/validation) → form object (if the codebase uses one) → service/business logic
|
|
36
|
+
(wherever it already lives) → query object (if in use) → controller (auth → authorize → delegate
|
|
37
|
+
→ render) → whatever serialization approach was detected in step 0.
|
|
38
|
+
|
|
39
|
+
## 2. API shape
|
|
40
|
+
|
|
41
|
+
If endpoints already exist, copy the established response envelope / status-code pattern / error
|
|
42
|
+
shape exactly, even over a "more standard" alternative — consistency wins. Only fall back to
|
|
43
|
+
generic REST conventions if this is genuinely the first endpoint of its kind, and say so.
|
|
44
|
+
|
|
45
|
+
## 3. Validation + errors
|
|
46
|
+
|
|
47
|
+
Match the existing `rescue_from`/error-class pattern if one exists. If none exists yet, a central
|
|
48
|
+
`rescue_from` chain with typed errors is a reasonable default to introduce — but flag that it's a
|
|
49
|
+
new cross-cutting pattern, since it affects every controller.
|
|
50
|
+
|
|
51
|
+
## 4. Security (non-negotiable regardless of which gems are chosen)
|
|
52
|
+
|
|
53
|
+
Strong params on every write action. Parameterized queries only, never string-interpolated SQL.
|
|
54
|
+
Secrets via Rails credentials/ENV, never hardcoded. Authorization checked using whichever library
|
|
55
|
+
is detected (or ask, per step 0, if none is set up).
|
|
56
|
+
|
|
57
|
+
## 5. Database/model
|
|
58
|
+
|
|
59
|
+
New column/table → a migration with DB-level constraints + indexes on FKs and hot query columns.
|
|
60
|
+
Avoid N+1 (`includes`/`preload`) on associations touched in a loop or the serialization layer.
|
|
61
|
+
Multi-table writes wrapped in a transaction.
|
|
62
|
+
|
|
63
|
+
## 6. Tests
|
|
64
|
+
|
|
65
|
+
Match the existing test style (framework, factories vs fixtures) exactly. Minimum bar for new
|
|
66
|
+
code: one happy-path test, one validation/error-path test, one auth-failure test if protected.
|
|
67
|
+
|
|
68
|
+
## 7. Restraint (applies to every task, especially small ones)
|
|
69
|
+
|
|
70
|
+
Make the smallest correct change. No unrelated refactors, no speculative abstractions, no
|
|
71
|
+
scaffolding beyond what was asked. Comments are short, explain *why* not *what*, and only appear
|
|
72
|
+
where the code isn't already self-evident.
|
|
73
|
+
|
|
74
|
+
## 8. Before you call it done
|
|
75
|
+
|
|
76
|
+
Whatever lint tool the codebase already uses, run it clean → no hardcoded secrets → pagination on
|
|
77
|
+
new index actions if the codebase paginates elsewhere → N+1 checked → diff scoped to exactly this
|
|
78
|
+
task.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
Need more depth? `01-project-structure.md`, `02-api-design-standards.md`,
|
|
82
|
+
`03-error-handling-validation.md`, `04-security-standards.md`, `05-database-model-standards.md`,
|
|
83
|
+
`06-testing-standards.md`, `07-new-component-checklist.md`, `08-code-style-general.md`.
|