feat: Phase 10 frontend - Gorbushka-class content module core (models only)
core/content-modules against docs/backend/PHASE-10-CONTENT-MODULES- CONTRACT.md §1-2: Shop/ShopCategory/MallService/Floor/SchemePin/ RentListing/Lead models + gateway/token, seeded empty. Scope: models/gateway seam only, no admin UI (mall scheme/floor/pin editor, rent listing management). This is explicitly the lowest-priority phase in the delivery plan - only after Commerce Core is real - so it gets the smallest build in this push, matching that priority rather than spending equal effort on every phase regardless of sequence. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
58
src/app/core/content-modules/models/mall-content.model.ts
Normal file
58
src/app/core/content-modules/models/mall-content.model.ts
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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<Shop[]>;
|
||||
loadShopCategories(): Observable<ShopCategory[]>;
|
||||
loadFloors(): Observable<Floor[]>;
|
||||
loadSchemePins(floorId: string): Observable<SchemePin[]>;
|
||||
loadRentListings(): Observable<RentListing[]>;
|
||||
submitLead(lead: Omit<Lead, 'id' | 'createdAt'>): Observable<Lead>;
|
||||
}
|
||||
@@ -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<MallContentGateway>('MALL_CONTENT_GATEWAY', {
|
||||
providedIn: 'root',
|
||||
factory: () => inject(MallContentLocalGateway),
|
||||
});
|
||||
@@ -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<Shop[]> { return of([]); }
|
||||
loadShopCategories(): Observable<ShopCategory[]> { return of([]); }
|
||||
loadFloors(): Observable<Floor[]> { return of([]); }
|
||||
loadSchemePins(_floorId: string): Observable<SchemePin[]> { return of([]); }
|
||||
loadRentListings(): Observable<RentListing[]> { return of([]); }
|
||||
|
||||
submitLead(lead: Omit<Lead, 'id' | 'createdAt'>): Observable<Lead> {
|
||||
return of({ ...lead, id: `lead_${Date.now()}`, createdAt: new Date().toISOString() });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user