Skip to content

Commit a8b003b

Browse files
nanotaboadaCopilot
andcommitted
docs(copilot): unify instructions as canonical single-file format
Consolidate .github/copilot-instructions.md and AGENTS.md into a single always-on file with a consistent section order (Overview, Tech Stack, Structure, Coding Guidelines, Commands, Agent Mode). - Replace two-file system with one canonical copilot-instructions.md - Absorb AGENTS.md content (autonomy levels, workflows) into Agent Mode Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 063ab0d commit a8b003b

File tree

2 files changed

+124
-320
lines changed

2 files changed

+124
-320
lines changed

.github/copilot-instructions.md

Lines changed: 124 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,128 @@
1-
# Copilot Instructions
1+
# GitHub Copilot Instructions
22

3-
## Stack
3+
## Overview
4+
5+
REST API for managing football players built with Node.js and Express.js in TypeScript (native ESM). Implements CRUD operations with a layered architecture, Sequelize ORM + SQLite, in-memory caching, Swagger documentation, and Pino structured logging. Part of a cross-language comparison study (.NET, Go, Java, Python, Rust).
6+
7+
## Tech Stack
48

59
- **Runtime**: Node.js 24 LTS (Krypton)
10+
- **Language**: TypeScript (strict mode, native ESM)
611
- **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)
12+
- **ORM**: Sequelize
13+
- **Database**: SQLite
14+
- **Caching**: node-cache (in-memory, 1-hour TTL)
15+
- **Logging**: Pino (structured, with request correlation IDs)
16+
- **Security**: Helmet, CORS, express-rate-limit
17+
- **Testing**: Jest 30 + Supertest
18+
- **Linting/Formatting**: ESLint + Prettier
19+
- **API Docs**: Swagger (JSDoc annotations → swagger.json)
20+
- **Containerization**: Docker (multi-stage builds)
21+
22+
## Structure
23+
24+
```text
25+
src/
26+
├── controllers/ — request handlers + Swagger JSDoc + try/catch [HTTP layer]
27+
├── routes/ — Express Router definitions + middleware
28+
├── services/ — business logic + node-cache caching [business layer]
29+
├── database/ — Sequelize interfaces + implementations [data layer]
30+
├── models/ — Sequelize Player model
31+
├── middlewares/ — rate limiter, validators, CSP
32+
├── docs/ — Swagger config and doc generation
33+
└── utils/ — Pino logging configuration
34+
tests/ — Jest + Supertest integration tests
35+
storage/ — pre-seeded SQLite database (versioned, used in Docker image)
36+
scripts/ — Docker entrypoint and healthcheck scripts
37+
```
38+
39+
**Layer rule**: `Routes → Controllers → Services → Database`. Controllers must not contain business logic. Services handle all caching and Sequelize operations.
40+
41+
## Coding Guidelines
42+
43+
- **Module system**: Native ESM — always include `.js` extension in relative imports (omitting it breaks ESM at runtime)
44+
- **Naming**: camelCase (variables/functions), PascalCase (classes/types/interfaces), kebab-case (file names, e.g. `player-service.ts`)
45+
- **Type safety**: Strict TypeScript; never use `any`; prefer interfaces over types
46+
- **DI**: Constructor injection with interface-based abstractions
47+
- **Async**: All I/O uses async/await; never callbacks or synchronous calls
48+
- **Logging**: Pino only; never `console.log`
49+
- **Imports**: Group external deps → internal modules → types; alphabetically sorted within groups
50+
- **Formatting**: Prettier (4 spaces, single quotes, 127 width) — enforced pre-commit
51+
- **Tests**: naming `it('Request {METHOD} {/path} {context} → Response {outcome}')` — METHOD ALL CAPS, status codes Title Case (e.g. `200 OK`, `404 Not Found`); mock external deps only; use real test database (no Sequelize mocking)
52+
- **Avoid**: `any` without justification, missing `.js` in imports, mixing CommonJS with ESM, sync file ops, `console.log`, `@ts-ignore` without comments, mocking Sequelize models
53+
54+
## Commands
55+
56+
### Quick Start
57+
58+
```bash
59+
npm install
60+
npm run dev # http://localhost:9000
61+
npm run build && npm start
62+
npm test # all tests
63+
npm run coverage # tests + coverage
64+
npm run lint
65+
npx tsc --noEmit # type check
66+
npx prettier --write .
67+
docker compose up
68+
docker compose down -v
69+
```
70+
71+
### Pre-commit Checks
72+
73+
1. Update `CHANGELOG.md` `[Unreleased]` section (Added / Changed / Fixed / Removed)
74+
2. `npm run lint` — ESLint must pass
75+
3. `npx tsc --noEmit` — TypeScript must compile clean
76+
4. `npm run coverage` — all tests must pass, coverage maintained
77+
5. `npm run lint:commit` — Conventional Commits validation
78+
6. Commit message follows Conventional Commits format (enforced by commitlint)
79+
80+
### Commits
81+
82+
Format: `type(scope): description (#issue)` — max 80 chars
83+
Types: `feat` `fix` `chore` `docs` `test` `refactor` `ci` `perf`
84+
Example: `feat(api): add player stats endpoint (#42)`
85+
86+
## Agent Mode
87+
88+
### Proceed freely
89+
90+
- Route handlers and controllers
91+
- Service layer logic and caching
92+
- Unit and integration tests
93+
- Documentation updates
94+
- Code quality and formatting improvements
95+
96+
### Ask before changing
97+
98+
- Database schema (Sequelize model fields)
99+
- Dependencies (`package.json`)
100+
- Node.js version (`.nvmrc`, `package.json engines`)
101+
- CI/CD configuration (`.github/workflows/`)
102+
- Docker setup
103+
- Environment variables
104+
- API contracts (breaking changes)
105+
106+
### Never modify
107+
108+
- `.env` files
109+
- `storage/players-sqlite3.db` (pre-seeded, versioned, used in Docker image)
110+
- Generated files (`dist/`, `coverage/`, `swagger.json`)
111+
- Port configuration (9000)
112+
- Production configurations or deployment secrets
113+
114+
### Key workflows
115+
116+
**Add an endpoint**: Create interface + implementation in `src/controllers/` with Swagger JSDoc + try/catch → add service logic in `src/services/` with caching + Sequelize operations → register route in `src/routes/` → add integration tests following naming convention → run `npm run swagger:docs` → run pre-commit checks.
117+
118+
**Modify schema**: Update Sequelize model in `src/models/` → manually update `storage/players-sqlite3.db` (no migration system) → rebuild Docker image with `docker compose build` → update services, controllers, and tests → run `npm run coverage`.
119+
120+
**Cross-repo consistency**: API contracts (endpoints, schemas, HTTP status codes), release naming (football terminology, alphabetical), and CI/CD patterns must stay consistent across all stacks.
121+
122+
**After completing work**: Suggest a branch name (e.g. `feat/add-player-stats`) and a commit message following Conventional Commits including co-author line:
123+
124+
```text
125+
feat(scope): description (#issue)
126+
127+
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
128+
```

0 commit comments

Comments
 (0)