# Session Note: Module Reclassification & Framework Layer

**Date:** 2026-01-27
**Previous Session:** SESSION_NOTE_2026-01-26_self-contained-modules.md
**Tag:** v0.9.0-pre-framework-refactor

## Summary

Implemented a three-tier module classification system and added core framework infrastructure:

1. **Three-Tier Classification**
   - Core modules (4): Always enabled, cannot be disabled
   - Optional modules (7): Can be enabled/disabled per platform
   - Internal modules (2): Admin-only tools, not customer-facing

2. **Module Renaming**
   - Renamed `platform-admin` → `tenancy`

3. **Core Module Promotion**
   - Promoted CMS and Customers to core (is_core=True)

4. **New Payments Module**
   - Extracted payment gateway logic into standalone module
   - Billing and Orders now depend on Payments

5. **Framework Layer Infrastructure**
   - Module events system (events.py)
   - Module-specific migrations support (migrations.py)
   - Observability framework (observability.py)

---

## Final Module Classification

### Core Modules (4)
| Module | Description |
|--------|-------------|
| `core` | Dashboard, settings, profile |
| `tenancy` | Platform, company, vendor, admin user management |
| `cms` | Content pages, media library, themes |
| `customers` | Customer database, profiles, segmentation |

### Optional Modules (7)
| Module | Dependencies | Description |
|--------|--------------|-------------|
| `payments` | - | Payment gateway integrations (Stripe, PayPal, etc.) |
| `billing` | payments | Platform subscriptions, vendor invoices |
| `inventory` | - | Stock management, locations |
| `orders` | payments | Order management, customer checkout |
| `marketplace` | inventory | Letzshop integration |
| `analytics` | - | Reports, dashboards |
| `messaging` | - | Messages, notifications |

### Internal Modules (2)
| Module | Description |
|--------|-------------|
| `dev-tools` | Component library, icons |
| `monitoring` | Logs, background tasks, Flower, Grafana |

---

## Key Files Modified/Created

### Modified
- `app/modules/registry.py` - Three-tier classification with CORE_MODULES, OPTIONAL_MODULES, INTERNAL_MODULES
- `app/modules/base.py` - Enhanced ModuleDefinition with new fields:
  - `version` - Semantic versioning
  - `is_internal` - Internal module flag
  - `permissions` - Module-specific permissions
  - `config_schema` - Pydantic config validation
  - `default_config` - Default configuration values
  - `migrations_path` - Module-specific migrations
  - Lifecycle hooks: `on_enable`, `on_disable`, `on_startup`, `health_check`
- `app/modules/service.py` - No changes needed (uses registry functions)
- `app/modules/cms/definition.py` - Set is_core=True
- `app/modules/customers/definition.py` - Set is_core=True
- `app/modules/billing/definition.py` - Added requires=["payments"]
- `app/modules/orders/definition.py` - Added requires=["payments"]
- `app/modules/dev_tools/definition.py` - Added is_internal=True
- `app/modules/monitoring/definition.py` - Added is_internal=True
- `alembic/env.py` - Added module migration discovery

### Created
- `app/modules/events.py` - Module event bus
  - ModuleEvent enum (ENABLED, DISABLED, STARTUP, SHUTDOWN, CONFIG_CHANGED)
  - ModuleEventData dataclass
  - ModuleEventBus class with subscribe/emit
- `app/modules/migrations.py` - Module migration utilities
  - discover_module_migrations()
  - get_all_migration_paths()
  - get_migration_order()
  - validate_migration_names()
- `app/core/observability.py` - Observability framework
  - HealthCheckRegistry
  - MetricsRegistry (Prometheus placeholder)
  - SentryIntegration
  - health_router (/health, /metrics, /health/live, /health/ready)
- `app/modules/payments/` - New payments module
  - definition.py
  - services/payment_service.py
  - services/gateway_service.py
  - routes/admin.py, vendor.py
  - schemas/__init__.py
- `alembic/versions/zc2m3n4o5p6q7_rename_platform_admin_to_tenancy.py`
- `alembic/versions/zd3n4o5p6q7r8_promote_cms_customers_to_core.py`

---

## Dependency Graph

