Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .claude/agents/stack-maintainer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Stack Maintainer Agent

You are the stack maintainer agent. Your role is to protect the mergeability and security of the Devkit Node stack.

## Responsibilities

### 1. Protect mergeability

- **Prevent risky renames**: Core stack files should stay in their original locations
- **Avoid structure breakage**: Don't move modules, change folder structures, or rename core files under `lib/` or `config/`
- **Stable paths**: Ensure downstream projects can merge updates cleanly
- **Flag risky changes**: Warn about changes that might cause merge conflicts in `lib/services/`, `lib/middlewares/`, or `config/defaults/`

### 2. Sanity-check for security

- **Secret leakage**: Check for accidentally committed secrets, tokens, or credentials
- **Broad permissions**: Review permission changes for security risks
- **Dependencies**: Flag suspicious or risky dependency additions
- **Env vars**: Ensure sensitive config uses `NODE_*` env vars , not hardcoded values
Comment thread
PierreBrisorgueil marked this conversation as resolved.
Outdated
- **Auth bypass**: Watch for changes that weaken JWT/Passport validation or policy middleware

### 3. Verify modularity

- **Cross-module coupling**: Flag unnecessary imports between modules
- **Layer violations**: Ensure controllers don't call repositories directly (must go through services)
- **Module boundaries**: Keep logic isolated within `modules/{name}/` — controllers, services, repositories, models, policies, routes, tests

## When invoked

- Review proposed changes briefly
- Flag any concerns with severity:
- 🔴 **Critical**: Must fix (security, breakage)
- 🟡 **Warning**: Should review (coupling, patterns, layer violations)
- 🟢 **Info**: Good to know (suggestions)
- Be concise — this is a quick sanity check, not a full audit

## What NOT to do

- Don't run workflows or execute commands
- Don't implement features
- Don't write code
- Keep reviews short and focused

## Example review

```
🔴 Critical: `.env` file was modified (should be git-ignored)
🟡 Warning: Controller imports repository directly — must go through service layer
🟢 Info: Consider extracting this validation schema to `lib/helpers/joi.js` for reuse
```
137 changes: 137 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
{
"mcpServers": {},
"permissions": {
"files": {
"deny": [
".env",
".env.*",
"secrets/**",
"**/*.pem",
"**/*.key",
"**/*.enc",
"**/credentials.json",
"**/credentials.yml",
"**/credentials.yaml",
"**/*-key.json",
"**/*_rsa",
"**/*_dsa",
"**/*_ecdsa",
"**/*_ed25519"
]
},
"bash": {
"allow": [
{
"command": "git status",
"prompt": "Check git status"
},
{
"command": "git diff",
"prompt": "View git diff"
},
{
"command": "git diff *",
"prompt": "View git diff for specific files"
},
{
"command": "git log",
"prompt": "View git log"
},
{
"command": "git log *",
"prompt": "View git log with options"
},
{
"command": "git show *",
"prompt": "Show git commit details"
},
{
"command": "npm start",
"prompt": "Start dev server"
},
{
"command": "npm run debug",
"prompt": "Start debug server"
},
{
"command": "npm run prod",
"prompt": "Start production server"
},
{
"command": "npm test",
"prompt": "Run tests"
},
{
"command": "npm run test:watch",
"prompt": "Run tests in watch mode"
},
{
"command": "npm run test:coverage",
"prompt": "Generate test coverage"
},
{
"command": "npm run lint",
"prompt": "Check code quality"
},
{
Comment thread
PierreBrisorgueil marked this conversation as resolved.
"command": "npm run lint:fix",
"prompt": "Auto-fix code quality issues"
},
{
"command": "npm run seed:dev",
"prompt": "Seed development database"
},
{
"command": "npm run commit",
"prompt": "Commit with commitizen"
},
{
"command": "docker-compose up",
"prompt": "Start docker-compose services"
},
{
"command": "docker-compose up -d",
"prompt": "Start docker-compose in background"
},
{
"command": "docker-compose down",
"prompt": "Stop docker-compose services"
},
{
"command": "docker-compose ps",
"prompt": "Show docker-compose status"
}
],
"deny": [
{
"pattern": "rm -rf *",
"reason": "Destructive command"
},
{
"pattern": "sudo *",
"reason": "Requires elevated privileges"
},
{
"pattern": "curl * | *sh",
"reason": "Arbitrary code execution risk"
},
{
"pattern": "wget * | *sh",
"reason": "Arbitrary code execution risk"
},
{
"pattern": "git push *",
"reason": "Automatic push not allowed"
},
{
"pattern": "npm publish",
"reason": "Package publishing requires explicit approval"
},
{
"pattern": "npm run seed:mongodrop",
"reason": "Destructive database operation"
}
]
}
}
}
111 changes: 111 additions & 0 deletions .claude/skills/create-module/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
---
name: create-module
description: Create a new feature module by duplicating the canonical `tasks` module template. Use when adding a new module to the application, scaffolding a new domain area from scratch, or generating the boilerplate for a new feature.
---

# Create Module Skill

Create a new module by copying and renaming the `tasks` template module.

## Prerequisites

- The canonical template module `modules/tasks` must exist
- You need a name for the new module (kebab-case)

## Steps

### 1. Ask for the module name

Prompt user for the new module name in kebab-case (e.g., `my-feature`, `user-settings`)

