Repository navigation
Changelog
All notable changes to this project are documented in this file.
[v0.1.0] — 2026-04-29
Added
- Full CRUD for task lists and tasks with Clean Architecture (Domain → Application → Infrastructure)
- JWT authentication:
POST /auth/register,POST /auth/login - Task status change:
PATCH /task-lists/{id}/tasks/{task_id}/status - Task assignment with simulated email notification:
PATCH /task-lists/{id}/tasks/{task_id}/assignee - Task list endpoint with filters (
?status=,?priority=) andcompletion_percentagefield GET /users/me,GET /users— authenticated user endpointsGET /system/enums— available task statuses and prioritiesGET /health(liveness) andGET /status(readiness — checks DB connectivity)- Structured logging with
structlogand per-request correlation ID middleware NotificationPortabstract interface for email notifications (DIP)- Application mappers (
task_mapper,task_list_mapper) replacing private_to_outputhelpers update()method onTaskandTaskListdomain entities (timestamp managed by the entity)GetUserUseCaseandListUsersUseCase— users router goes through the application layerCurrentUserdataclass independencies.py;usernameincluded in JWT payloadALLOWED_ORIGINSsetting for CORS (replaces invalidallow_origins=["*"]+ credentials combo).dockerignoreto exclude dev artefacts, secrets and IDE files from the image- Multistage
Dockerfile(builder → development → runtime) with venv at/venv docker-compose.yml(dev with hot-reload) anddocker-compose.prod.yml(2 replicas + Nginx)Makefilewith targets for install, run, test, lint, format, Docker, migrations.pre-commit-config.yamlwith isort, black, ruff, flake8 and general file hygiene hooks- GitHub Actions CI: lint → test (PostgreSQL service) → Docker build
- Alembic migration setup with
compare_type=Trueandcompare_server_default=True
Changed
- Migrated package management from pip to uv with
uv.lockfor reproducible installs - Replaced
passlibwithbcryptdirectly (incompatible with bcrypt 4.x on Python 3.13) POSTGRES_*individual fields replace a singleDATABASE_URLstring in all.envfiles; URL built internally via@computed_field- All
datetime.utcnow()calls replaced withdatetime.now(UTC)(deprecation fix) DateTimecolumns changed toDateTime(timezone=True)for timezone-aware storageMapped[str]annotations for enum columns corrected toMapped[TaskStatus]/Mapped[Priority]withnative_enum=FalseMapped[list]onTaskListModel.taskscorrected toMapped[list["TaskModel"]]- Repository
update()methods rewritten withsa_update()— eliminates the redundant SELECT before every write count_by_task_list+count_completed_by_task_listmerged intocount_tasks_summary()returning(total, completed)in one queryAuthServiceinstantiated once at module level independencies.py(singleton)- All routers receive repositories via
Depends(get_task_repo / get_task_list_repo / get_user_repo)— no concrete SQLAlchemy classes leaked into the API layer Base.metadata.create_allgated toENVIRONMENT=development; production must runalembic upgrade headTaskStatusandPrioritymigrated from(str, Enum)toStrEnum(Python 3.11+)- Login use case checks
is_activebefore bcrypt to prevent timing-based user enumeration lifespanfunction annotated withAsyncGenerator[None, None]return typeasyncio_default_fixture_loop_scope = functionadded topytest.ini- Connection pool explicit settings:
pool_timeout=30,pool_recycle=1800 - HTTP Basic Auth protection on
/docs,/redocand/openapi.json