Skip to content

Commit fc31838

Browse files
committed
docs: fix documentation inconsistencies in copilot-instructions and AGENTS
1 parent 8dc85ac commit fc31838

File tree

2 files changed

+146
-189
lines changed

2 files changed

+146
-189
lines changed

.github/copilot-instructions.md

Lines changed: 11 additions & 183 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
# GitHub Copilot Instructions
22

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)
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)
55
> For specialized knowledge, use: `#file:SKILLS/<skill-name>/SKILL.md` (loaded on-demand when needed)
66
77
## 🎯 Quick Context
88

9-
**Project**: FastAPI REST API demonstrating modern Python async patterns
10-
**Stack**: Python 3.13 • FastAPI • SQLAlchemy (async) • SQLite • Docker • pytest
11-
**Pattern**: Routes → Services → Database (layered architecture)
9+
**Project**: FastAPI REST API demonstrating modern Python async patterns
10+
**Stack**: Python 3.13 • FastAPI • SQLAlchemy (async) • SQLite • Docker • pytest
11+
**Pattern**: Routes → Services → Database (layered architecture)
1212
**Philosophy**: Learning-focused PoC emphasizing async/await and type safety
1313

1414
## 📐 Core Conventions
@@ -21,7 +21,7 @@
2121

2222
## 🏗️ Architecture at a Glance
2323

24-
```
24+
```text
2525
Route → Service → Database
2626
↓ ↓
2727
Cache Session
@@ -31,7 +31,7 @@ Cache Session
3131
- **Services**: Async database operations via SQLAlchemy
3232
- **Database**: SQLite with async support (`aiosqlite`)
3333
- **Models**: Pydantic for validation, SQLAlchemy for ORM
34-
- **Cache**: aiocache SimpleMemoryCache (10min/1hr TTL)
34+
- **Cache**: aiocache SimpleMemoryCache (TTL: 600s / 10 min)
3535

3636
## ✅ Copilot Should
3737

@@ -56,195 +56,23 @@ Cache Session
5656

5757
```bash
5858
# Run with hot reload
59-
uvicorn main:app --reload --host 0.0.0.0 --port 8000
59+
uvicorn main:app --reload --host 0.0.0.0 --port 9000
6060

6161
# Test with coverage
6262
pytest --cov=. --cov-report=term-missing
6363

6464
# Docker
6565
docker compose up
6666

67-
# Swagger: http://localhost:8000/docs
67+
# Swagger: http://localhost:9000/docs
6868
```
6969

7070
## 📚 Need More Detail?
7171

72-
**For operational procedures**: Load `#file:AGENTS.md`
73-
**For Docker expertise**: *(Planned)* `#file:SKILLS/docker-containerization/SKILL.md`
72+
**For operational procedures**: Load `#file:AGENTS.md`
73+
**For Docker expertise**: *(Planned)* `#file:SKILLS/docker-containerization/SKILL.md`
7474
**For testing patterns**: *(Planned)* `#file:SKILLS/testing-patterns/SKILL.md`
7575

7676
---
7777

