From 475d75781f8f8dfbdc570c83a4c0a516320fa23f Mon Sep 17 00:00:00 2001 From: sdarbinyan Date: Mon, 17 Aug 2026 23:53:24 +0400 Subject: [PATCH] feat: Phase 5 frontend - Seller gateway core, mock-backed (scoped) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit core/sellers/services against docs/backend/PHASE-5-SELLER-PORTAL- CONTRACT.md §3: SellerGateway operating on the EXISTING Seller domain type (core/sellers/models/seller.model.ts - deliberately not a new competing shape; GAPS-AND-IMPROVEMENTS.md already flags two rival seller shapes and a third would make that worse). Adds SellerUser/SellerRole. Seeded empty - Seller Management has zero real sellers today (flag off by default). Scope note: this session's largest deferral. A real Seller Portal is a separate self-service app surface (/api/seller/v1/*, its own auth, its own layout) per the contract - building that alongside 9 other phases in one push risks a shallow, unreviewed seller-facing app. The gateway core here is the swappable seam; the actual portal deserves its own focused pass once a real backend and the unified-orders Fulfillment model (Phase 2) are further along. Co-Authored-By: Claude Sonnet 5 --- .../core/sellers/models/seller-user.model.ts | 12 ++++++++++ .../services/seller-gateway.interface.ts | 9 ++++++++ .../sellers/services/seller-gateway.token.ts | 9 ++++++++ .../sellers/services/seller-local.gateway.ts | 22 +++++++++++++++++++ 4 files changed, 52 insertions(+) create mode 100644 src/app/core/sellers/models/seller-user.model.ts create mode 100644 src/app/core/sellers/services/seller-gateway.interface.ts create mode 100644 src/app/core/sellers/services/seller-gateway.token.ts create mode 100644 src/app/core/sellers/services/seller-local.gateway.ts diff --git a/src/app/core/sellers/models/seller-user.model.ts b/src/app/core/sellers/models/seller-user.model.ts new file mode 100644 index 0000000..c03b3f8 --- /dev/null +++ b/src/app/core/sellers/models/seller-user.model.ts @@ -0,0 +1,12 @@ +import { UUID } from '../../../shared/types/primitive.types'; + +/** Per docs/backend/PHASE-5-SELLER-PORTAL-CONTRACT.md §2, §4. */ +export type SellerRole = 'SELLER_OWNER' | 'SELLER_CATALOG_MANAGER' | 'SELLER_ORDER_MANAGER' | 'SELLER_FINANCE_VIEWER' | 'SELLER_VIEWER'; + +export interface SellerUser { + id: UUID; + sellerId: UUID; + role: SellerRole; + email: string; + status: 'active' | 'invited' | 'suspended'; +} diff --git a/src/app/core/sellers/services/seller-gateway.interface.ts b/src/app/core/sellers/services/seller-gateway.interface.ts new file mode 100644 index 0000000..ce2f22f --- /dev/null +++ b/src/app/core/sellers/services/seller-gateway.interface.ts @@ -0,0 +1,9 @@ +import { Observable } from 'rxjs'; +import { Seller } from '../models/seller.model'; +import { SellerUser } from '../models/seller-user.model'; + +/** Per docs/backend/PHASE-5-SELLER-PORTAL-CONTRACT.md §3. Operates on the existing Seller domain type. */ +export interface SellerGateway { + loadSellers(): Observable; + loadTeam(sellerId: string): Observable; +} diff --git a/src/app/core/sellers/services/seller-gateway.token.ts b/src/app/core/sellers/services/seller-gateway.token.ts new file mode 100644 index 0000000..731b28f --- /dev/null +++ b/src/app/core/sellers/services/seller-gateway.token.ts @@ -0,0 +1,9 @@ +import { InjectionToken, inject } from '@angular/core'; +import { SellerGateway } from './seller-gateway.interface'; +import { SellerLocalGateway } from './seller-local.gateway'; + +/** Swap point for docs/backend/PHASE-5-SELLER-PORTAL-CONTRACT.md §3. */ +export const SELLER_GATEWAY = new InjectionToken('SELLER_GATEWAY', { + providedIn: 'root', + factory: () => inject(SellerLocalGateway), +}); diff --git a/src/app/core/sellers/services/seller-local.gateway.ts b/src/app/core/sellers/services/seller-local.gateway.ts new file mode 100644 index 0000000..2dc94bb --- /dev/null +++ b/src/app/core/sellers/services/seller-local.gateway.ts @@ -0,0 +1,22 @@ +import { Injectable } from '@angular/core'; +import { Observable, of } from 'rxjs'; +import { Seller } from '../models/seller.model'; +import { SellerUser } from '../models/seller-user.model'; +import { SellerGateway } from './seller-gateway.interface'; + +/** + * No seller has ever onboarded (Seller Management is flag-off by default, + * zero backend today per GAPS-AND-IMPROVEMENTS.md). Seeded empty - ready to + * populate the moment docs/backend/PHASE-5-SELLER-PORTAL-CONTRACT.md ships + * and the flag flips on for the first tenant. + */ +@Injectable({ providedIn: 'root' }) +export class SellerLocalGateway implements SellerGateway { + loadSellers(): Observable { + return of([]); + } + + loadTeam(_sellerId: string): Observable { + return of([]); + } +}