Skip to content

Commit a8508da

Browse files
committed
docs: update readme
1 parent 7d30ef3 commit a8508da

2 files changed

Lines changed: 58 additions & 19 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
# Python
23
__pycache__/
34
*.pyc
@@ -7,6 +8,7 @@ __pycache__/
78
*.so
89
*.egg-info/
910
.eggs/
11+
.cache/
1012

1113
# Virtual environments
1214
venv/

README.md

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ The API is currently versioned under `/api/v1`.
2525
- [Database and Migrations](#database-and-migrations)
2626
- [Testing and Quality Checks](#testing-and-quality-checks)
2727
- [Makefile Commands](#makefile-commands)
28+
- [Additional Documentation](#additional-documentation)
2829
- [Docker Notes](#docker-notes)
2930
- [Development Guide](#development-guide)
3031
- [Troubleshooting](#troubleshooting)
@@ -52,7 +53,7 @@ The API is currently versioned under `/api/v1`.
5253
- Async SQLAlchemy persistence.
5354
- Alembic database migrations.
5455
- Database seeders for authorization data and optional users.
55-
- Pytest regression tests.
56+
- Pytest application-validation tests.
5657
- Ruff linting.
5758

5859
## Tech Stack
@@ -83,7 +84,7 @@ The API is currently versioned under `/api/v1`.
8384
│ ├── main.py # FastAPI application entrypoint
8485
│ ├── core/
8586
│ │ ├── bootstrap/ # Application bootstrap helpers
86-
│ │ ├── authorization/ # RBAC permissions, Casbin services, auth models
87+
│ │ ├── authorization/ # Shared authorization persistence and services
8788
│ │ ├── config/ # Runtime settings
8889
│ │ ├── database/ # PostgreSQL and Redis connection setup
8990
│ │ ├── dependency/ # Shared FastAPI dependencies
@@ -93,12 +94,13 @@ The API is currently versioned under `/api/v1`.
9394
│ │ ├── schemas/ # Shared response schemas
9495
│ │ ├── security/ # JWT, password, revocation, audit helpers
9596
│ │ ├── seed/ # Database seeding orchestration
96-
│ │ ├── utils/ # Cursor pagination helpers
9797
│ │ └── lifespan.py # FastAPI lifespan hook
9898
│ ├── modules/
9999
│ │ ├── authorization/
100-
│ │ │ ├── domain/ # Role and permission entities
101-
│ │ │ └── presenter/ # Role and permission routers/schemas
100+
│ │ │ ├── application/ # Role and permission use cases
101+
│ │ │ ├── domain/ # Role, resource, and permission entities
102+
│ │ │ ├── infrastructure/ # Casbin and SQLAlchemy adapters
103+
│ │ │ └── presentation/ # Role and permission routers/schemas
102104
│ │ ├── user/
103105
│ │ │ ├── application/ # User commands, queries, handlers
104106
│ │ │ ├── domain/ # User entity, exceptions, repository port
@@ -111,7 +113,11 @@ The API is currently versioned under `/api/v1`.
111113
│ │ └── presentation/ # FastAPI router and dependencies
112114
│ └── shared/
113115
│ ├── database/ # Shared SQLAlchemy base and mixins
114-
│ └── exceptions/ # Cross-cutting exceptions
116+
│ ├── email/ # Shared email contracts
117+
│ ├── events/ # Shared event contracts
118+
│ ├── exceptions/ # Cross-cutting exceptions
119+
│ └── utils/ # Cursor pagination helpers
120+
├── templates/emails/ # Transactional email templates
115121
├── tests/ # Pytest tests
116122
├── pyproject.toml # Project metadata and dependencies
117123
├── poetry.lock # Poetry lock file
@@ -211,6 +217,7 @@ GET /api/v1/auth/me
211217
POST /api/v1/auth/logout
212218
POST /api/v1/todos/
213219
GET /api/v1/todos/?cursor=<cursor>&limit=10
220+
GET /api/v1/todos/{todo_id}
214221
PATCH /api/v1/todos/{todo_id}
215222
DELETE /api/v1/todos/{todo_id}
216223
POST /api/v1/roles/
@@ -240,6 +247,7 @@ Public routes:
240247
- `/openapi.json`
241248
- `/api/v1/auth/login`
242249
- `/api/v1/auth/register`
250+
- `/api/v1/auth/refresh`
243251

244252
Protected routes require:
245253

@@ -254,6 +262,8 @@ Swagger UI, ReDoc, and OpenAPI JSON are disabled when `APP_ENV=production`.
254262
- Python `3.14` or compatible with the project constraint.
255263
- Poetry.
256264
- PostgreSQL, either local or via Docker.
265+
- Redis, either local or via Docker.
266+
- Docker with the Compose plugin, if using the containerized stack.
257267
- Make, if using the generated `Makefile`.
258268

259269
## Environment Variables
@@ -269,6 +279,7 @@ Expected values:
269279
```env
270280
APP_NAME=Todo Modulith API
271281
APP_ENV=production
282+
FRONTEND_URL=http://localhost:3000
272283
POSTGRES_USER=postgres
273284
POSTGRES_PASSWORD=
274285
POSTGRES_DB=todo_db
@@ -296,34 +307,48 @@ ACCOUNT_LOCKOUT_MAX_ATTEMPTS=5
296307
ACCOUNT_LOCKOUT_WINDOW_MINUTES=15
297308
ACCOUNT_LOCKOUT_DURATION_MINUTES=15
298309
LOG_FORMAT=json
310+
EMAIL_PROVIDER=ses
311+
AWS_REGION=us-east-1
312+
AWS_ACCESS_KEY_ID=
313+
AWS_SECRET_ACCESS_KEY=
314+
SES_FROM_EMAIL=noreply@example.com
315+
SENDGRID_API_KEY=
316+
SENDGRID_FROM_EMAIL=noreply@example.com
317+
SMTP_HOST=
318+
SMTP_PORT=587
319+
SMTP_USERNAME=
320+
SMTP_PASSWORD=
321+
SMTP_FROM_EMAIL=noreply@example.com
322+
SMTP_USE_TLS=true
299323
SEED_ADMIN_EMAIL=
300324
SEED_ADMIN_PASSWORD=
301325
SEED_ADMIN_USERNAME=admin
302326
SEED_ADMIN_FULLNAME=System Administrator
303327
SEED_DEVELOPMENT_USERS_PASSWORD=
304328
```
305329

306-
For local development without Docker, point `DATABASE_URL` at your local PostgreSQL host, for example:
330+
`MAX_REQUEST_SIZE_MB` is currently interpreted as a byte count despite its name. Keep it at `5242880` for a 5 MiB limit.
331+
332+
For local development without Docker, use development mode and point the service URLs at local PostgreSQL and Redis instances, for example:
307333

308334
```env
335+
APP_ENV=development
309336
DATABASE_URL=postgresql+asyncpg://postgres@localhost:5432/todo_db
337+
REDIS_URL=redis://127.0.0.1:6379/0
310338
```
311339

340+
Production mode requires a non-default `SECRET_KEY`, non-empty database and Redis URLs, JWT issuer and audience values, positive token lifetimes, and explicit CORS origins.
341+
312342
## Local Setup
313343

314-
Install dependencies:
344+
The Makefile expects Poetry to create `.venv` inside the repository. Configure that once, then install dependencies:
315345

316346
```bash
347+
poetry config virtualenvs.in-project true --local
317348
poetry install
318349
```
319350

320-
Activate the virtual environment if desired:
321-
322-
```bash
323-
poetry shell
324-
```
325-
326-
Or run commands through Poetry:
351+
Run commands through Poetry directly:
327352

328353
```bash
329354
poetry run pytest -q
@@ -351,6 +376,8 @@ Open:
351376
http://localhost:8000/docs
352377
```
353378

379+
This documentation endpoint is available only when `APP_ENV` is not `production`.
380+
354381
Health check:
355382

356383
```text
@@ -458,8 +485,11 @@ Current check set:
458485

459486
- `pytest -q`
460487
- `ruff check src tests scripts`
488+
- import boundary checks through `lint-imports`
461489
- import check for `src.main`
462490

491+
The current pytest suite focuses on application-layer command and query validation. Broader middleware, API integration, and infrastructure regression coverage still needs to be added.
492+
463493
Dependency scanning is available separately:
464494

465495
```bash
@@ -474,6 +504,7 @@ make install
474504
make run
475505
make test
476506
make lint
507+
make lint-imports
477508
make import-check
478509
make security-scan
479510
make check
@@ -487,6 +518,10 @@ make db-logs
487518
make clean
488519
```
489520

521+
## Additional Documentation
522+
523+
- [Query Optimization Guide](docs/QUERY_OPTIMIZATION.md)
524+
490525
## Docker Notes
491526

492527
Before starting Docker Compose, set non-empty `POSTGRES_PASSWORD`, `REDIS_PASSWORD`, and `SECRET_KEY` in `.env`. Compose intentionally fails fast when database or Redis passwords are missing.
@@ -497,6 +532,8 @@ Run API, PostgreSQL, and Redis services:
497532
make db-up
498533
```
499534

535+
The API container applies Alembic migrations before starting Uvicorn. Database seeding remains an explicit `make seed` step.
536+
500537
Stop services:
501538

502539
```bash
@@ -635,11 +672,11 @@ Legend: `Implemented` means code exists in the repository. `Partial` means code
635672
- [x] Add production config validation for secrets and unsafe defaults.
636673
- [x] Harden CORS through environment-driven allowed origins, methods, and headers.
637674
- [x] Review exception responses to avoid leaking token parsing details or internal exception messages.
638-
- [x] Add automated tests for request size limits, rate limiting, auth failures, authorization failures, CORS, security headers, and request IDs.
675+
- [ ] Add automated tests for request size limits, rate limiting, auth failures, authorization failures, CORS, security headers, and request IDs.
639676
- [x] Add dependency vulnerability scanning to local or CI checks, for example `pip-audit` or an equivalent Poetry-compatible scanner.
640677

641678
## Known Notes
642679

643-
- `src/core/lifespan.py` still calls `Base.metadata.create_all`; with Alembic in place, production environments normally rely on migrations instead.
644-
- The project has a Pydantic v2 deprecation warning for class-based settings config.
645-
- The current architecture is clean enough for a learning modulith, but some flows can be made stricter by moving remaining business orchestration out of routers and into application handlers.
680+
- The automated test suite currently covers application validation only; middleware, router, database, Redis, and authorization integration paths are not covered.
681+
- Authorization persistence currently exists under both `src/core/authorization/infrastructure` and `src/modules/authorization/infrastructure`; new work should avoid increasing that duplication.
682+
- Some authorization routes call the domain service directly while other modules use dedicated application handlers, so CQRS boundaries are not yet applied consistently.

0 commit comments

Comments
 (0)