Phase 7: Hardening — logging, security, Docker, production readiness
Backend:
- Structured JSON logging (python-json-logger) with request ID correlation
- RequestIDMiddleware (server-generated UUID, no client trust)
- Global exception handlers: AppException, RequestValidationError, generic 500
— all return consistent {"error": {code, message, request_id}} format
- Async rate limiting with lock + stale key eviction on auth endpoints
- Health endpoint checks DB connectivity, returns version + status
- Custom exception classes (NotFoundException, ForbiddenException, etc.)
- OpenAPI docs with tag descriptions, conditional URL (disabled in production)
- LOG_LEVEL, DOCS_ENABLED, RATE_LIMIT_* settings added
Docker:
- Backend: multi-stage build (builder + runtime), non-root user, HEALTHCHECK
- Frontend: removed dead user, HEALTHCHECK directive
- docker-compose: restart policies, healthchecks, Redis service, named volumes
for uploads/PDFs, rate limit env vars forwarded
- Alembic migrations run only in Dockerfile CMD (removed from lifespan)
Nginx:
- server_tokens off
- CSP, Referrer-Policy, Permissions-Policy headers
- HSTS ready (commented, enable with TLS)
Config & Docs:
- .env.production.example with production-ready settings
- CLAUDE.md project conventions (structure, workflow, naming, how-to)
- .env.example updated with new variables
Review fixes applied:
- Rate limiter: async lock prevents race condition, stale key eviction
- Request ID: always server-generated (no log injection)
- Removed duplicate alembic migration from lifespan
- Removed dead app user from frontend Dockerfile
- Health check logs DB errors
- Rate limit env vars forwarded in docker-compose
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
83
CLAUDE.md
Normal file
83
CLAUDE.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# AI Assistant - Project Conventions
|
||||
|
||||
## Tech Stack
|
||||
|
||||
- **Backend**: Python 3.12, FastAPI, SQLAlchemy 2.0 (async), Alembic, Pydantic v2
|
||||
- **Frontend**: React 18, TypeScript, Vite, Tailwind CSS, shadcn/ui, Zustand, TanStack Query
|
||||
- **Database**: PostgreSQL 16
|
||||
- **AI**: Claude API (Anthropic SDK) with streaming + tool use
|
||||
- **Deployment**: Docker Compose (nginx, backend, frontend, postgres, redis)
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
backend/
|
||||
app/
|
||||
api/v1/ # FastAPI routers (thin controllers)
|
||||
core/ # Security, middleware, logging, exceptions
|
||||
models/ # SQLAlchemy ORM models (inherit from Base in database.py)
|
||||
schemas/ # Pydantic request/response models
|
||||
services/ # Business logic layer
|
||||
utils/ # Utilities (file storage, text extraction)
|
||||
workers/ # Background tasks (document processing, notifications)
|
||||
templates/ # Jinja2 templates (PDF generation)
|
||||
alembic/ # Database migrations
|
||||
scripts/ # Standalone scripts (seed_admin.py)
|
||||
tests/ # Pytest test files
|
||||
|
||||
frontend/
|
||||
src/
|
||||
api/ # Axios API client modules
|
||||
components/ # React components (layout/, chat/, auth/, shared/, etc.)
|
||||
hooks/ # Custom React hooks
|
||||
stores/ # Zustand state stores
|
||||
pages/ # Page components (mapped to routes)
|
||||
lib/ # Utilities (cn(), query-client)
|
||||
```
|
||||
|
||||
## Adding a New Feature (Endpoint to UI)
|
||||
|
||||
1. **Model**: Create in `backend/app/models/`, inherit `Base` from `database.py`
|
||||
2. **Migration**: `alembic revision -m "description"` or write manually in `alembic/versions/`
|
||||
3. **Schema**: Create Pydantic models in `backend/app/schemas/`
|
||||
4. **Service**: Business logic in `backend/app/services/`
|
||||
5. **Router**: FastAPI endpoint in `backend/app/api/v1/`, register in `router.py`
|
||||
6. **Frontend API**: Typed functions in `frontend/src/api/`
|
||||
7. **Page/Component**: React component in `frontend/src/pages/` or `components/`
|
||||
8. **Route**: Add to `frontend/src/routes.tsx`
|
||||
9. **i18n**: Add keys to both `public/locales/en/` and `ru/translation.json`
|
||||
10. **Tests**: Add to `backend/tests/`
|
||||
|
||||
## Conventions
|
||||
|
||||
- **Auth**: JWT access (15min) + refresh (24h/30d) tokens. Use `get_current_user` dependency.
|
||||
- **Admin**: Use `require_admin` dependency. All admin endpoints under `/api/v1/admin/`.
|
||||
- **Ownership**: Always filter by `user_id` — never expose other users' data.
|
||||
- **Schemas**: Use `model_config = {"from_attributes": True}` for ORM compatibility.
|
||||
- **JSONB columns**: Name the Python attribute `metadata_` with `mapped_column("metadata", JSONB)`.
|
||||
- **Error responses**: Use `HTTPException` or `AppException` subclasses.
|
||||
- **i18n**: All user-facing strings via `useTranslation()`. Both `en` and `ru` required.
|
||||
- **State**: Zustand for client state, TanStack Query for server state.
|
||||
- **Sidebar nav**: Add to `navItems` array in `sidebar.tsx`.
|
||||
|
||||
## Running
|
||||
|
||||
```bash
|
||||
# Development
|
||||
cp .env.example .env
|
||||
docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build
|
||||
|
||||
# Production
|
||||
cp .env.production.example .env
|
||||
docker compose up -d --build
|
||||
|
||||
# Seed admin user
|
||||
docker compose exec backend python scripts/seed_admin.py
|
||||
|
||||
# Run backend tests (requires test DB)
|
||||
docker compose exec backend pytest
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
See `.env.example` for development and `.env.production.example` for production.
|
||||
Reference in New Issue
Block a user