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:
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user