feat: consolidate media service, add merchant users page, fix metrics overlap

- Merge ImageService into MediaService with WebP variant generation,
  DB-backed storage stats, and module-driven media usage discovery
  via new MediaUsageProviderProtocol
- Add merchant users admin page with scoped user listing, stats
  endpoint, template, JS, and i18n strings (de/en/fr/lb)
- Fix merchant user metrics so Owners and Team Members are mutually
  exclusive (filter team_members on user_type="member" and exclude
  owner IDs) ensuring stat cards add up correctly
- Update billing and monitoring services to use media_service
- Update subscription-billing and feature-gating docs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-07 21:17:11 +01:00
parent 4cb2bda575
commit 2250054ba2
30 changed files with 1220 additions and 805 deletions

View File

@@ -16,7 +16,7 @@ import psutil
from sqlalchemy import func, text
from sqlalchemy.orm import Session
from app.modules.core.services.image_service import image_service
from app.modules.cms.services.media_service import media_service
from app.modules.inventory.models import Inventory
from app.modules.orders.models import Order
from app.modules.catalog.models import Product
@@ -108,9 +108,9 @@ class PlatformHealthService:
"inventory_count": inventory_count,
}
def get_image_storage_metrics(self) -> dict:
def get_image_storage_metrics(self, db: Session) -> dict:
"""Get image storage statistics."""
stats = image_service.get_storage_stats()
stats = media_service.get_storage_stats(db)
return {
"total_files": stats["total_files"],
"total_size_mb": stats["total_size_mb"],
@@ -134,7 +134,7 @@ class PlatformHealthService:
products_by_store = {name or "Unknown": count for name, count in store_counts}
# Image storage
image_stats = image_service.get_storage_stats()
image_stats = media_service.get_storage_stats(db)
# Database size
db_size = self._get_database_size(db)
@@ -282,7 +282,7 @@ class PlatformHealthService:
database = self.get_database_metrics(db)
# Image storage metrics
image_storage = self.get_image_storage_metrics()
image_storage = self.get_image_storage_metrics(db)
# Subscription capacity
subscription_capacity = self.get_subscription_capacity(db)