14 KiB
14 KiB
AGENTS.md – HMS Licht & Ton Build & Test Guide
Projekt: hms-licht-ton (ID 30) Stack: Nuxt 3 (Frontend) + FastAPI (Backend) + PostgreSQL + Redis Deployment: Coolify (Docker) auf coolify-01
DESIGN-RICHTLINIEN:
docs/design-rules.md– VERBINDLICH für alle Erweiterungen! Jeder KI-Agent MUSS diese Regeln vor der Implementierung lesen und einhalten.
1. Build & Test Commands
1.1 Frontend (Nuxt 3)
# Install dependencies
cd frontend && npm ci
# Development server (http://localhost:3000)
cd frontend && npm run dev
# Production build
cd frontend && npm run build
# Preview production build
cd frontend && npm run preview
# Generate static site (SSG pages)
cd frontend && npm run generate
# Unit tests (Vitest)
cd frontend && npx vitest run --reporter verbose
# Watch mode
cd frontend && npx vitest
# Coverage report
cd frontend && npx vitest run --coverage
# E2E tests (Playwright)
cd frontend && npx playwright test
# Specific E2E test
cd frontend && npx playwright test --grep 'Mietkatalog'
# Lint
cd frontend && npm run lint
# Type check
cd frontend && npm run typecheck
1.2 Backend (FastAPI)
# Install dependencies
cd backend && pip install -r requirements.txt
# Development server (http://localhost:8000)
cd backend && uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
# Run all tests
cd backend && python -m pytest tests/ -v
# Run with coverage
cd backend && python -m pytest tests/ -v --cov=app --cov-report=term-missing
# Specific test file
cd backend && python -m pytest tests/test_equipment_router.py -v
# Specific test
cd backend && python -m pytest tests/test_rentman_import.py::test_paginated_import -v
# Database migrations
cd backend && alembic upgrade head
cd backend && alembic revision --autogenerate -m "description"
# Seed admin user
cd backend && python -m app.scripts.seed_admin
1.3 Docker / Full Stack
# Build all containers
docker compose build
# Start all services
docker compose up -d
# View logs
docker compose logs -f backend
docker compose logs -f frontend
# Health check
curl -s http://localhost:8000/api/health
# Stop all services
docker compose down
# Reset volumes (DESTRUCTIVE)
docker compose down -v
1.4 Integration Tests (Full Stack)
# Start backend + DB + Redis
docker compose up -d backend postgres redis
# Wait for health
curl -s http://localhost:8000/api/health | grep ok
# Run backend tests
cd backend && python -m pytest tests/ -v
# Start frontend
docker compose up -d frontend
# Run E2E tests
cd frontend && npx playwright test
2. Test Rules (MANDATORY)
2.1 TDD Principle
- Write tests first, then implementation. Tests define the contract.
- Tests MUST be written before or alongside the implementation code.
- Never commit code without corresponding tests.
- Coverage target: >= 80% for all modules.
2.2 Do NOT Modify Tests
- Never modify existing tests to make them pass.
- If a test fails, fix the implementation, not the test.
- Tests are the source of truth for expected behavior.
- If a test is genuinely wrong, flag it in a PR and explain why.
- Only the original test author or a reviewer may modify tests.
2.3 Test File Naming
Frontend:
- Unit tests:
frontend/tests/unit/*.test.ts - E2E tests:
frontend/tests/e2e/*.spec.ts - Fixtures:
frontend/tests/fixtures/* - Mocks:
frontend/tests/mocks/*
Backend:
- Unit/Integration tests:
backend/tests/test_*.py - Fixtures:
backend/tests/conftest.py - Factories:
backend/tests/factories.py - Mocks:
backend/tests/mocks/
2.4 Test Categories
| Category | Tool | Scope | When to Run |
|---|---|---|---|
| Unit | Vitest / Pytest | Functions, composables, stores, services | Every commit |
| Component | Vitest + Vue Test Utils | Vue components, props, emits | Every commit |
| Integration | Pytest + TestClient | API endpoints, DB operations | Every commit |
| E2E | Playwright | Full page flows, forms, navigation | Pre-merge, nightly |
| Smoke | curl scripts | API health, endpoints | Post-deploy |
2.5 Mocking Rules
- Rentman API: Always mock in tests. Never call live Rentman API.
- Use
unittest.mock.patchorresponseslibrary - Mock
GET /equipmentwith paginated test data - Mock
POST /projectrequestswith fake response IDs
- Use
- SMTP: Always mock email sending in tests.
- Mock
aiosmtplib.sendto capture sent emails - Verify email content, not actual delivery
- Mock
- Database: Use SQLite in-memory or test PostgreSQL instance.
- Never run tests against production database
- Use separate test database:
DATABASE_URL=sqlite+aiosqlite:///test.db
3. Coding Conventions
3.1 Frontend (Vue 3 + TypeScript)
// Use Composition API with <script setup>
<script setup lang="ts">
import { ref, computed } from 'vue'
// Props with TypeScript types
const props = defineProps<{
item: EquipmentItem
showBadge?: boolean
}>()
// Emits with TypeScript types
const emit = defineEmits<{
'add-to-cart': [item: EquipmentItem]
'click': [id: number]
}>()
// Refs with types
const loading = ref(false)
const error = ref<string | null>(null)
// Computed
const totalPrice = computed(() => items.value.reduce((sum, i) => sum + i.price, 0))
</script>
Rules:
- Use
<script setup lang="ts">always - Use Composition API (not Options API)
- Use Pinia for global state
- Use
useFetch/useAsyncDatafor SSR data fetching - Use Tailwind utility classes (no custom CSS unless necessary)
- Use design tokens (CSS variables) for colors, spacing, radius
- Components: PascalCase filenames (
EquipmentCard.vue) - Pages: kebab-case filenames (
mietkatalog/[id].vue) - Composables:
useprefix (useEquipment.ts) - Stores:
stores/*.tswith Pinia defineStore
3.2 Backend (Python + FastAPI)
# Use async/await always
async def get_equipment_list(
search: str | None = None,
category: str | None = None,
page: int = 1,
page_size: int = 20,
db: AsyncSession = Depends(get_db),
) -> PaginatedResponse[EquipmentItem]:
...
# Pydantic schemas for all input/output
class EquipmentItem(BaseModel):
id: int
name: str
category: str | None = None
rental_price: Decimal | None = None
available: bool = True
# Type hints everywhere
def calculate_reference_number() -> str:
year = datetime.now().year
random_num = random.randint(1, 99999)
return f"HMS-{year}-{random_num:05d}"
Rules:
- PEP 8 style (line length 100)
- async/await for all I/O operations (DB, Redis, API calls, SMTP)
- Pydantic v2 for all schemas (input validation, output serialization)
- Type hints on all functions and methods
- Routers in
routers/, services inservices/, models inmodels/ - Config via
pydantic-settings(BaseSettings class) - Database: SQLAlchemy async with
asyncpgdriver - No raw SQL in routers (use SQLAlchemy ORM or service layer)
- Error handling: HTTPException with proper status codes
3.3 Naming Conventions
| Type | Frontend | Backend |
|---|---|---|
| Files | kebab-case (mietkatalog.vue) |
snake_case (rentman_import.py) |
| Components | PascalCase (EquipmentCard) |
– |
| Functions | camelCase (getEquipmentList) |
snake_case (get_equipment_list) |
| Variables | camelCase (equipmentList) |
snake_case (equipment_list) |
| Constants | UPPER_SNAKE (API_BASE_URL) |
UPPER_SNAKE (RENTMAN_API_TOKEN) |
| Classes | PascalCase (EquipmentItem) |
PascalCase (EquipmentItem) |
| CSS | kebab-case (.equipment-card) |
– |
| DB Tables | – | snake_case (equipment_cache) |
| API Routes | kebab-case (/api/rental-requests) |
kebab-case (/api/rental-requests) |
3.4 Git Conventions
- Branch naming:
feature/T01-frontend-foundation,fix/equipment-search - Commit messages: Conventional Commits
feat: add equipment search filterfix: correct date validation in rental requesttest: add equipment router testsdocs: update architecture.mdrefactor: extract email servicechore: update dependencies
- PR: Squash merge, one PR per task
- Never commit secrets (.env, credentials)
4. Environment Variables
4.1 Required (.env)
# Rentman
RENTMAN_API_TOKEN=your_token_here
# Auth
JWT_SECRET=your_jwt_secret_here
# Database
DATABASE_URL=postgresql+asyncpg://hms:password@localhost:5432/hms
# Redis
REDIS_URL=redis://localhost:6379/0
# SMTP
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=user@example.com
SMTP_PASSWORD=your_password
SMTP_FROM=info@hms-licht-ton.de
# Frontend
NUXT_PUBLIC_API_BASE=http://localhost:8000/api
4.2 Optional
# Admin seeding
ADMIN_USERNAME=admin
ADMIN_PASSWORD=change_me_in_production
# CORS
CORS_ORIGINS=https://hms.media-on.de
5. Task Dependencies
T01 (Frontend Foundation) ─────┬──> T02 (Static Pages)
├──> T06 (Mietkatalog Frontend) ──> T07 (Cart/Mietanfrage)
│
T03 (Backend Core) ────────────┼──> T04 (Rentman Integration)
├──> T05 (Email/Contact/Rental Backend)
├──> T06 (Mietkatalog Frontend)
│
T08 (Docker/CI/CD) ── depends on ALL ──>
Parallel execution:
- T01 and T03 can start simultaneously (no shared dependencies)
- T02 starts after T01
- T04 starts after T03
- T06 starts after T01 AND T03
- T05 starts after T03 AND T04
- T07 starts after T01 AND T06
- T08 starts after ALL other tasks
6. Quality Gates
6.1 Per-Task Gate
Before a task is marked complete:
- All test_spec.commands pass
- Coverage >= target (80%)
- All acceptance_criteria verified
- Build succeeds (npm run build / pip install)
- No linting errors
- No type errors
6.2 Pre-Merge Gate
- All task tests pass
- E2E tests pass
- Docker build succeeds
- No secrets in code
- Code review approved
6.3 Pre-Deploy Gate
- All E2E tests pass
- Health check returns 200
- Environment variables set in Coolify
- Domain DNS configured
- TLS certificate active
7. Forbidden Patterns
7.1 Frontend
- ❌ Options API (
export default { data() { ... } }) - ❌ Hardcoded colors (use CSS variables / Tailwind config)
- ❌ Inline styles (use Tailwind classes)
- ❌
localStoragedirect access in components (use Pinia store with persist plugin) - ❌ Fetching in
mounted()(useuseAsyncData/useFetchfor SSR) - ❌
anytype (use proper TypeScript types) - ❌ Console.log in production code
- ❌ Large inline SVG (use separate component files)
7.2 Backend
- ❌ Sync I/O in async context (no
requests.get, usehttpx.AsyncClient) - ❌ Raw SQL in routers (use service layer + SQLAlchemy ORM)
- ❌ Hardcoded secrets (use env vars / pydantic-settings)
- ❌
print()in production code (uselogging) - ❌ Missing type hints
- ❌ Missing Pydantic validation (all inputs must be validated)
- ❌ Direct Rentman API calls without going through service layer
- ❌ Missing error handling (no bare
except:) - ❌ Synchronous database operations (use async SQLAlchemy)
8. Project Structure Summary
hms-licht-ton/
├── frontend/ (Nuxt 3 + Tailwind CSS)
│ ├── components/ (Vue 3 SFCs)
│ ├── pages/ (File-based routing)
│ ├── stores/ (Pinia stores)
│ ├── composables/ (useXxx composables)
│ ├── layouts/ (Nuxt layouts)
│ ├── assets/ (CSS, images, SVG)
│ ├── tests/ (Vitest + Playwright)
│ └── nuxt.config.ts
├── backend/ (FastAPI + SQLAlchemy + Redis)
│ ├── app/
│ │ ├── main.py
│ │ ├── config.py
│ │ ├── database.py
│ │ ├── models/ (SQLAlchemy models)
│ │ ├── schemas/ (Pydantic schemas)
│ │ ├── routers/ (API endpoints)
│ │ ├── services/ (Business logic)
│ │ └── cache.py (Redis client)
│ ├── tests/ (Pytest)
│ ├── alembic/ (Migrations)
│ └── Dockerfile
├── docs/ (Architecture, requirements, UI design)
├── docker-compose.yml (4 services)
├── .env.example
├── .forgejo/ (CI/CD workflows)
├── AGENTS.md (This file)
└── README.md
9. Key References
- Architecture:
docs/architecture.md - Task Graph:
docs/task_graph.json - Requirements:
docs/requirements.md - UI Design:
docs/ui_design.md - Component Inventory:
docs/component_inventory.md - Rentman API Skills:
rentman-api-operations+rentman-domain-basics(load before API calls) - Rentman Python Client:
from usr.plugins.rentman.helpers.rentman import RentmanAPI
10. Emergency Procedures
10.1 Backend Down
- Check
docker compose logs backend - Check
docker compose ps(is it running?) - Check
curl http://localhost:8000/api/health - If DB issue:
docker compose restart postgres - If Redis issue:
docker compose restart redis - If app crash:
docker compose restart backend
10.2 Frontend Down
- Check
docker compose logs frontend - Check
docker compose ps docker compose restart frontend- If build issue:
cd frontend && npm run build(check errors)
10.3 Rentman API Unreachable
- Check
RENTMAN_API_TOKENin env vars - Test token:
curl -H "Authorization: Bearer $TOKEN" https://api.rentman.net/equipment - If expired: Generate new token in Rentman UI
- Cached equipment still serves from PostgreSQL + Redis
10.4 Database Reset (DESTRUCTIVE)
docker compose down -v
docker compose up -d
cd backend && alembic upgrade head
python -m app.scripts.seed_admin
11. Handoff
- AGENTS.md status: COMPLETE
- All build commands documented: YES
- Test rules documented: YES
- Conventions documented: YES
- Quality gates defined: YES
- Ready for implementation: YES (after Plan Mode transition to
implementation_allowed)