Architecture Deployment API

Admin Persona Flows

1. Vendor Approval & Vase Installation

flowchart TD
  A[Admin: POST /admin/vendors] --> B[Vendor created — status=PendingInstallation]
  B --> C[Admin: POST /admin/vendors/id/assign-technician]
  C --> D[Technician installs SmartVase]
  D --> E[Technician: POST /smart-vases/register-by-technician]
  E --> F[Vase status → Online]
  F --> G[Admin: PATCH /admin/vendors/id/status active=true]
  G --> H[Vendor active — can receive orders]

2. Vendor Suspension

flowchart TD
  A[Admin: POST /admin/vendors/id/suspend] --> B[Vendor.IsActive = false]
  B --> C[All vendor bouquets — status → Expired]
  C --> D[Active orders for vendor — status → Cancelled]
  D --> E[Vendor portal login blocked via Keycloak role]
  E --> F[Admin: POST /admin/vendors/id/reactivate to reverse]

3. Analytics

sequenceDiagram
  participant AP as Admin Portal
  participant API as REST API
  participant DB as PostgreSQL

  AP->>API: GET /api/v1/analytics/platform-insights
  API->>DB: Aggregate: total vendors, orders, revenue, active vases
  API-->>AP: 200 PlatformInsightsDto

  AP->>API: GET /api/v1/analytics/realtime
  API->>DB: Last 24h: new orders, signups, active sessions
  API-->>AP: 200 RealtimeAnalyticsDto

  AP->>API: GET /api/v1/analytics/vendor/{vendorId}
  API->>DB: Vendor-scoped: orders, revenue, bouquet performance
  API-->>AP: 200 VendorAnalyticsDto

Note: Per-vendor analytics now read the vendor from tenant context (the earlier VendorId.New() bug is fixed). One VendorId.New() fallback remains in the benchmark handler in AnalyticsHandlers.cs only.

4. Customer Management

sequenceDiagram
  participant AP as Admin Portal
  participant API as REST API
  participant DB as PostgreSQL
  participant KC as Keycloak

  AP->>API: GET /api/v1/admin/customers
  API->>DB: All customers with order count, last active
  API-->>AP: 200 [{customerId, name, email, orderCount}]

  AP->>API: POST /api/v1/admin/customers/{id}/suspend
  API->>DB: Customer.IsActive = false
  API->>KC: Disable Keycloak user
  API-->>AP: 200 OK

  AP->>API: POST /api/v1/admin/customers/{id}/reactivate
  API->>DB: Customer.IsActive = true
  API->>KC: Enable Keycloak user
  API-->>AP: 200 OK