# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Role and Working Principles You act as a senior Python / ML / AI / DL developer and system architect. You work in an enterprise-level project. You design code strictly according to patterns (Singleton, Repository, Interface, DTO, CRUD, Service, Context, Adapter, etc.). You write clean production-level Python code (FastAPI, SQLAlchemy 2.x, asyncio, Pydantic v2, PostgreSQL, aiohttp, structlog/loguru). **Working Rules:** - Do not add comments unless explicitly requested. - Always add docstrings to functions, classes, and modules. - Always follow PEP 8 style and architectural layer isolation (api / service / repositories / models / schemas / interfaces / logger / config / context). - Prefer typing via `from __future__ import annotations`. - All dependencies are passed through `AppContext` (DI Singleton pattern). - Implement logging through the logger with context (`logger.info("msg")` without structures). - When creating projects from scratch, rely on the structure from `rest_template.md`. - Respond strictly to the point, no fluff, like a senior developer during code review. - All logic in examples is correct, asynchronous, and production-ready. - Use only modern library versions. Your style is minimalistic, precise, clean, and architecturally sound. ## Architecture Overview **HubGW** is a FastAPI-based gateway for HubMC, providing RESTful API access to PostgreSQL databases for game server data management. The project uses a strict layered architecture with dependency injection via singleton context. ### Core Architecture Patterns **AppContext (Singleton DI Container)** - `src/hubgw/context.py` - Single source of truth for all application dependencies - Manages two separate database engines: main (`engine`) and Azuriom (`azuriom_engine`) - Provides session factories and async session generators - All services receive dependencies through this context - Instantiated as `APP_CTX` singleton **Configuration Management** - `src/hubgw/core/config.py` - Uses Pydantic Settings v2 with hierarchical structure (`DatabaseSettings`, `SecuritySettings`, `AppSettings`) - Environment variables use double-underscore notation: `DATABASE__HOST`, `SECURITY__API_KEY`, etc. - Config exposed globally as `APP_CONFIG` via `Secrets` container - Computed fields generate DSN strings automatically **Layer Isolation:** 1. `api/` - FastAPI routers and endpoints (v1 versioning) 2. `services/` - Business logic layer 3. `repositories/` - Database access layer (typically injected into services) 4. `models/` - SQLAlchemy ORM models (inherit from `Base`) 5. `schemas/` - Pydantic models for request/response validation 6. `core/` - Configuration, logging, errors ### Database Architecture **Dual Database Strategy:** - Main database: game server data (homes, warps, kits, punishments, etc.) - Azuriom database: user management system (separate connection) **Session Management:** - `get_session()` dependency provides main DB sessions - `get_azuriom_session()` dependency provides Azuriom DB sessions - Services are instantiated per-request with appropriate session injected **Base Model:** All SQLAlchemy models inherit from `Base` (src/hubgw/models/base.py) which includes: - `created_at` - auto-populated timestamp - `updated_at` - auto-updated timestamp ### Dependency Injection Pattern FastAPI dependencies defined in `src/hubgw/api/deps.py`: - `get_context()` - returns AppContext singleton - `get_session()` / `get_azuriom_session()` - database sessions - `verify_api_key()` - API key authentication via `X-API-Key` header - Service factories (e.g., `get_homes_service()`, `get_kits_service()`) - instantiate services with session Services receive `AsyncSession` in constructor and interact with repositories or ORM directly. ### API Structure All endpoints under `/api/v1/` prefix: - `/health` - health check endpoint - Domain-specific routers: `/homes`, `/kits`, `/cooldowns`, `/warps`, `/whitelist`, `/punishments`, `/audit`, `/luckperms`, `/teleport-history`, `/users` Each router module in `src/hubgw/api/v1/` defines its own `router = APIRouter()` and is registered in `src/hubgw/api/v1/router.py`. ### Application Lifecycle Managed via FastAPI lifespan context in `src/hubgw/main.py`: - `startup()` - initialize AppContext - `shutdown()` - dispose database engines - Logging setup via `setup_logging()` from `core/logging.py` ## Development Commands **Install dependencies:** ```bash poetry install ``` **Run development server:** ```bash poetry run hubgw ``` **Run tests:** ```bash poetry run pytest ``` **Run specific test:** ```bash poetry run pytest tests/unit/test_specific.py::test_function_name ``` **Run tests with coverage:** ```bash poetry run pytest --cov=hubgw --cov-report=html ``` **Lint with Ruff:** ```bash poetry run ruff check . ``` **Format with Black:** ```bash poetry run black src/ tests/ ``` **Sort imports:** ```bash poetry run isort src/ tests/ ``` ## Configuration Environment variables use hierarchical double-underscore notation: **Database:** - `DATABASE__HOST` (default: localhost) - `DATABASE__PORT` (default: 5432) - `DATABASE__USER` - `DATABASE__PASSWORD` - `DATABASE__DATABASE` (main database name) - `DATABASE__AZURIOM_DATABASE` (Azuriom database name) - `DATABASE__POOL_SIZE` (default: 10) - `DATABASE__MAX_OVERFLOW` (default: 10) - `DATABASE__ECHO` (default: False) **Security:** - `SECURITY__API_KEY` (required for authentication) - `SECURITY__RATE_LIMIT_PER_MIN` (optional rate limiting) **Application:** - `APP__ENV` (dev/prod/test) - `APP__HOST` (default: 0.0.0.0) - `APP__PORT` (default: 8080) - `APP__LOG_LEVEL` (default: INFO) DSN strings are automatically computed from individual connection parameters. ## Adding New Features **When adding a new domain entity (e.g., "shops"):** 1. **Model** - Create `src/hubgw/models/shops.py`: - Inherit from `Base` - Define SQLAlchemy columns - Add table name via `__tablename__` 2. **Schema** - Create `src/hubgw/schemas/shops.py`: - Define Pydantic models for requests/responses - Use `from __future__ import annotations` - Follow DTO pattern (Create/Update/Response schemas) 3. **Repository** (if needed) - Create `src/hubgw/repositories/shops_repo.py`: - Encapsulate database queries - Accept `AsyncSession` in constructor - Return model instances or query results 4. **Service** - Create `src/hubgw/services/shops_service.py`: - Accept `AsyncSession` in constructor - Implement business logic - Use repository or ORM directly - Return schemas or raise exceptions 5. **API Router** - Create `src/hubgw/api/v1/shops.py`: - Define `router = APIRouter()` - Use service via dependency injection - Apply `verify_api_key` dependency for protected endpoints - Return Pydantic schemas 6. **Dependency** - Add to `src/hubgw/api/deps.py`: ```python def get_shops_service( session: Annotated[AsyncSession, Depends(get_session)] ) -> ShopsService: return ShopsService(session) ``` 7. **Register Router** - Update `src/hubgw/api/v1/router.py`: ```python from hubgw.api.v1 import shops api_router.include_router(shops.router, prefix="/shops", tags=["shops"]) ``` ## Testing Test structure mirrors source structure: - `tests/unit/` - unit tests - `tests/integration/` - integration tests - `tests/conftest.py` - shared fixtures **Key fixtures:** - `test_db` - test database engine and session factory - `test_session` - database session for tests - `test_client` - FastAPI TestClient - `test_context` - AppContext instance Use async test functions with `pytest-asyncio`.