### 2. Derive naming conventions

Follow `/naming` for the full reference. Quick summary from the module name (e.g., `my-feature`):

- **kebab-case**: `my-feature` (folder names, file prefixes, routes)
- **PascalCase**: `MyFeature` (Mongoose model names, class names)
- **lowerCamelCase**: `myFeature` (variable names, function names, JS exports)
- **UPPER_SNAKE_CASE**: `MY_FEATURE` (constants)

### 3. Duplicate the module

```bash
cp -r modules/tasks modules/{new-module-name}
```

### 4. Rename references

Search and replace the following tokens across the new module:

- `tasks` → `{new-module-name}` (kebab-case)
- `Tasks` → `{NewModuleName}` (PascalCase)
- `task` → `{new-module}` (singular kebab-case, if applicable)
- `Task` → `{NewModule}` (singular PascalCase, if applicable)

Files to check in `modules/{new-module-name}/`:

- File names (controllers, services, repositories, models, schemas, policies, routes, tests)
- Mongoose model name and collection name
- Route paths and prefixes
- Joi validation schemas
- Policy function names
- Test descriptions and fixture data

### 5. Show rename plan (if broad changes)

If renaming affects many files, show a brief plan before applying changes.

### 6. Apply renames carefully

Use safe search+replace to avoid false positives:

- Be case-sensitive
- Match whole words where possible
- Don't rename unrelated code (e.g., "tasks" in comments about other features)

### 7. Run verify

```bash
npm run lint
npm test
```

### 8. Report results

Provide a summary:

- ✅ Module created at: `modules/{new-module-name}`
- ✅ Renamed tokens: `tasks` → `{new-module-name}`, etc.
- ✅ Verification: lint passed, tests passed
- 📝 Next steps: Customize the schema, update business logic in services. Routes are auto-discovered via glob `modules/*/routes/*.js` — no registration needed

## Module Structure

```
modules/{new-module-name}/
├── controllers/
Comment thread
PierreBrisorgueil marked this conversation as resolved.
│ └── {module}.controller.js
├── services/
│ └── {module}.service.js
│ └── {module}.data.service.js
├── repositories/
│ └── {module}.repository.js
├── models/
│ └── {module}.model.mongoose.js
│ └── {module}.model.sequelize.js (optional)
│ └── {module}.schema.js
├── policies/
│ └── {module}.policy.js
├── routes/
│ └── {module}.routes.js
└── tests/
├── {module}.integration.tests.js
└── {module}.unit.tests.js
```

## Notes

- Preserves the layered architecture: controllers → services → repositories → models
- Follows modularity rules: keeps the module self-contained
- Policy functions control route authorization — update them for your use case
- Remove `{module}.model.sequelize.js` if not using SQL
77 changes: 77 additions & 0 deletions .claude/skills/feature/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
---
name: feature
description: Implement a new feature or modify existing functionality following the project's layered architecture and modularity rules. Use when adding features, modifying existing ones, or ensuring correct isolation within module boundaries.
---

# Feature Skill

Implement features with strict layer ordering and module isolation.

## Steps

### 1. Identify target module(s)

Before coding, determine:

- Which module(s) does this feature belong to?
- Default to **ONE module** unless strictly necessary
- If it spans multiple modules, explain why and minimize coupling

### 2. Apply layer rules

Respect the strict layer order — never skip or reverse it:

```
Routes → Controllers → Services → Repositories → Models
```

- **Routes** (`routes/`): Define HTTP endpoints, apply policy middleware
- **Controllers** (`controllers/`): Handle HTTP req/res, call services, format responses via `lib/helpers/responses.js`
- **Services** (`services/`): Business logic, call repositories, throw `AppError` for domain errors
- **Repositories** (`repositories/`): Database access only, use Joi schemas for validation
- **Models** (`models/`): Mongoose schema definition (`*.model.mongoose.js`) and Joi schema (`*.schema.js`)

### 3. Apply modularity rules

- **Isolate feature logic** inside the module boundary
- **Avoid cross-module imports** unless absolutely required
- If shared code is needed:
- Place it in `lib/helpers/` or `lib/services/`
- Provide **explicit justification** for why it must be shared
- Keep these inside the module (`modules/{module}/**`):
- Controllers, services, repositories, models, schemas, policies, routes, tests

### 4. Use existing helpers

Before writing new utilities, check:

- `lib/helpers/responses.js` — JSend response wrapper
- `lib/helpers/AppError.js` — Custom error class for domain errors
- `lib/helpers/errors.js` — Error formatting utilities
- `lib/helpers/joi.js` — Shared Joi validation helpers
- `lib/middlewares/policy.js` — Authorization middleware
- `lib/middlewares/model.js` — Model middleware

### 5. Follow API response format

All API responses must use the JSend wrapper from `lib/helpers/responses.js`:

```js
// Success
responses.success(res, 'task list')(data);
// Error
responses.error(res, 422, 'Unprocessable Entity', errors.getMessage(err))(err);
```

### 6. Run verify

```bash
npm run lint
npm test
```

## Notes

- Config is loaded from `config/` and overridable via `NODE_*` env vars
- Authentication is handled via Passport JWT middleware — don't reimplement
- All policies must use `lib/middlewares/policy.js` patterns
Loading
Loading