refactor: migrate remaining routes to modules and enforce auto-discovery

MIGRATION:
- Delete app/api/v1/vendor/analytics.py (duplicate - analytics module already auto-discovered)
- Move usage routes from app/api/v1/vendor/usage.py to billing module
- Move onboarding routes from app/api/v1/vendor/onboarding.py to marketplace module
- Move features routes to billing module (admin + vendor)
- Move inventory routes to inventory module (admin + vendor)
- Move marketplace/letzshop routes to marketplace module
- Move orders routes to orders module
- Delete legacy letzshop service files (moved to marketplace module)

DOCUMENTATION:
- Add docs/development/migration/module-autodiscovery-migration.md with full migration history
- Update docs/architecture/module-system.md with Entity Auto-Discovery Reference section
- Add detailed sections for each entity type: routes, services, models, schemas, tasks,
  exceptions, templates, static files, locales, configuration

ARCHITECTURE VALIDATION:
- Add MOD-016: Routes must be in modules, not app/api/v1/
- Add MOD-017: Services must be in modules, not app/services/
- Add MOD-018: Tasks must be in modules, not app/tasks/
- Add MOD-019: Schemas must be in modules, not models/schema/
- Update scripts/validate_architecture.py with _validate_legacy_locations method
- Update .architecture-rules/module.yaml with legacy location rules

These rules enforce that all entities must be in self-contained modules.
Legacy locations now trigger ERROR severity violations.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-31 14:25:59 +01:00
parent e2cecff014
commit 401db56258
52 changed files with 1160 additions and 4968 deletions

View File

@@ -419,3 +419,133 @@ module_rules:
required_files:
- "__init__.py"
- "versions/__init__.py"
# =========================================================================
# Legacy Location Rules (Auto-Discovery Enforcement)
# =========================================================================
- id: "MOD-016"
name: "Routes must be in modules, not app/api/v1/"
severity: "error"
description: |
All API routes must be defined in module directories, not in legacy
app/api/v1/vendor/ or app/api/v1/admin/ locations.
WRONG (legacy location):
app/api/v1/vendor/orders.py
app/api/v1/admin/orders.py
RIGHT (module location):
app/modules/orders/routes/api/vendor.py
app/modules/orders/routes/api/admin.py
Routes in modules are auto-discovered and registered. Legacy routes
require manual registration and don't follow module patterns.
EXCEPTIONS (allowed in legacy):
- __init__.py (router aggregation)
- auth.py (core authentication - will move to tenancy)
- Files with # noqa: mod-016 comment
WHY THIS MATTERS:
- Auto-discovery: Module routes are automatically registered
- Encapsulation: Routes belong with their domain logic
- Consistency: All modules follow the same pattern
- Maintainability: Easier to understand module boundaries
pattern:
prohibited_locations:
- "app/api/v1/vendor/*.py"
- "app/api/v1/admin/*.py"
exceptions:
- "__init__.py"
- "auth.py"
- id: "MOD-017"
name: "Services must be in modules, not app/services/"
severity: "error"
description: |
All business logic services must be defined in module directories,
not in the legacy app/services/ location.
WRONG (legacy location):
app/services/order_service.py
RIGHT (module location):
app/modules/orders/services/order_service.py
EXCEPTIONS (allowed in legacy):
- __init__.py (re-exports for backwards compatibility)
- Files that are pure re-exports from modules
- Files with # noqa: mod-017 comment
WHY THIS MATTERS:
- Encapsulation: Services belong with their domain
- Clear boundaries: Know which module owns which service
- Testability: Can test modules in isolation
- Refactoring: Easier to move/rename modules
pattern:
prohibited_locations:
- "app/services/*.py"
exceptions:
- "__init__.py"
- id: "MOD-018"
name: "Tasks must be in modules, not app/tasks/"
severity: "error"
description: |
All Celery background tasks must be defined in module directories,
not in the legacy app/tasks/ location.
WRONG (legacy location):
app/tasks/subscription_tasks.py
RIGHT (module location):
app/modules/billing/tasks/subscription.py
The module tasks/ directory must have __init__.py for Celery
autodiscovery to work.
EXCEPTIONS (allowed in legacy):
- __init__.py (Celery app configuration)
- dispatcher.py (task routing infrastructure)
- Files with # noqa: mod-018 comment
WHY THIS MATTERS:
- Auto-discovery: Celery finds tasks from module directories
- Encapsulation: Tasks belong with their domain logic
- Consistency: All async operations in one place per module
pattern:
prohibited_locations:
- "app/tasks/*.py"
exceptions:
- "__init__.py"
- "dispatcher.py"
- id: "MOD-019"
name: "Schemas must be in modules, not models/schema/"
severity: "error"
description: |
All Pydantic schemas must be defined in module directories,
not in the legacy models/schema/ location.
WRONG (legacy location):
models/schema/order.py
RIGHT (module location):
app/modules/orders/schemas/order.py
EXCEPTIONS (allowed in legacy):
- __init__.py (re-exports for backwards compatibility)
- auth.py (core authentication schemas)
- Files with # noqa: mod-019 comment
WHY THIS MATTERS:
- Encapsulation: Schemas belong with their domain
- Co-location: Request/response schemas near route handlers
- Clear ownership: Know which module owns which schema
pattern:
prohibited_locations:
- "models/schema/*.py"
exceptions:
- "__init__.py"
- "auth.py"