```
                    CORE MODULES
    ┌────────────────────────────────────────┐
    │  core  ←  tenancy  ←  cms  ←  customers │
    └────────────────────────────────────────┘

                   OPTIONAL MODULES
    ┌─────────────────────────────────────────┐
    │              payments                    │
    │             ↙       ↘                   │
    │       billing        orders              │
    │                                          │
    │       inventory                          │
    │           ↓                              │
    │      marketplace                         │
    │                                          │
    │    analytics    messaging                │
    └─────────────────────────────────────────┘

                   INTERNAL MODULES
    ┌─────────────────────────────────────────┐
    │     dev-tools       monitoring           │
    └─────────────────────────────────────────┘
```

---

## New Registry Functions

```python
# Module dictionaries
CORE_MODULES: dict[str, ModuleDefinition]
OPTIONAL_MODULES: dict[str, ModuleDefinition]
INTERNAL_MODULES: dict[str, ModuleDefinition]
MODULES: dict[str, ModuleDefinition]  # All combined

# New helper functions
get_optional_module_codes() -> set[str]
get_internal_modules() -> list[ModuleDefinition]
get_internal_module_codes() -> set[str]
is_core_module(code: str) -> bool
is_internal_module(code: str) -> bool
get_modules_by_tier() -> dict[str, list[ModuleDefinition]]
get_module_tier(code: str) -> str | None  # 'core', 'optional', 'internal', None
```

---

## Module Event System

```python
from app.modules.events import module_event_bus, ModuleEvent

# Subscribe to events
@module_event_bus.subscribe(ModuleEvent.ENABLED)
def on_module_enabled(data: ModuleEventData):
    print(f"Module {data.module_code} enabled for platform {data.platform_id}")

# Emit events (done by ModuleService)
module_event_bus.emit_enabled("billing", platform_id=1, user_id=42)
```

---

## Module Migrations

Modules can now have their own migrations in `app/modules/<code>/migrations/versions/`.

Migration naming convention:
```
{module_code}_{sequence}_{description}.py
Example: cms_001_create_content_pages.py
```

Alembic automatically discovers module migrations via `get_all_migration_paths()`.

---

## Observability Framework

```python
from app.core.observability import (
    health_registry,
    metrics_registry,
    sentry,
    init_observability,
)

# Register health check
@health_registry.register("database")
def check_db() -> HealthCheckResult:
    return HealthCheckResult(name="database", status=HealthStatus.HEALTHY)

# Initialize in lifespan
init_observability(
    enable_metrics=True,
    sentry_dsn="...",
    flower_url="http://flower:5555",
)
```

Endpoints:
- `GET /health` - Aggregated health from all checks
- `GET /health/live` - Kubernetes liveness probe
- `GET /health/ready` - Kubernetes readiness probe
- `GET /metrics` - Prometheus metrics
- `GET /health/tools` - External tool URLs (Flower, Grafana)

---

## Payments Module

New standalone module for payment gateway abstractions:

```python
from app.modules.payments.services import PaymentService, GatewayService

payment_service = PaymentService()
result = await payment_service.process_payment(
    amount=1000,  # cents
    currency="EUR",
    payment_method_id="pm_xxx",
)

gateway_service = GatewayService()
gateways = gateway_service.get_available_gateways()
```

**Separation from Billing:**
- **Payments**: Gateway abstractions, payment processing, refunds
- **Billing**: Subscriptions, invoices, tier management (uses Payments)
- **Orders**: Checkout, order payments (uses Payments)

---

## Verification Completed

✅ App starts successfully
✅ Core modules: core, tenancy, cms, customers
✅ Optional modules: payments, billing, inventory, orders, marketplace, analytics, messaging
✅ Internal modules: dev-tools, monitoring
✅ Dependencies validated (billing→payments, orders→payments, marketplace→inventory)
✅ Module event bus working
✅ Observability framework working
✅ Migration discovery working

---

## Next Steps

1. **Phase 6: Make Customers Self-Contained** (deferred)
   - Move models, services to app/modules/customers/
   - Create module-specific migrations

2. **Database Migrations**
   - Run: `alembic upgrade head`
   - This will rename platform-admin → tenancy in platform_modules

3. **Integrate Observability**
   - Add health_router to main.py
   - Initialize observability in lifespan

4. **Add Module Health Checks**
   - Implement health_check on modules that need monitoring
   - Call register_module_health_checks() on startup

5. **Payments Module Implementation**
   - Implement actual Stripe/PayPal gateway logic
   - Add Payment, Transaction models
   - Create module migrations
