feat: implement DashboardWidgetProvider pattern for modular dashboard widgets

Add protocol-based widget system following the MetricsProvider pattern:

- Create DashboardWidgetProviderProtocol in contracts/widgets.py
- Add WidgetAggregatorService in core to discover and aggregate widgets
- Implement MarketplaceWidgetProvider for recent_imports widget
- Implement TenancyWidgetProvider for recent_vendors widget
- Update admin dashboard to use widget_aggregator
- Add widget_provider field to ModuleDefinition

Architecture documentation:
- Add widget-provider-pattern.md with implementation guide
- Add cross-module-import-rules.md enforcing core/optional separation
- Update module-system.md with widget_provider and import rules

This enables modules to provide rich dashboard widgets without core modules
importing from optional modules, maintaining true module independence.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-04 19:01:23 +01:00
parent a8fae0fbc7
commit 3e38db79aa
13 changed files with 1906 additions and 25 deletions

View File

@@ -25,12 +25,13 @@ The Wizamart platform uses a **plug-and-play modular architecture** where module
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ CORE MODULES (Always Enabled) │ │
│ │ core tenancy cms customers │ │
│ │ contracts │ core tenancy cms customers │ billing │ │ │
│ │ payments │ messaging │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ OPTIONAL MODULES (Per-Platform) │ │
│ │ payments │ billing │ inventory │ ordersmarketplace │ ...│ │
│ │ analytics │ inventory │ catalogcart │ checkout │ ... │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
@@ -72,7 +73,7 @@ touch app/modules/mymodule/exceptions.py
## Three-Tier Classification
### Core Modules (5)
### Core Modules (8)
Core modules are **always enabled** and cannot be disabled. They provide fundamental platform functionality.
@@ -83,24 +84,29 @@ Core modules are **always enabled** and cannot be disabled. They provide fundame
| `cms` | Content pages, media library, themes | Content management | 5 |
| `customers` | Customer database, profiles, segmentation | Customer data management | 4 |
| `tenancy` | Platform, company, vendor, admin user management | Multi-tenant infrastructure | 4 |
| `billing` | Platform subscriptions, tier limits, vendor invoices | Subscription management, tier-based feature gating | 5 |
| `payments` | Payment gateway integrations (Stripe, PayPal, etc.) | Payment processing, required for billing | 3 |
| `messaging` | Messages, notifications, email templates | Email for registration, password reset, notifications | 3 |
### Optional Modules (11)
**Why these are core:**
- **billing**: Tier limits affect many features (team size, product limits, email providers). Subscription management is fundamental.
- **payments**: Required by billing for subscription payment processing.
- **messaging**: Email is required for user registration, password reset, and team invitations.
### Optional Modules (8)
Optional modules can be **enabled or disabled per platform**. They provide additional functionality that may not be needed by all platforms.
| Module | Dependencies | Description | Permissions |
|--------|--------------|-------------|-------------|
| `analytics` | - | Reports, dashboards | 3 |
| `billing` | `payments` | Platform subscriptions, vendor invoices | 5 |
| `analytics` | - | Reports, dashboards, advanced statistics | 3 |
| `cart` | `inventory` | Shopping cart management, session-based carts | 2 |
| `catalog` | `inventory` | Customer-facing product browsing | 6 |
| `checkout` | `cart`, `orders`, `payments`, `customers` | Cart-to-order conversion, checkout flow | 2 |
| `checkout` | `cart`, `orders`, `customers` | Cart-to-order conversion, checkout flow | 2 |
| `inventory` | - | Stock management, locations | 3 |
| `loyalty` | `customers` | Stamp/points loyalty programs, wallet integration | 4 |
| `marketplace` | `inventory` | Letzshop integration | 3 |
| `messaging` | - | Messages, notifications | 3 |
| `orders` | `payments` | Order management, customer checkout | 4 |
| `payments` | - | Payment gateway integrations (Stripe, PayPal, etc.) | 3 |
| `marketplace` | `inventory` | Letzshop integration, product import/export | 3 |
| `orders` | - | Order management, customer checkout | 4 |
### Internal Modules (2)
@@ -243,6 +249,7 @@ analytics_module = ModuleDefinition(
| `is_internal` | `bool` | Admin-only if True |
| `is_self_contained` | `bool` | Uses self-contained structure |
| `metrics_provider` | `Callable` | Factory function returning MetricsProviderProtocol (see [Metrics Provider Pattern](metrics-provider-pattern.md)) |
| `widget_provider` | `Callable` | Factory function returning DashboardWidgetProviderProtocol (see [Widget Provider Pattern](widget-provider-pattern.md)) |
## Route Auto-Discovery
@@ -308,22 +315,27 @@ The Framework Layer provides infrastructure that modules depend on. These are **
Modules can depend on other modules. When enabling a module, its dependencies are automatically enabled.
```
payments
↙ ↘
billing orders ←──┐
inventory │ │
↓ cart │
marketplace ↘ │
checkout
CORE MODULES (always enabled):
┌─────────────────────────────────────────────────────────┐
contracts core tenancy cms customers │
billing ← payments messaging
└─────────────────────────────────────────────────────────┘
OPTIONAL MODULES (dependencies shown):
inventory
↙ ↓ ↘
catalog cart marketplace
checkout ← orders
```
**Dependency Rules:**
1. Core modules cannot depend on optional modules
1. **Core modules NEVER import from optional modules** (see [Cross-Module Import Rules](cross-module-import-rules.md))
2. Enabling a module auto-enables its dependencies
3. Disabling a module auto-disables modules that depend on it
4. Circular dependencies are not allowed
5. Use protocol patterns (Metrics/Widget Provider) for cross-module data
## Module Registry
@@ -347,7 +359,7 @@ billing = get_module("billing")
tier = get_module_tier("billing") # Returns "optional"
# Get all core module codes
core_codes = get_core_module_codes() # {"core", "tenancy", "cms", "customers"}
core_codes = get_core_module_codes() # {"contracts", "core", "tenancy", "cms", "customers", "billing", "payments", "messaging"}
```
## Module Service
@@ -1252,16 +1264,20 @@ python scripts/validate_architecture.py
### Don't
- Create circular dependencies
- Make core modules depend on optional modules
- **Make core modules import from optional modules** (use provider patterns instead)
- Put framework-level code in modules
- Skip migration naming conventions
- Forget `__init__.py` in tasks directory
- Manually register modules in registry.py (use auto-discovery)
- Import optional modules at the top of core module files
- Use direct imports when a protocol pattern exists
## Related Documentation
- [Creating Modules](../development/creating-modules.md) - Step-by-step guide
- [Cross-Module Import Rules](cross-module-import-rules.md) - Import constraints and patterns
- [Metrics Provider Pattern](metrics-provider-pattern.md) - Dashboard statistics architecture
- [Widget Provider Pattern](widget-provider-pattern.md) - Dashboard widgets architecture
- [Menu Management](menu-management.md) - Sidebar configuration
- [Observability](observability.md) - Health checks integration
- [Feature Gating](../implementation/feature-gating-system.md) - Tier-based access