refactor: rename storefront CategoryApiModel; correct stale auth-error doc; add Phase 1 backend contract
- models/category.model.ts: Category -> CategoryApiModel, disambiguated from core/categories/models/category-domain.model.ts's Category (admin domain shape). Removes a dead unused import in item.utils.ts along the way. Only live consumer was services/api.service.ts, updated in place. - BACKEND-API-REFERENCE.md §5: corrected two rows documenting the TOKEN_EXPIRED/INVALID_SIGNATURE auth-error bug as still open - the fix (reading error.error.code before falling back to HTTP status) is already in auth.service.ts. Doc was stale, not the code. - Sprint 0.2 audit: AdminRole duplication and the PRODUCT_DATA_PROVIDER/CATEGORY_REPOSITORY dead mock branches were already resolved in a prior pass - verified, no code change needed. - docs/backend/PHASE-1-MONEY-FX-PAYMENTS-CONTRACT.md: new wire contract for Money/FxQuote/PriceSnapshot/payment state machine, so backend can start Phase 1 the moment the frozen payment chain is unblocked. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
import { ItemName } from './item.model';
|
||||
|
||||
export interface Category {
|
||||
/**
|
||||
* Storefront-side raw category shape (item.service.ts/api.service.ts responses).
|
||||
* Unrelated to core/categories/models/category-domain.model.ts's Category, which is
|
||||
* the normalized admin-backoffice domain shape produced by CategoryMapper.
|
||||
*/
|
||||
export interface CategoryApiModel {
|
||||
categoryID: number;
|
||||
name: string;
|
||||
parentID: number;
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
|
||||
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
|
||||
import { Observable, timer } from 'rxjs';
|
||||
import { map, retry } from 'rxjs/operators';
|
||||
import { Category, DeliveryOption, Item, Subcategory } from '../models';
|
||||
import { CategoryApiModel, DeliveryOption, Item, Subcategory } from '../models';
|
||||
import { normalizeDeliveryOption, normalizeOptionalNumber } from '../utils/normalization.utils';
|
||||
import { environment } from '../../environments/environment';
|
||||
import { ApiConfigService } from '../core/config/api-config.service';
|
||||
@@ -199,7 +199,7 @@ export class ApiService {
|
||||
|| (subcategory.subcategories?.length ?? 0) > 0;
|
||||
}
|
||||
|
||||
private isDisplayableCategory(category: Category): boolean {
|
||||
private isDisplayableCategory(category: CategoryApiModel): boolean {
|
||||
return category.visible !== false;
|
||||
}
|
||||
|
||||
@@ -462,8 +462,8 @@ export class ApiService {
|
||||
* Normalize a category from the API response — supports both
|
||||
* the flat legacy format and nested backOffice format.
|
||||
*/
|
||||
private normalizeCategory(raw: any): Category {
|
||||
const cat: Category = { ...raw };
|
||||
private normalizeCategory(raw: any): CategoryApiModel {
|
||||
const cat: CategoryApiModel = { ...raw };
|
||||
|
||||
if (raw.id != null && raw.categoryID == null) {
|
||||
cat.id = String(raw.id);
|
||||
@@ -522,7 +522,7 @@ export class ApiService {
|
||||
return cat;
|
||||
}
|
||||
|
||||
private normalizeCategories(cats: any[] | null | undefined): Category[] {
|
||||
private normalizeCategories(cats: any[] | null | undefined): CategoryApiModel[] {
|
||||
if (!cats || !Array.isArray(cats)) return [];
|
||||
return cats
|
||||
.map(c => this.normalizeCategory(c))
|
||||
@@ -535,7 +535,7 @@ export class ApiService {
|
||||
return this.http.get<{ message: string }>(`${this.baseUrl}/ping`);
|
||||
}
|
||||
|
||||
getCategories(): Observable<Category[]> {
|
||||
getCategories(): Observable<CategoryApiModel[]> {
|
||||
return this.http.get<any[]>(`${this.baseUrl}/category`)
|
||||
.pipe(retry(this.retryConfig), map(cats => this.normalizeCategories(cats)));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Item } from '../models';
|
||||
import { Category } from '../models/category.model';
|
||||
|
||||
export function getDiscountedPrice(item: Item): number {
|
||||
return item.price * (1 - (item.discount || 0) / 100);
|
||||
|
||||
Reference in New Issue
Block a user