feat(subscriptions): migrate subscription management to merchant level and seed tiers
Move subscription create/edit from store detail (broken endpoint) to merchant detail page with proper modal UI. Seed 4 subscription tiers (Essential, Professional, Business, Enterprise) in init_production.py. Also includes cross-module dependency declarations, store domain platform_id migration, platform context middleware, CMS route fixes, and migration backups. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,239 @@
|
||||
# Session Note: IMPORT-002 Cross-Module Dependency Cleanup
|
||||
|
||||
**Date:** 2026-02-09
|
||||
**Status:** Part A complete, Part B deferred
|
||||
**Priority:** Medium — architecture cleanup (no runtime crashes, but undeclared dependencies)
|
||||
**Follows:** SESSION_NOTE_2026-02-03_module-dependency-redesign.md
|
||||
|
||||
---
|
||||
|
||||
## Context
|
||||
|
||||
After fixing all IMPORT-001 violations (core → optional) in previous sessions, the architecture validator now passes with **0 errors and 40 IMPORT-002 warnings**. These are all optional → optional cross-module imports without declared dependencies.
|
||||
|
||||
Billing module is fully clean — zero violations.
|
||||
|
||||
---
|
||||
|
||||
## Current `requires=[]` Declarations
|
||||
|
||||
| Module | Currently declares |
|
||||
|--------|--------------------|
|
||||
| catalog | `requires=["inventory"]` |
|
||||
| marketplace | `requires=["inventory"]` |
|
||||
| orders | `requires=["payments"]` |
|
||||
| inventory | *(nothing)* |
|
||||
| cart | `requires=["inventory"]` |
|
||||
| analytics | *(nothing)* |
|
||||
|
||||
---
|
||||
|
||||
## Part A: Declare Dependencies (30 warnings — trivial fixes)
|
||||
|
||||
These are **hard dependencies** where the source module fundamentally cannot function without the target. Fix is adding to `requires=[]` in each module's `definition.py`.
|
||||
|
||||
### A1. marketplace → add `catalog`, `orders`
|
||||
|
||||
**Change:** `requires=["inventory"]` → `requires=["inventory", "catalog", "orders"]`
|
||||
**File:** `app/modules/marketplace/definition.py`
|
||||
**Warnings resolved:** 9
|
||||
|
||||
| File | Imports from | What |
|
||||
|------|-------------|------|
|
||||
| `services/marketplace_product_service.py:862-863` | catalog | `Product` model |
|
||||
| `services/letzshop_export_service.py:16` | catalog | `Product` model |
|
||||
| `services/letzshop/order_service.py:26-27` | catalog, orders | `Order`, `OrderItem`, `Product` models |
|
||||
| `services/letzshop/order_service.py:17` | orders | `order_service` |
|
||||
| `services/marketplace_product_service.py:1006` | orders | order-related import |
|
||||
| `routes/api/admin_letzshop.py:23-24` | orders | `OrderHasUnresolvedExceptionsException`, `order_item_exception_service` |
|
||||
| `routes/api/store_letzshop.py:24-25` | orders | `OrderHasUnresolvedExceptionsException`, `order_item_exception_service` |
|
||||
|
||||
**Rationale:** Marketplace syncs products and imports orders from Letzshop. No products or orders = no marketplace.
|
||||
|
||||
---
|
||||
|
||||
### A2. orders → add `catalog`, `inventory`
|
||||
|
||||
**Change:** `requires=["payments"]` → `requires=["payments", "catalog", "inventory"]`
|
||||
**File:** `app/modules/orders/definition.py`
|
||||
**Warnings resolved:** 9
|
||||
|
||||
| File | Imports from | What |
|
||||
|------|-------------|------|
|
||||
| `services/order_item_exception_service.py:22,26` | catalog | `ProductNotFoundException`, `Product` |
|
||||
| `services/order_service.py:51` | catalog | `Product` model |
|
||||
| `services/order_inventory_service.py:17-28` | inventory | `Inventory`, `InventoryTransaction`, `TransactionType`, exceptions, schemas, service (6 imports) |
|
||||
| `services/order_service.py:29` | inventory | `InsufficientInventoryException` |
|
||||
|
||||
**Rationale:** Order line items reference products. Order fulfillment manages stock via `order_inventory_service.py`. Both are fundamental.
|
||||
|
||||
---
|
||||
|
||||
### A3. inventory → add `catalog`
|
||||
|
||||
**Change:** `requires=[]` → `requires=["catalog"]`
|
||||
**File:** `app/modules/inventory/definition.py`
|
||||
**Warnings resolved:** 7
|
||||
|
||||
| File | Imports from | What |
|
||||
|------|-------------|------|
|
||||
| `services/inventory_service.py:15,33` | catalog | `ProductNotFoundException`, `Product` |
|
||||
| `services/inventory_transaction_service.py:14,19` | catalog | `ProductNotFoundException`, `Product` |
|
||||
| `services/inventory_import_service.py:27` | catalog | `Product` |
|
||||
|
||||
**Rationale:** Every inventory record tracks stock for a product. No products = no inventory.
|
||||
|
||||
---
|
||||
|
||||
### A4. cart → add `catalog`
|
||||
|
||||
**Change:** `requires=["inventory"]` → `requires=["inventory", "catalog"]`
|
||||
**File:** `app/modules/cart/definition.py`
|
||||
**Warnings resolved:** 2
|
||||
|
||||
| File | Imports from | What |
|
||||
|------|-------------|------|
|
||||
| `services/cart_service.py:24,27` | catalog | `ProductNotFoundException`, `Product` |
|
||||
|
||||
**Rationale:** Cart items are products. Can't add to cart without the Product model.
|
||||
|
||||
---
|
||||
|
||||
### Part A Subtotal: 4 one-line edits → 27 warnings resolved
|
||||
|
||||
*(Note: 3 remaining "declare dependency" warnings are covered by marketplace→analytics which is categorized under Part B as provider pattern instead.)*
|
||||
|
||||
---
|
||||
|
||||
## Part B: Provider Pattern (10 warnings — moderate refactoring)
|
||||
|
||||
These are **optional enrichment** where the source module works without the target. Need actual refactoring to conditionally load/call.
|
||||
|
||||
### B1. catalog → marketplace (3 warnings)
|
||||
|
||||
| File | What |
|
||||
|------|------|
|
||||
| `schemas/product.py:14` | `MarketplaceProductResponse` |
|
||||
| `schemas/catalog.py:14` | `MarketplaceProductResponse` |
|
||||
| `services/product_service.py:21` | `MarketplaceProduct` model |
|
||||
|
||||
**Why optional:** Products exist independently. Marketplace sync status is display enrichment.
|
||||
**Fix approach:** Make marketplace fields `Optional` in schemas, populate via provider if marketplace is enabled.
|
||||
|
||||
---
|
||||
|
||||
### B2. marketplace → analytics (2 warnings)
|
||||
|
||||
| File | What |
|
||||
|------|------|
|
||||
| `routes/api/admin_marketplace.py:17` | `stats_service` |
|
||||
| `routes/api/admin_marketplace.py:29` | `ImportStatsResponse` |
|
||||
|
||||
**Why optional:** Marketplace import/sync works without analytics. Stats on admin page are dashboard decoration.
|
||||
**Fix approach:** Conditionally call stats aggregator, return empty stats if analytics disabled.
|
||||
|
||||
---
|
||||
|
||||
### B3. orders → marketplace (1 warning)
|
||||
|
||||
| File | What |
|
||||
|------|------|
|
||||
| `services/order_service.py:50` | `MarketplaceProduct`, `MarketplaceProductTranslation` |
|
||||
|
||||
**Why optional:** Orders work without marketplace. Enriches order display with Letzshop product info.
|
||||
**Fix approach:** Conditionally join marketplace data when rendering, skip if module disabled.
|
||||
|
||||
---
|
||||
|
||||
### B4. inventory → orders (2 warnings)
|
||||
|
||||
| File | What |
|
||||
|------|------|
|
||||
| `services/inventory_transaction_service.py:15,18` | `OrderNotFoundException`, `Order` |
|
||||
|
||||
**Why optional:** Inventory tracks stock independently. Order reference on transactions is an audit back-reference, not functional.
|
||||
**Fix approach:** Store `order_id` as nullable FK, resolve order details via provider for display.
|
||||
|
||||
---
|
||||
|
||||
### B5. inventory → marketplace (1 warning)
|
||||
|
||||
| File | What |
|
||||
|------|------|
|
||||
| `services/inventory_service.py:606` | marketplace import |
|
||||
|
||||
**Why optional:** Optional sync enrichment.
|
||||
**Fix approach:** Conditional import or provider call.
|
||||
|
||||
---
|
||||
|
||||
### B6. analytics → catalog, orders, inventory, marketplace (4 warnings)
|
||||
|
||||
| File | What |
|
||||
|------|------|
|
||||
| `services/stats_service.py:23` | `Inventory` model |
|
||||
| `services/stats_service.py:24` | `MarketplaceImportJob`, `MarketplaceProduct` models |
|
||||
| `services/stats_service.py:25` | `Order` model |
|
||||
| `services/stats_service.py:26` | `Product` model |
|
||||
|
||||
**Why optional:** Analytics aggregates everything — should report on whatever modules are enabled, not crash if one is disabled. Every module already exposes a `metrics_provider`.
|
||||
**Fix approach:** Refactor `stats_service` to use module `metrics_provider` pattern instead of direct model imports. Cleanest candidate for provider pattern.
|
||||
|
||||
---
|
||||
|
||||
### Part B Subtotal: 6 refactors → 13 warnings resolved
|
||||
|
||||
---
|
||||
|
||||
## Resulting Dependency Tree
|
||||
|
||||
After all fixes, the clean module dependency graph:
|
||||
|
||||
```
|
||||
catalog (foundational — products)
|
||||
├── inventory (requires: catalog)
|
||||
├── cart (requires: catalog, inventory)
|
||||
├── orders (requires: catalog, inventory, payments)
|
||||
├── marketplace (requires: catalog, orders, inventory)
|
||||
└── analytics (no hard deps — all via providers)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Execution Log
|
||||
|
||||
### Part A — Completed 2026-02-09
|
||||
|
||||
- [x] **A1** — marketplace: declare `catalog`, `orders` ✅
|
||||
- [x] **A2** — orders: declare `catalog`, `inventory` ✅
|
||||
- [x] **A3** — inventory: declare `catalog` ✅
|
||||
- [x] **A4** — cart: declare `catalog` ✅
|
||||
|
||||
**Result:** 40 warnings → 13 warnings (27 resolved)
|
||||
|
||||
### Part B — Deferred (provider pattern refactors)
|
||||
|
||||
Remaining 13 warnings require provider pattern refactoring. To be tackled in a future session.
|
||||
|
||||
- [ ] **B6** — analytics: provider pattern (cleanest, biggest impact — 4 warnings)
|
||||
- [ ] **B1** — catalog: provider pattern for marketplace enrichment (3 warnings)
|
||||
- [ ] **B2** — marketplace: provider pattern for analytics stats (2 warnings)
|
||||
- [ ] **B4** — inventory: provider pattern for order back-references (2 warnings)
|
||||
- [ ] **B3** — orders: provider pattern for marketplace enrichment (1 warning)
|
||||
- [ ] **B5** — inventory: provider pattern for marketplace sync (1 warning)
|
||||
|
||||
---
|
||||
|
||||
## Validation Target
|
||||
|
||||
Current state:
|
||||
```
|
||||
$ python scripts/validate_architecture.py
|
||||
→ 0 errors, 13 warnings (all IMPORT-002 — provider pattern candidates)
|
||||
```
|
||||
|
||||
After Part B complete:
|
||||
```
|
||||
$ python scripts/validate_architecture.py
|
||||
→ 0 errors, 0 warnings
|
||||
```
|
||||
Reference in New Issue
Block a user