Manual deploys had been using a bare `git pull && docker compose up -d
--build api` sequence, which works for the container itself but silently
skipped writing `.build-info`. The stale `.build-info` left
`?v=<commit-sha>` pointing at the previous deploy's SHA on every shared
JS/CSS URL — so browsers happily kept cached pre-fix assets even after
a successful rebuild. Bit us today: ~5 hours of "is this even deployed?"
debugging on the loyalty-dashboard redirect-flicker fix.
deploy.sh wasn't a substitute because it's a CI/CD script: stashes
working tree, runs alembic, restarts every service in the full profile
(db, redis, api, celery-worker, celery-beat, flower), 60s health budget.
Heavy and disruptive for an api-only hotfix.
New scripts/deploy-api-only.sh fills the gap with the narrow path:
- Refuses if working tree is dirty (no silent stash → no pop conflicts).
- git pull --ff-only.
- Writes .build-info (the critical missing step).
- docker compose -f docker-compose.yml --profile full up -d --build api
(only the api service — db/redis/celery untouched).
- Tight 30s health budget since DB doesn't need to come back up.
- Exit codes 0/1/2/3 for clean automation.
docs/deployment/hetzner-server-setup.md §16.5 split into 16.5a
(code-only — points at the new script as the default) and 16.5b
(full deploy fallback — kept the existing deploy.sh path for migrations
/ Dockerfile / docker-compose / requirements changes). §12 footnote on
.build-info refreshed to mention both scripts.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Architecture Validation Scripts
This directory contains scripts for validating and enforcing architectural patterns across the codebase.
Architecture Validator
Overview
validate_architecture.py is an automated tool that checks the codebase against architectural rules defined in .architecture-rules.yaml.
Key Features
- API Endpoint Validation: Ensures proper separation of concerns, Pydantic usage, exception handling
- Service Layer Validation: Enforces domain exceptions, database session patterns
- Model Validation: Checks proper separation of SQLAlchemy and Pydantic models
- Exception Handling: Validates proper exception patterns
- JavaScript Patterns: Enforces coding standards for frontend code
- Template Validation: Ensures templates follow required patterns
Usage
# Validate entire codebase
python scripts/validate/validate_architecture.py
# Validate specific directory
python scripts/validate/validate_architecture.py app/api/
# Verbose output with code context
python scripts/validate/validate_architecture.py --verbose
# Show only errors (suppress warnings)
python scripts/validate/validate_architecture.py --errors-only
# Use custom config file
python scripts/validate/validate_architecture.py --config custom-rules.yaml
Exit Codes
0: Validation passed (warnings allowed)1: Validation failed (errors found)
Integration with Pre-commit
Install pre-commit hooks to run validation automatically:
# Install pre-commit
pip install pre-commit
# Setup hooks
pre-commit install
# Run manually on all files
pre-commit run --all-files
# Run on staged files only
pre-commit run
Configuration
The validation rules are defined in .architecture-rules.yaml at the project root. This file contains:
- Core Principles: Separation of concerns, type safety, exception handling
- API Endpoint Rules: (API-001 through API-004)
- Service Layer Rules: (SVC-001 through SVC-004)
- Model Rules: (MDL-001 through MDL-002)
- Exception Rules: (EXC-001 through EXC-002)
- JavaScript Rules: (JS-001 through JS-003)
- Template Rules: (TPL-001)
Rule Categories
API Endpoint Rules
- API-001: Use Pydantic models for request/response
- API-002: No business logic in endpoints
- API-003: Proper exception handling (catch and convert to HTTPException)
- API-004: Authentication on protected endpoints
Service Layer Rules
- SVC-001: No HTTPException in services (use domain exceptions)
- SVC-002: Create custom exception classes (avoid generic Exception)
- SVC-003: Database session as parameter (not created internally)
- SVC-004: Use Pydantic for input validation
Model Rules
- MDL-001: Use SQLAlchemy Base for database models
- MDL-002: Separate Pydantic from SQLAlchemy models
Exception Rules
- EXC-001: Define custom exceptions in exceptions module
- EXC-002: Never use bare except
JavaScript Rules
- JS-001: Use apiClient directly (not window.apiClient)
- JS-002: Use centralized logger (not console)
- JS-003: Alpine components must spread ...data()
Example Output
🔍 Starting architecture validation...
📡 Validating API endpoints...
🔧 Validating service layer...
📦 Validating models...
⚠️ Validating exception handling...
🟨 Validating JavaScript...
📄 Validating templates...
================================================================================
📊 ARCHITECTURE VALIDATION REPORT
================================================================================
Files checked: 145
Total violations: 3
❌ ERRORS (2):
--------------------------------------------------------------------------------
[API-002] Endpoint must NOT contain business logic
File: app/api/v1/admin/stores.py:45
Issue: Database operations should be in service layer
💡 Suggestion: Move database operations to service layer
[SVC-001] Service must NOT raise HTTPException
File: app/services/store_service.py:78
Issue: Service raises HTTPException - use domain exceptions instead
💡 Suggestion: Create custom exception class (e.g., StoreNotFoundError) and raise that
⚠️ WARNINGS (1):
--------------------------------------------------------------------------------
[JS-001] Use apiClient directly
File: static/admin/js/stores.js:23
Issue: Use apiClient directly instead of window.apiClient
💡 Suggestion: Replace window.apiClient with apiClient
================================================================================
❌ VALIDATION FAILED - Fix errors before committing
================================================================================
CI/CD Integration
Add to your CI pipeline (GitHub Actions example):
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
validate-architecture:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install dependencies
run: |
pip install pyyaml
- name: Validate Architecture
run: |
python scripts/validate/validate_architecture.py
Documentation
For detailed architectural patterns and examples, see:
Extending the Validator
To add new rules:
- Add rule definition to
.architecture-rules.yaml - Implement validation logic in
validate_architecture.py - Add examples to
docs/architecture/architecture-patterns.md - Test with
python scripts/validate/validate_architecture.py --verbose
Troubleshooting
Issue: Validator reports false positives
Solution: Add exception patterns to .architecture-rules.yaml under ignore section
Issue: Validator doesn't catch a specific violation
Solution: The rule might not be implemented yet. Check .architecture-rules.yaml and validate_architecture.py to add the rule.
Issue: Pre-commit hook fails but manual run passes
Solution: Ensure pre-commit is using the same Python environment:
pre-commit clean
pre-commit install
Contributing
When adding new architectural patterns:
- Document the pattern in
docs/architecture/architecture-patterns.md - Add validation rule to
.architecture-rules.yaml - Implement validation in
validate_architecture.py - Test thoroughly with existing codebase
- Update this README with the new rule
Questions? See the Architecture Patterns Documentation