7878
💡 **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!
79-
5. **Caching**: In-memory cache (10 min TTL) with `X-Cache` headers (HIT/MISS)
80-
6. **Async/Await**: All database operations are async
81-
82-
## Coding Guidelines
83-
84-
### Python Style (Strict Enforcement)
85-
86-
- **Formatter**: Black (line length: 88, target: Python 3.13)
87-
- **Linter**: flake8 (max-complexity: 10, ignores: E203, W503)
88-
- **Run Before Commit**: `black .` and `flake8`
89-
- **Imports**: SQLAlchemy 2.0+ style (use `select()` not legacy `Query`)
90-
- **Docstrings**: Google-style docstrings for all modules, classes, and functions
91-
- **Type Hints**: Use type annotations for function parameters and return values
92-
93-
### File Exclusions
94-
95-
Black and flake8 exclude:
96-
- `.venv`, `.git`, `.github`, `.pytest_cache`, `__pycache__`
97-
- `assets/`, `htmlcov/`, `postman_collections/`, `scripts/`, `storage/`
98-
- Exception: `tests/test_main.py` allows E501 (long lines for test names)
99-
100-
### Commit Conventions
101-
102-
Follow **Conventional Commits** (enforced by commitlint):
103-
- `feat:` for new features
104-
- `fix:` for bug fixes
105-
- `chore:` for maintenance/tooling
106-
- Max header length: 80 characters
107-
- Max body line length: 80 characters
108-
109-
## Common Commands
110-
111-
### Local Development
112-
113-
```bash
114-
# Install dependencies
115-
pip install -r requirements.txt
116-
pip install -r requirements-lint.txt
117-
pip install -r requirements-test.txt
118-
119-
# IMPORTANT: Activate virtual environment before running commands
120-
source .venv/bin/activate
121-
122-
# Start server (auto-reload on port 9000)
123-
uvicorn main:app --reload --port 9000
124-
125-
# Access interactive API docs
126-
# http://localhost:9000/docs
127-
128-
# Format code (must run from venv)
129-
black .
130-
131-
# Lint code (must run from venv)
132-
flake8 .
133-
134-
# Run tests
135-
pytest -v
136-
137-
# Run tests with coverage
138-
pytest --cov=./ --cov-report=xml --cov-report=term
139-
```
140-
141-
### Docker
142-
143-
```bash
144-
# Build image
145-
docker compose build
146-
147-
# Start app (initializes DB from seed on first run)
148-
docker compose up
149-
150-
# Stop app
151-
docker compose down
152-
153-
# Reset database (removes volume)
154-
docker compose down -v
155-
```
156-
157-
## Database Details
158-
159-
- **Path**: Controlled by `STORAGE_PATH` env var (default: `./storage/players-sqlite3.db`)
160-
- **Docker Volume**: Persistent volume at `/storage/` in container
161-
- **Initialization**: On first Docker run, `entrypoint.sh` copies seed DB from `/app/hold/` to `/storage/`
162-
- **Schema**: Single `players` table with columns: id (PK), firstName, middleName, lastName, dateOfBirth, squadNumber (unique), position, abbrPosition, team, league, starting11
163-
164-
## API Endpoints
165-
166-
| Method | Path | Description | Cache |
167-
|--------|-------------------------------------|------------------------------|-------|
168-
| GET | `/health` | Health check | No |
169-
| GET | `/players/` | Get all players | Yes |
170-
| GET | `/players/{player_id}` | Get player by ID | No |
171-
| GET | `/players/squadnumber/{squad_number}` | Get player by squad number | No |
172-
| POST | `/players/` | Create new player | Clears|
173-
| PUT | `/players/{player_id}` | Update existing player | Clears|
174-
| DELETE | `/players/{player_id}` | Delete player | Clears|
175-
176-
**Cache Notes**:
177-
- Cache key: `"players"`, TTL: 600s (10 min)
178-
- Cache is cleared on POST/PUT/DELETE operations
179-
- Response header `X-Cache: HIT` or `MISS` indicates cache status
180-
181-
## Testing
182-
183-
- **Framework**: pytest with `TestClient` from FastAPI
184-
- **Fixture**: `client` fixture in `conftest.py` (function scope for test isolation)
185-
- **Coverage Target**: 80% (configured in `codecov.yml`)
186-
- **Test Data**: Use stubs from `tests/player_stub.py`
187-
- **Warnings**: DeprecationWarning from httpx is suppressed in conftest
188-
189-
## CI/CD Pipeline
190-
191-
GitHub Actions workflow (`.github/workflows/python-app.yml`):
192-
1. **Lint Job**: Commitlint → Flake8 → Black (check mode)
193-
2. **Test Job**: pytest with coverage report generation
194-
3. **Coverage Job**: Upload to Codecov and Codacy (only for same-repo PRs)
195-
196-
**All PRs must pass CI checks before review.**
197-
198-
## Common Pitfalls & Solutions
199-
200-
1. **Virtual Environment**: Always activate `.venv` before running black, flake8, or pytest:
201-
```bash
202-
source .venv/bin/activate
203-
```
204-
205-
2. **FastAPI Route Ordering**: Static routes MUST be defined before dynamic path parameters. Place `/players/statistics` before `/players/{player_id}`, or FastAPI will try to parse "statistics" as a player_id.
206-
```python
207-
# CORRECT order:
208-
@api_router.get("/players/statistics") # Static route first
209-
@api_router.get("/players/{player_id}") # Dynamic route after
210-
```
211-
212-
3. **SQLAlchemy 2.0 Migration**: Use `select()` not `session.query()`. Example:
213-
```python
214-
statement = select(Player).where(Player.id == player_id)
215-
result = await async_session.execute(statement)
216-
```
217-
218-
4. **Async Session Usage**: Always use `Depends(generate_async_session)` in routes, never create sessions manually.
219-
220-
5. **Cache Invalidation**: Remember to call `await simple_memory_cache.clear(CACHE_KEY)` after mutations (POST/PUT/DELETE).
221-
222-
6. **Pydantic Model Conversion**: Use `player_model.model_dump()` to convert Pydantic to dict for SQLAlchemy:
223-
```python
224-
player = Player(**player_model.model_dump())
225-
```
226-
227-
7. **Database Path in Docker**: Use `STORAGE_PATH` env var, not hardcoded paths.
228-
229-
8. **Port Conflicts**: Default port is 9000. If occupied, use `--port` flag with uvicorn.
230-
231-
## VS Code Configuration
232-
233-
Recommended extensions (`.vscode/extensions.json`):
234-
- `ms-python.python`, `ms-python.flake8`, `ms-python.black-formatter`
235-
- `github.vscode-pull-request-github`, `github.vscode-github-actions`
236-
- `ms-azuretools.vscode-containers`, `sonarsource.sonarlint-vscode`
237-
238-
Settings (`.vscode/settings.json`):
239-
- Auto-format on save with Black
240-
- Pytest enabled (not unittest)
241-
- Flake8 integration with matching CLI args
242-
- Editor ruler at column 88
243-
244-
## Additional Resources
245-
246-
- **Postman Collection**: `postman_collections/python-samples-fastapi-restful.postman_collection.json`
247-
- **Architecture Diagram**: `assets/images/structure.svg`
248-
- **FastAPI Docs**: https://fastapi.tiangolo.com/
249-
- **SQLAlchemy 2.0**: https://docs.sqlalchemy.org/en/20/
250-
- **Conventional Commits**: https://www.conventionalcommits.org/

0 commit comments

Comments
 (0)