Skip to content

Commit eef6ca1

Browse files
authored
Merge pull request #488 from nanotaboada/docs/restructure-ai-instructions
docs: restructure AI instruction files
2 parents d7393c6 + 4206710 commit eef6ca1

File tree

2 files changed

+265
-533
lines changed

2 files changed

+265
-533
lines changed

.github/copilot-instructions.md

Lines changed: 58 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,112 +1,58 @@
1-
# GitHub Copilot Instructions
2-
3-
> **⚡ Token Efficiency Note**: This is a minimal pointer file (~500 tokens, auto-loaded by Copilot).
4-
> For complete operational details, reference: `#file:AGENTS.md` (~2,500 tokens, loaded on-demand)
5-
> For specialized knowledge, use: `#file:SKILLS/<skill-name>/SKILL.md` (loaded on-demand when needed)
6-
7-
## 🎯 Quick Context
8-
9-
**Project**: Express.js REST API with TypeScript and native ESM
10-
**Stack**: Node.js 24 • Express 5 • TypeScript • Sequelize • SQLite • Docker
11-
**Pattern**: Routes → Controllers → Services → ORM (layered)
12-
**Philosophy**: Learning-focused PoC with modern TypeScript and ESM
13-
14-
## 📐 Core Conventions
15-
16-
- **Module System**: Native ESM (require `.js` in imports!)
17-
- **Naming**: camelCase (variables/functions), PascalCase (classes/types)
18-
- **Type Safety**: Strict TypeScript, no `any` without justification
19-
- **Async**: All I/O operations use async/await
20-
- **Testing**: Jest with ESM experimental VM modules
21-
- **Formatting**: Prettier (4 spaces, single quotes, 127 width)
22-
- **Commit Messages**: Follow Conventional Commits with issue number suffix
23-
- Format: `type(scope): description (#issue)` (max 80 chars)
24-
- Types: `feat`, `fix`, `chore`, `docs`, `test`, `refactor`
25-
- Example: `feat(api): add player search endpoint (#123)`
26-
27-
## 🧪 Test Naming Convention
28-
29-
Integration tests follow an action-oriented pattern with visual flow:
30-
31-
**Pattern:**
32-
```typescript
33-
it('Request {METHOD} {/path} {context} → Response {outcome}', async () => {
34-
```
35-
36-
**Components:**
37-
- `Request` / `Response` - Title Case structural keywords
38-
- `METHOD` - ALL CAPS HTTP verbs: `GET`, `POST`, `PUT`, `DELETE`
39-
- `/path` - Actual endpoint with parameters: `/players`, `/players/{id}`
40-
- `context` - Lowercase descriptors: `existing`, `body empty`, `within rate limit`
41-
- `` - Arrow separator showing cause-effect flow
42-
- `outcome` - What's asserted: `status 200 OK`, `body players`, `header rate limit standard`
43-
- Status codes - Title Case with number: `200 OK`, `201 Created`, `400 Bad Request`, `404 Not Found`, `204 No Content`, `409 Conflict`, `429 Too Many Requests`
44-
45-
**Examples:**
46-
```typescript
47-
it('Request GET /health → Response status 200 OK', async () => {
48-
it('Request GET /players → Response body players', async () => {
49-
it('Request GET /players/{id} existing → Response status 200 OK', async () => {
50-
it('Request POST /players body empty → Response status 400 Bad Request', async () => {
51-
it('Request PUT /players/{id} existing → Response status 204 No Content', async () => {
52-
it('Request DELETE /players/{id} nonexistent → Response status 404 Not Found', async () => {
53-
it('Request GET /players exceed rate limit → Response status 429 Too Many Requests', async () => {
54-
```
55-
56-
## 🏗️ Architecture at a Glance
57-
58-
```
59-
RouteControllerServiceSequelizeDatabase
60-
↓ ↓ ↓
61-
Cache Validation Transaction
62-
```
63-
64-
- **Routes**: Express router with middleware
65-
- **Controllers**: Request/response handling
66-
- **Services**: Business logic with Sequelize ORM
67-
- **Models**: Sequelize models with TypeScript types
68-
- **Cache**: node-cache (1-hour TTL)
69-
70-
## ✅ Copilot Should
71-
72-
- Generate TypeScript with proper types and interfaces
73-
- Use ESM imports with `.js` extensions (mandatory!)
74-
- Follow Express async/await patterns correctly
75-
- Write Jest tests with proper ESM configuration
76-
- Apply Sequelize models and migrations correctly
77-
- Use Helmet and CORS for security
78-
- Implement proper error handling with try/catch
79-
80-
## 🚫 Copilot Should Avoid
81-
82-
- Using `any` type without reason
83-
- Missing `.js` in relative imports (ESM requirement!)
84-
- Mixing CommonJS (`require`) with ESM (`import`)
85-
- Synchronous file operations
86-
- Missing error handling on async operations
87-
- Using `console.log` instead of proper logging
88-
89-
## ⚡ Quick Commands
90-
91-
```bash
92-
# Run with hot reload
93-
npm run dev
94-
95-
# Test with coverage
96-
npm test
97-
98-
# Docker
99-
docker compose up
100-
101-
# Swagger: http://localhost:9000/api-docs
102-
```
103-
104-
## 📚 Need More Detail?
105-
106-
**For operational procedures**: Load `#file:AGENTS.md`
107-
**For Docker expertise**: *(Planned)* `#file:SKILLS/docker-containerization/SKILL.md`
108-
**For testing patterns**: *(Planned)* `#file:SKILLS/testing-patterns/SKILL.md`
109-
110-
---
111-
112-
💡 **Why this structure?** Copilot auto-loads this file on every chat (~500 tokens). Loading `AGENTS.md` or `SKILLS/` explicitly gives you deep context only when needed, saving 80% of your token budget!
1+
# Copilot Instructions
2+
3+
## Stack
4+
5+
- **Runtime**: Node.js 24 LTS (Krypton)
6+
- **Framework**: Express.js 5
7+
- **Language**: TypeScript (strict mode)
8+
- **Database**: SQLite with Sequelize ORM
9+
- **Testing**: Jest 30 with Supertest
10+
- **Containerization**: Docker with multi-stage builds
11+
12+
## Project Patterns
13+
14+
- **Layered Architecture**: Routes → Controllers → Services → Database
15+
- **Dependency Injection**: Constructor injection with interface-based abstractions
16+
- **Error Handling**: Try/catch in controllers, centralized error middleware
17+
- **Caching**: In-memory node-cache (1-hour TTL) at service layer
18+
- **Logging**: Pino structured logging with request correlation IDs
19+
- **Security**: Helmet middleware for headers, CORS, express-rate-limit
20+
21+
## Code Conventions
22+
23+
- **Module System**: Native ESM (not CommonJS) - always include `.js` in relative imports
24+
- **Naming**: camelCase for variables/functions, PascalCase for classes/types/interfaces
25+
- **File Naming**: kebab-case with suffixes (`player-service.ts`, `player-controller.ts`)
26+
- **Imports**: Group by external deps → internal modules → types, alphabetically sorted
27+
- **Type Safety**: Strict TypeScript, avoid `any` unless justified, prefer interfaces over types
28+
- **Async**: All I/O operations use async/await, never callbacks or synchronous calls
29+
- **Comments**: JSDoc for public APIs and Swagger annotations, inline comments only when necessary
30+
- **Formatting**: Prettier (4 spaces, single quotes, 127 width) - enforced pre-commit
31+
- **Commit Messages**: Conventional Commits format `type(scope): description (#issue)` (max 80 chars)
32+
33+
## Testing
34+
35+
- **Structure**: Integration tests in `/tests/`, focus on controller/service/route layers
36+
- **Naming Convention**: Action-oriented pattern with visual flow
37+
38+
```typescript
39+
it('Request {METHOD} {/path} {context} → Response {outcome}', async () => {
40+
```
41+
42+
- Example: `it('Request GET /players/{id} existing → Response status 200 OK', async () => {`
43+
- **Components**: Request/Response (Title Case), METHOD (ALL CAPS), /path (actual endpoint), context (lowercase), outcome (status codes in Title Case like `200 OK`, `404 Not Found`)
44+
- **Mocking**: Use Jest mocks for external dependencies, avoid mocking internal modules
45+
- **Coverage**: Maintain existing coverage levels (controllers, services, routes only)
46+
- **Runner**: Jest with ESM support (`ts-jest` preset), use `--watch` in development
47+
48+
## Avoid
49+
50+
- Using `any` type without explicit justification
51+
- Missing `.js` extensions in relative imports (ESM breaks without them)
52+
- Mixing CommonJS (`require`/`module.exports`) with ESM (`import`/`export`)
53+
- Synchronous file operations (`fs.readFileSync`, `fs.writeFileSync`)
54+
- Missing error handling on async operations (always `try/catch`)
55+
- Using `console.log` instead of Pino logger
56+
- Creating files without interfaces when abstraction is needed
57+
- Ignoring TypeScript errors or using `@ts-ignore` without comments
58+
- Mocking Sequelize models in tests (use real test database)

0 commit comments

Comments
 (0)