diff --git a/src/app/core/content-modules/models/mall-content.model.ts b/src/app/core/content-modules/models/mall-content.model.ts new file mode 100644 index 0000000..3056bca --- /dev/null +++ b/src/app/core/content-modules/models/mall-content.model.ts @@ -0,0 +1,58 @@ +/** Per docs/backend/PHASE-10-CONTENT-MODULES-CONTRACT.md §1. Gorbushka-class (mall_directory) tenants. */ +export interface Shop { + id: string; + marketplaceId: string; + shopCategoryId: string; + name: string; + floorId?: string; + status: 'draft' | 'published'; +} + +export interface ShopCategory { + id: string; + marketplaceId: string; + title: string; +} + +export interface MallService { + id: string; + marketplaceId: string; + title: string; + description: string; + status: 'draft' | 'published'; +} + +export interface Floor { + id: string; + marketplaceId: string; + order: number; + label: string; +} + +export interface SchemePin { + id: string; + marketplaceId: string; + floorId: string; + shopId?: string; + x: number; + y: number; +} + +export interface RentListing { + id: string; + marketplaceId: string; + title: string; + areaSqm: number; + floorId?: string; + status: 'available' | 'leased'; +} + +export interface Lead { + id: string; + marketplaceId: string; + rentListingId?: string; + contactName: string; + contactPhone: string; + message?: string; + createdAt: string; +} diff --git a/src/app/core/content-modules/services/mall-content-gateway.interface.ts b/src/app/core/content-modules/services/mall-content-gateway.interface.ts new file mode 100644 index 0000000..1efd63b --- /dev/null +++ b/src/app/core/content-modules/services/mall-content-gateway.interface.ts @@ -0,0 +1,12 @@ +import { Observable } from 'rxjs'; +import { Floor, Lead, RentListing, SchemePin, Shop, ShopCategory } from '../models/mall-content.model'; + +/** Per docs/backend/PHASE-10-CONTENT-MODULES-CONTRACT.md §2. */ +export interface MallContentGateway { + loadShops(): Observable; + loadShopCategories(): Observable; + loadFloors(): Observable; + loadSchemePins(floorId: string): Observable; + loadRentListings(): Observable; + submitLead(lead: Omit): Observable; +} diff --git a/src/app/core/content-modules/services/mall-content-gateway.token.ts b/src/app/core/content-modules/services/mall-content-gateway.token.ts new file mode 100644 index 0000000..b618b2d --- /dev/null +++ b/src/app/core/content-modules/services/mall-content-gateway.token.ts @@ -0,0 +1,9 @@ +import { InjectionToken, inject } from '@angular/core'; +import { MallContentGateway } from './mall-content-gateway.interface'; +import { MallContentLocalGateway } from './mall-content-local.gateway'; + +/** Swap point for docs/backend/PHASE-10-CONTENT-MODULES-CONTRACT.md. */ +export const MALL_CONTENT_GATEWAY = new InjectionToken('MALL_CONTENT_GATEWAY', { + providedIn: 'root', + factory: () => inject(MallContentLocalGateway), +}); diff --git a/src/app/core/content-modules/services/mall-content-local.gateway.ts b/src/app/core/content-modules/services/mall-content-local.gateway.ts new file mode 100644 index 0000000..af6b954 --- /dev/null +++ b/src/app/core/content-modules/services/mall-content-local.gateway.ts @@ -0,0 +1,23 @@ +import { Injectable } from '@angular/core'; +import { Observable, of } from 'rxjs'; +import { Floor, Lead, RentListing, SchemePin, Shop, ShopCategory } from '../models/mall-content.model'; +import { MallContentGateway } from './mall-content-gateway.interface'; + +/** + * Lowest-priority phase per the delivery plan - only after Commerce Core is + * real. Seeded empty; the current Gorbushka frontend/archive remains UX + * reference only per ADR-0001, production data routes through the shared + * platform once docs/backend/PHASE-10-CONTENT-MODULES-CONTRACT.md ships. + */ +@Injectable({ providedIn: 'root' }) +export class MallContentLocalGateway implements MallContentGateway { + loadShops(): Observable { return of([]); } + loadShopCategories(): Observable { return of([]); } + loadFloors(): Observable { return of([]); } + loadSchemePins(_floorId: string): Observable { return of([]); } + loadRentListings(): Observable { return of([]); } + + submitLead(lead: Omit): Observable { + return of({ ...lead, id: `lead_${Date.now()}`, createdAt: new Date().toISOString() }); + } +}