Add new skills for backend patterns, coding standards, continuous learning, and NestJS best practices
- Introduced backend patterns skill with guidelines on API design, database optimization, and server-side best practices. - Added coding standards skill outlining universal coding principles for TypeScript, NestJS, and Node.js development. - Implemented continuous learning skill to automatically extract reusable patterns from Cursor sessions. - Created NestJS best practices skill detailing architecture patterns, dependency injection, error handling, and security measures. - Included various rules and templates for NestJS best practices to ensure production-ready applications.
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
---
|
||||
description: When to use planner, architect, tdd-guide, code-reviewer, and other agents; parallel Task execution
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# Agent Orchestration
|
||||
|
||||
## Layout
|
||||
|
||||
- Agents: `.cursor/agents/`
|
||||
- Skills: `.agents/skills/`
|
||||
- Rules: `.cursor/rules/`
|
||||
- Hooks: `.cursor/hooks.json` and `.cursor/hooks/`
|
||||
|
||||
## Available Agents
|
||||
|
||||
| Agent | Purpose | When to Use |
|
||||
| -------------------- | ----------------------- | ----------------------------- |
|
||||
| planner | Implementation planning | Complex features, refactoring |
|
||||
| architect | System design | Architectural decisions |
|
||||
| tdd-guide | Test-driven development | New features, bug fixes |
|
||||
| code-reviewer | Code review | After writing code |
|
||||
| security-reviewer | Security analysis | Before commits |
|
||||
| build-error-resolver | Fix build errors | When build fails |
|
||||
| e2e-runner | NestJS E2E testing | Critical API flows |
|
||||
| refactor-cleaner | Dead code cleanup | Code maintenance |
|
||||
| doc-updater | Documentation | Updating docs |
|
||||
|
||||
## Immediate Agent Usage
|
||||
|
||||
No user prompt needed:
|
||||
|
||||
1. Complex feature requests - Use **planner** agent
|
||||
2. Code just written/modified - Use **code-reviewer** agent
|
||||
3. Bug fix or new feature - Use **tdd-guide** agent
|
||||
4. Architectural decision - Use **architect** agent
|
||||
|
||||
## Parallel Task Execution
|
||||
|
||||
ALWAYS use parallel Task execution for independent operations:
|
||||
|
||||
```markdown
|
||||
# GOOD: Parallel execution
|
||||
|
||||
Launch 3 agents in parallel:
|
||||
|
||||
1. Agent 1: Security analysis of auth.ts
|
||||
2. Agent 2: Performance review of cache system
|
||||
3. Agent 3: Type checking of utils.ts
|
||||
|
||||
# BAD: Sequential when unnecessary
|
||||
|
||||
First agent 1, then agent 2, then agent 3
|
||||
```
|
||||
|
||||
## Multi-Perspective Analysis
|
||||
|
||||
For complex problems, use split role sub-agents:
|
||||
|
||||
- Factual reviewer
|
||||
- Senior engineer
|
||||
- Security expert
|
||||
- Consistency reviewer
|
||||
- Redundancy checker
|
||||
@@ -0,0 +1,76 @@
|
||||
---
|
||||
description: Immutability, file organization, error handling, and input validation
|
||||
globs: "**/*.{ts,tsx,js,jsx}"
|
||||
alwaysApply: false
|
||||
---
|
||||
|
||||
# Coding Style
|
||||
|
||||
## Immutability (CRITICAL)
|
||||
|
||||
ALWAYS create new objects, NEVER mutate:
|
||||
|
||||
```javascript
|
||||
// WRONG: Mutation
|
||||
function updateUser(user, name) {
|
||||
user.name = name // MUTATION!
|
||||
return user
|
||||
}
|
||||
|
||||
// CORRECT: Immutability
|
||||
function updateUser(user, name) {
|
||||
return {
|
||||
...user,
|
||||
name
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## File Organization
|
||||
|
||||
MANY SMALL FILES > FEW LARGE FILES:
|
||||
- High cohesion, low coupling
|
||||
- 200-400 lines typical, 800 max
|
||||
- Extract utilities from large components
|
||||
- Organize by feature/domain, not by type
|
||||
|
||||
## Error Handling
|
||||
|
||||
ALWAYS handle errors comprehensively:
|
||||
|
||||
```typescript
|
||||
try {
|
||||
const result = await riskyOperation()
|
||||
return result
|
||||
} catch (error) {
|
||||
console.error('Operation failed:', error)
|
||||
throw new Error('Detailed user-friendly message')
|
||||
}
|
||||
```
|
||||
|
||||
## Input Validation
|
||||
|
||||
ALWAYS validate user input with class-validator DTOs (and Zod where DTOs are not used):
|
||||
|
||||
```typescript
|
||||
import { z } from 'zod'
|
||||
|
||||
const schema = z.object({
|
||||
email: z.string().email(),
|
||||
age: z.number().int().min(0).max(150)
|
||||
})
|
||||
|
||||
const validated = schema.parse(input)
|
||||
```
|
||||
|
||||
## Code Quality Checklist
|
||||
|
||||
Before marking work complete:
|
||||
- [ ] Code is readable and well-named
|
||||
- [ ] Functions are small (<50 lines)
|
||||
- [ ] Files are focused (<800 lines)
|
||||
- [ ] No deep nesting (>4 levels)
|
||||
- [ ] Proper error handling
|
||||
- [ ] No console.log statements
|
||||
- [ ] No hardcoded values
|
||||
- [ ] No mutation (immutable patterns used)
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
description: All date-related data must use DateTime; never add parallel date files or helpers — extend the VO instead
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# DateTime Value Object
|
||||
|
||||
## Mandatory
|
||||
|
||||
ALL data related to dates or date-times in the domain and application layers MUST use `DateTime` from `src/common/value-objects/date-time/`.
|
||||
|
||||
- Construct from HTTP ISO via `DateTime.create(raw)`
|
||||
- Reconstruct from DB via `DateTime.fromUnixMs(ms)`
|
||||
- Compare with `equals()`, persist with `value` / `toJSON()` (unix **milliseconds**, UTC instant)
|
||||
- Render with `format()` / `toString()` using `DEFAULT_TIMEZONE` (default `GMT+7`) — timezone is for display and naive ISO interpretation only
|
||||
|
||||
There is one date abstraction in this codebase: `DateTime`. Use it for every timestamp, occurrence, schedule instant, created/updated field, and any other date-related value in domain/application code.
|
||||
|
||||
## Forbidden
|
||||
|
||||
Do NOT:
|
||||
|
||||
- Store or pass date-times as plain `string` / `number` / built-in `Date` in domain models, services, or repositories (beyond the DTO/HTTP or DB number boundary)
|
||||
- Create **any** new file or function for date parsing, validation, formatting, timezone conversion, or comparison
|
||||
- Add pipes, decorators, utils, helpers, or modules that bypass the VO
|
||||
- Use date libraries (`date-fns`, `luxon`, `moment`, `dayjs`, Temporal polyfills, etc.)
|
||||
|
||||
```typescript
|
||||
// BAD — new helper / parallel logic
|
||||
function parseDate(raw: string): number { /* ... */ }
|
||||
function formatDate(ms: number): string { /* ... */ }
|
||||
user.occurredAt = Date.parse(dto.occurredAt)
|
||||
|
||||
// GOOD — DateTime only
|
||||
const occurredAt = DateTime.create(dto.occurredAt)
|
||||
user.occurredAt = occurredAt // DateTime in domain
|
||||
await repo.save({ occurredAt: occurredAt.value }) // unix ms only at persistence edge
|
||||
```
|
||||
|
||||
## When the VO is not enough
|
||||
|
||||
If a requirement cannot be met with the current VO (e.g. new input formats, formatting options, comparisons, timezone forms):
|
||||
|
||||
1. **Update** `src/common/value-objects/date-time/` (implementation + colocated tests) to match the requirement
|
||||
2. Do **not** create a new file, function, type, helper, or module for dates
|
||||
|
||||
## Boundaries
|
||||
|
||||
- HTTP DTOs may accept ISO `string`; map to `DateTime.create()` at the service boundary
|
||||
- Database columns may store unix milliseconds (`bigint` / integer); map to/from `DateTime` in the repository
|
||||
- Naive ISO strings (no `Z` / offset) are interpreted in `DEFAULT_TIMEZONE`
|
||||
- `InvalidDateTimeError` is the only date validation error; do not echo raw input in messages
|
||||
- Canonical storage is always UTC; never persist the display timezone as the instant
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
description: Commit message format, PR workflow, and feature implementation steps
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# Git Workflow
|
||||
|
||||
## Commit Message Format
|
||||
|
||||
```
|
||||
<type>: <description>
|
||||
|
||||
<optional body>
|
||||
```
|
||||
|
||||
Types: feat, fix, refactor, docs, test, chore, perf, ci
|
||||
|
||||
Keep commit messages conventional. Do not add AI attribution trailers.
|
||||
|
||||
## Pull Request Workflow
|
||||
|
||||
When creating PRs:
|
||||
1. Analyze full commit history (not just latest commit)
|
||||
2. Use `git diff [base-branch]...HEAD` to see all changes
|
||||
3. Draft comprehensive PR summary
|
||||
4. Include test plan with TODOs
|
||||
5. Push with `-u` flag if new branch
|
||||
|
||||
## Feature Implementation Workflow
|
||||
|
||||
1. **Plan First**
|
||||
- Use **planner** agent to create implementation plan
|
||||
- Identify dependencies and risks
|
||||
- Break down into phases
|
||||
|
||||
2. **TDD Approach**
|
||||
- Use **tdd-guide** agent
|
||||
- Write tests first (RED)
|
||||
- Implement to pass tests (GREEN)
|
||||
- Refactor (IMPROVE)
|
||||
- Verify 80%+ coverage
|
||||
|
||||
3. **Code Review**
|
||||
- Use **code-reviewer** agent immediately after writing code
|
||||
- Address CRITICAL and HIGH issues
|
||||
- Fix MEDIUM issues when possible
|
||||
|
||||
4. **Commit & Push**
|
||||
- Detailed commit messages
|
||||
- Follow conventional commits format
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
description: Cursor hooks system, auto-accept permissions, and TodoWrite practices
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# Hooks System
|
||||
|
||||
Project hooks live in `.cursor/hooks.json` (schema version 1) and scripts under `.cursor/hooks/` and `.cursor/scripts/hooks/`.
|
||||
|
||||
## Hook Events
|
||||
|
||||
- **sessionStart / sessionEnd**: Load and persist session context
|
||||
- **preCompact**: Save state before context compaction
|
||||
- **afterFileEdit**: Suggest strategic compact after edits
|
||||
- **beforeShellExecution**: Gate long-running servers and `git push`
|
||||
|
||||
## Current Project Hooks
|
||||
|
||||
### sessionStart
|
||||
- Load previous session files from `.cursor/sessions/`
|
||||
- Detect package manager
|
||||
- Report learned skills in `.agents/skills/learned/`
|
||||
|
||||
### sessionEnd
|
||||
- Persist session state
|
||||
- Evaluate the session for extractable patterns
|
||||
|
||||
### preCompact
|
||||
- Log compaction and append a note to the active session file
|
||||
|
||||
### afterFileEdit
|
||||
- Suggest manual compaction after many edits
|
||||
|
||||
### beforeShellExecution
|
||||
- Ask before running dev servers outside tmux
|
||||
- Ask before `git push`
|
||||
|
||||
## Auto-Accept Permissions
|
||||
|
||||
Use with caution:
|
||||
- Enable for trusted, well-defined plans
|
||||
- Disable for exploratory work
|
||||
- Never skip permissions for git push, installs, or production commands
|
||||
|
||||
## TodoWrite Best Practices
|
||||
|
||||
Use TodoWrite to:
|
||||
- Track progress on multi-step tasks
|
||||
- Verify understanding of instructions
|
||||
- Show granular implementation steps
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
description: NestJS modular TDD structure with Drizzle and PostgreSQL
|
||||
globs: "**/*.{ts,js}"
|
||||
alwaysApply: false
|
||||
---
|
||||
|
||||
# NestJS Project Conventions
|
||||
|
||||
Stack: NestJS + PostgreSQL + Drizzle ORM. Follow `.agents/skills/nestjs-best-practices` and `.agents/skills/project-guidelines-example`.
|
||||
|
||||
## Modules
|
||||
|
||||
- One feature folder under `src/modules/`
|
||||
- Each feature has `*.module.ts`, `*.controller.ts`, `*.service.ts`, `dto/`
|
||||
- Share cross-cutting code via `src/common/` (filters, guards, pipes, interceptors)
|
||||
|
||||
## Tests
|
||||
|
||||
- Unit tests colocated as `*.spec.ts`
|
||||
- E2E tests in `test/*.e2e-spec.ts` with Supertest
|
||||
- Write tests first (RED → GREEN → REFACTOR)
|
||||
- Mock Drizzle and external services, not Nest internals
|
||||
|
||||
## Database
|
||||
|
||||
- Schema and SQL migrations in `drizzle/`
|
||||
- Config in `drizzle.config.ts`
|
||||
- Never mutate production schema without a migration
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
description: NestJS API response format, feature modules, and Drizzle repository pattern
|
||||
globs: "**/*.ts"
|
||||
alwaysApply: false
|
||||
---
|
||||
|
||||
# Common Patterns
|
||||
|
||||
## API Response Format
|
||||
|
||||
```typescript
|
||||
interface ApiResponse<T> {
|
||||
success: boolean
|
||||
data?: T
|
||||
error?: string
|
||||
meta?: {
|
||||
total: number
|
||||
page: number
|
||||
limit: number
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Feature Module
|
||||
|
||||
```typescript
|
||||
@Module({
|
||||
imports: [],
|
||||
controllers: [UsersController],
|
||||
providers: [UsersService, UsersRepository],
|
||||
exports: [UsersService],
|
||||
})
|
||||
export class UsersModule {}
|
||||
```
|
||||
|
||||
## Repository Pattern (Drizzle)
|
||||
|
||||
```typescript
|
||||
interface Repository<T> {
|
||||
findAll(filters?: Filters): Promise<T[]>
|
||||
findById(id: string): Promise<T | null>
|
||||
create(data: CreateDto): Promise<T>
|
||||
update(id: string, data: UpdateDto): Promise<T>
|
||||
delete(id: string): Promise<void>
|
||||
}
|
||||
```
|
||||
|
||||
## Skeleton Projects
|
||||
|
||||
When implementing new functionality:
|
||||
1. Search for battle-tested NestJS module patterns
|
||||
2. Use parallel agents to evaluate options:
|
||||
- Security assessment
|
||||
- Extensibility analysis
|
||||
- Relevance scoring
|
||||
- Implementation planning
|
||||
3. Clone best match as foundation
|
||||
4. Iterate within proven structure
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
description: Model selection, context window management, and build troubleshooting
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# Performance Optimization
|
||||
|
||||
## Model Selection Strategy
|
||||
|
||||
**Haiku 4.5** (90% of Sonnet capability, 3x cost savings):
|
||||
- Lightweight agents with frequent invocation
|
||||
- Pair programming and code generation
|
||||
- Worker agents in multi-agent systems
|
||||
|
||||
**Sonnet 4.5** (Best coding model):
|
||||
- Main development work
|
||||
- Orchestrating multi-agent workflows
|
||||
- Complex coding tasks
|
||||
|
||||
**Opus 4.5** (Deepest reasoning):
|
||||
- Complex architectural decisions
|
||||
- Maximum reasoning requirements
|
||||
- Research and analysis tasks
|
||||
|
||||
## Context Window Management
|
||||
|
||||
Avoid last 20% of context window for:
|
||||
- Large-scale refactoring
|
||||
- Feature implementation spanning multiple files
|
||||
- Debugging complex interactions
|
||||
|
||||
Lower context sensitivity tasks:
|
||||
- Single-file edits
|
||||
- Independent utility creation
|
||||
- Documentation updates
|
||||
- Simple bug fixes
|
||||
|
||||
## Ultrathink + Plan Mode
|
||||
|
||||
For complex tasks requiring deep reasoning:
|
||||
1. Use `ultrathink` for enhanced thinking
|
||||
2. Enable **Plan Mode** for structured approach
|
||||
3. "Rev the engine" with multiple critique rounds
|
||||
4. Use split role sub-agents for diverse analysis
|
||||
|
||||
## Build Troubleshooting
|
||||
|
||||
If build fails:
|
||||
1. Use **build-error-resolver** agent
|
||||
2. Analyze error messages
|
||||
3. Fix incrementally
|
||||
4. Verify after each fix
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
description: All phone-number data must use the PhoneNumber value object; extend the VO instead of adding alternate helpers
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# Phone Number Value Object
|
||||
|
||||
## Mandatory
|
||||
|
||||
ALL phone-number data in the domain and application layers MUST use `PhoneNumber` from `src/common/value-objects/phone-number/`.
|
||||
|
||||
- Construct only via `PhoneNumber.create(raw)`
|
||||
- Compare with `equals()`, serialize with `value` / `toString()` / `toJSON()`
|
||||
- Persist and transmit the canonical E.164 from `phone.value` (or `toString()` / `toJSON()`)
|
||||
|
||||
## Forbidden
|
||||
|
||||
Do NOT:
|
||||
|
||||
- Store or pass phone numbers as plain `string` / `number` in domain models, services, or repositories (beyond the DTO/HTTP or DB string boundary)
|
||||
- Add phone validators, parsers, formatters, regex helpers, pipes, or decorators that bypass the VO
|
||||
- Create new files or functions for phone-number validation or normalization
|
||||
- Use `libphonenumber-js` (or similar) outside the PhoneNumber VO
|
||||
|
||||
```typescript
|
||||
// BAD
|
||||
function normalizePhone(raw: string): string { /* ... */ }
|
||||
user.phone = '+6281234567890'
|
||||
|
||||
// GOOD
|
||||
const phone = PhoneNumber.create(dto.phone)
|
||||
user.phone = phone // PhoneNumber type in domain
|
||||
await repo.save({ phoneNumber: phone.value }) // E.164 string only at persistence edge
|
||||
```
|
||||
|
||||
## When the VO is not enough
|
||||
|
||||
If a requirement cannot be met with the current VO (e.g. national formats, default region, formatting for display):
|
||||
|
||||
1. **Update** `src/common/value-objects/phone-number/` (implementation + colocated tests)
|
||||
2. Do **not** invent a parallel phone helper, type, or module
|
||||
|
||||
## Boundaries
|
||||
|
||||
- HTTP DTOs may accept `string`; map to `PhoneNumber.create()` at the service boundary
|
||||
- Database columns may store E.164 `text`/`varchar`; map to/from `PhoneNumber` in the repository
|
||||
- `InvalidPhoneNumberError` is the only phone validation error; do not echo raw input in messages
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
description: Mandatory security checks, secret management, and security response protocol
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# Security Guidelines
|
||||
|
||||
## Mandatory Security Checks
|
||||
|
||||
Before ANY commit:
|
||||
- [ ] No hardcoded secrets (API keys, passwords, tokens)
|
||||
- [ ] All user inputs validated
|
||||
- [ ] SQL injection prevention (parameterized queries)
|
||||
- [ ] XSS prevention (sanitized HTML)
|
||||
- [ ] CSRF protection enabled
|
||||
- [ ] Authentication/authorization verified
|
||||
- [ ] Rate limiting on all endpoints
|
||||
- [ ] Error messages don't leak sensitive data
|
||||
|
||||
## Secret Management
|
||||
|
||||
```typescript
|
||||
// NEVER: Hardcoded secrets
|
||||
const apiKey = "sk-proj-xxxxx"
|
||||
|
||||
// ALWAYS: Environment variables
|
||||
const apiKey = process.env.OPENAI_API_KEY
|
||||
|
||||
if (!apiKey) {
|
||||
throw new Error('OPENAI_API_KEY not configured')
|
||||
}
|
||||
```
|
||||
|
||||
## Security Response Protocol
|
||||
|
||||
If security issue found:
|
||||
1. STOP immediately
|
||||
2. Use **security-reviewer** agent
|
||||
3. Fix CRITICAL issues before continuing
|
||||
4. Rotate any exposed secrets
|
||||
5. Review entire codebase for similar issues
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
description: TDD workflow, 80% coverage minimum, and NestJS unit/e2e requirements
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# Testing Requirements
|
||||
|
||||
## Minimum Test Coverage: 80%
|
||||
|
||||
Test Types (ALL required):
|
||||
1. **Unit Tests** - Services, guards, pipes, utilities (`*.spec.ts`)
|
||||
2. **Integration Tests** - NestJS testing module + Drizzle
|
||||
3. **E2E Tests** - HTTP flows with Supertest (`test/*.e2e-spec.ts`)
|
||||
|
||||
## Test-Driven Development
|
||||
|
||||
MANDATORY workflow:
|
||||
1. Write test first (RED)
|
||||
2. Run test - it should FAIL
|
||||
3. Write minimal implementation (GREEN)
|
||||
4. Run test - it should PASS
|
||||
5. Refactor (IMPROVE)
|
||||
6. Verify coverage (80%+)
|
||||
|
||||
## Troubleshooting Test Failures
|
||||
|
||||
1. Use **tdd-guide** agent
|
||||
2. Check test isolation
|
||||
3. Verify mocks are correct
|
||||
4. Fix implementation, not tests (unless tests are wrong)
|
||||
|
||||
## Agent Support
|
||||
|
||||
- **tdd-guide** - Use PROACTIVELY for new features, enforces write-tests-first
|
||||
- **e2e-runner** - NestJS E2E (Supertest) specialist
|
||||
- Skill: `.agents/skills/tdd-workflow/`
|
||||
Reference in New Issue
Block a user