hubmc-datagw/CLAUDE.md

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_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:

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__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:

    def get_shops_service(
        session: Annotated[AsyncSession, Depends(get_session)]
    ) -> ShopsService:
        return ShopsService(session)
    
  7. 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 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.