diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..2a780c9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,40 @@ +--- +name: Bug report +about: Report a bug or unexpected behavior +title: "[BUG]" +labels: bug +assignees: '' + +--- + +## Description + +A clear and concise description of what the bug is. + +## Steps to Reproduce + +1. Step 1 +2. Step 2 +3. Step 3 + +## Expected Behavior + +What you expected to happen. + +## Actual Behavior + +What actually happened. + +## Environment + +- **Python version:** (output of `python --version`) +- **FastAPI version:** (from `pyproject.toml`) +- **OS:** (e.g., macOS 14.0, Ubuntu 22.04, Windows 11) + +## Additional Context + +Add any other context about the problem here (logs, screenshots, etc.). + +## Possible Solution + +(Optional) Suggest a fix or workaround if you have one. diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 8cb8fe8..3523477 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -130,4 +130,5 @@ Example: `feat(api): add player stats endpoint (#42)` feat(scope): description (#issue) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> +Co-authored-by: Claude ``` diff --git a/README.md b/README.md index d318829..3f26678 100644 --- a/README.md +++ b/README.md @@ -86,68 +86,93 @@ Proof of Concept for a RESTful API built with [Python 3](https://www.python.org/ ## Architecture +Layered architecture with dependency injection via FastAPI's `Depends()` mechanism and Pydantic for request/response validation. + ```mermaid %%{init: { "theme": "default", "themeVariables": { "fontFamily": "Fira Code, Consolas, monospace", "textColor": "#555", - "lineColor": "#555", - "lineWidth": 2 + "lineColor": "#555" } }}%% -graph BT - %% Core application packages +graph RL + + tests[tests] + main[main] routes[routes] + fastapi[FastAPI] + aiocache[aiocache] + services[services] - schemas[schemas] - databases[databases] + models[models] + pydantic[Pydantic] - %% External dependencies - fastapi[FastAPI] + schemas[schemas] + + databases[databases] sqlalchemy[SQLAlchemy] - pydantic[Pydantic] - %% Test coverage - tests[tests] + %% Strong dependencies - %% Module dependencies routes --> main fastapi --> main + + fastapi --> routes + aiocache --> routes services --> routes models --> routes databases --> routes + schemas --> services models --> services - databases --> schemas - fastapi --> routes - sqlalchemy --> routes sqlalchemy --> services + pydantic --> models + + databases --> schemas sqlalchemy --> schemas sqlalchemy --> databases - pydantic --> models + + %% Soft dependencies + + sqlalchemy -.-> routes main -.-> tests - %% Node styling + %% Node styling with stroke-width classDef core fill:#b3d9ff,stroke:#6db1ff,stroke-width:2px,color:#555,font-family:monospace; classDef deps fill:#ffcccc,stroke:#ff8f8f,stroke-width:2px,color:#555,font-family:monospace; classDef test fill:#ccffcc,stroke:#53c45e,stroke-width:2px,color:#555,font-family:monospace; class main,routes,services,schemas,databases,models core - class fastapi,sqlalchemy,pydantic deps + class fastapi,sqlalchemy,pydantic,aiocache deps class tests test ``` -**Arrow Semantics:** Solid arrows represent import-time module dependencies — the arrow points from the dependency to the consumer. The dotted arrow to `tests` indicates the integration tests validate the full application stack as wired by `main`. +*Simplified, conceptual view — not all components or dependencies are shown.* + +### Arrow Semantics + +Arrows point from a dependency toward its consumer. Solid arrows (`-->`) denote **strong (functional) dependencies**: the consumer actively invokes behavior — registering route handlers, dispatching requests, executing async queries, or managing the database session. Dotted arrows (`-.->`) denote **soft (structural) dependencies**: the consumer only references types without invoking runtime behavior. This distinction follows UML's `«use»` dependency notation and classical coupling theory (Myers, 1978): strong arrows approximate *control or stamp coupling*, while soft arrows approximate *data coupling*, where only shared data structures cross the boundary. + +### Composition Root Pattern + +The `main` module acts as the composition root — it creates the FastAPI application instance, configures the lifespan handler, and registers all route modules via `app.include_router()`. Rather than explicit object construction, dependency injection is provided by FastAPI's built-in `Depends()` mechanism: `routes` declare their dependencies (e.g. `AsyncSession`) as function parameters and FastAPI resolves them at request time. This pattern enables dependency injection, improves testability, and ensures no other module bears responsibility for wiring or lifecycle management. + +### Layered Architecture + +The codebase is organized into four conceptual layers: Initialization (`main`), HTTP (`routes`), Business (`services`), and Data (`schemas`, `databases`). + +Third-party dependencies are co-resident within the layer that consumes them: `FastAPI` and `aiocache` inside HTTP, and `SQLAlchemy` inside Data. `routes` holds a soft dependency on `SQLAlchemy` — `AsyncSession` is referenced only as a type annotation in `Depends()`, without any direct SQLAlchemy method calls at the route level. -**Composition Root Pattern:** The `main` module acts as the composition root — it imports `FastAPI` and the route modules, creates the app instance, and registers all routers. This pattern enables dependency injection via `Depends()`, improves testability, and maintains clear separation of concerns. +The `models` package is a **cross-cutting type concern** — it defines Pydantic request and response models consumed across multiple layers, without containing logic or behavior of its own. Dependencies always flow from consumers toward their lower-level types: each layer depends on (consumes) the layers below it, and no layer invokes behavior in a layer above it. -**Layered Architecture:** Each layer has a specific responsibility — routes handle HTTP mapping, validation, and in-memory caching, services contain business logic, schemas define the ORM model, and databases manage the async session. +### Color Coding -**Color Coding:** Core packages (blue) implement the application logic, external dependencies (red) are third-party frameworks and ORMs, and tests (green) ensure code quality. +Core packages (blue) implement the application logic, third-party dependencies (red) are community packages, and tests (green) ensure code quality. ## API Reference