222 lines
7.5 KiB
Markdown
222 lines
7.5 KiB
Markdown
# 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`.
|