7.5 KiB
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_CTXsingleton
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_CONFIGviaSecretscontainer - Computed fields generate DSN strings automatically
Layer Isolation:
api/- FastAPI routers and endpoints (v1 versioning)services/- Business logic layerrepositories/- Database access layer (typically injected into services)models/- SQLAlchemy ORM models (inherit fromBase)schemas/- Pydantic models for request/response validationcore/- 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 sessionsget_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 timestampupdated_at- auto-updated timestamp
Dependency Injection Pattern
FastAPI dependencies defined in src/hubgw/api/deps.py:
get_context()- returns AppContext singletonget_session()/get_azuriom_session()- database sessionsverify_api_key()- API key authentication viaX-API-Keyheader- 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 AppContextshutdown()- dispose database engines- Logging setup via
setup_logging()fromcore/logging.py
Development Commands
Install dependencies:
poetry install
Run development server:
poetry run hubgw
Run tests:
poetry run pytest
Run specific test:
poetry run pytest tests/unit/test_specific.py::test_function_name
Run tests with coverage:
poetry run pytest --cov=hubgw --cov-report=html
Lint with Ruff:
poetry run ruff check .
Format with Black:
poetry run black src/ tests/
Sort imports:
poetry run isort src/ tests/
Configuration
Environment variables use hierarchical double-underscore notation:
Database:
DATABASE__HOST(default: localhost)DATABASE__PORT(default: 5432)DATABASE__USERDATABASE__PASSWORDDATABASE__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"):
-
Model - Create
src/hubgw/models/shops.py:- Inherit from
Base - Define SQLAlchemy columns
- Add table name via
__tablename__
- Inherit from
-
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)
-
Repository (if needed) - Create
src/hubgw/repositories/shops_repo.py:- Encapsulate database queries
- Accept
AsyncSessionin constructor - Return model instances or query results
-
Service - Create
src/hubgw/services/shops_service.py:- Accept
AsyncSessionin constructor - Implement business logic
- Use repository or ORM directly
- Return schemas or raise exceptions
- Accept
-
API Router - Create
src/hubgw/api/v1/shops.py:- Define
router = APIRouter() - Use service via dependency injection
- Apply
verify_api_keydependency for protected endpoints - Return Pydantic schemas
- Define
-
Dependency - Add to
src/hubgw/api/deps.py:def get_shops_service( session: Annotated[AsyncSession, Depends(get_session)] ) -> ShopsService: return ShopsService(session) -
Register Router - Update
src/hubgw/api/v1/router.py: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 teststests/integration/- integration teststests/conftest.py- shared fixtures
Key fixtures:
test_db- test database engine and session factorytest_session- database session for teststest_client- FastAPI TestClienttest_context- AppContext instance
Use async test functions with pytest-asyncio.