From 23d9f2f66f3449f64dd7b5aea4613f8a59d79774 Mon Sep 17 00:00:00 2001 From: sdarbinyan Date: Thu, 13 Aug 2026 11:16:16 +0400 Subject: [PATCH] refactor: rename duplicate AdminRole interface, type sellerId as UUID AdminRole was defined twice with unrelated shapes (core/auth's real JWT role union vs. the Users admin page's display interface), flagged in BACKEND-API-REFERENCE.md \u00a72b as needing a rename. Renamed the Users-page one to AdminUserRoleRecord. sellerId was bare string in admin-order/admin-product/item models while core/sellers/models/seller-scope.model.ts already used the shared UUID alias. Aligned all three to UUID for consistency (UUID is currently just = string, so this is a documentation-level type change, not a behavior change). Co-Authored-By: Claude Sonnet 5 --- src/app/features/admin/orders/models/admin-order.model.ts | 4 +++- .../features/admin/products/models/admin-product.model.ts | 4 +++- src/app/features/admin/users/facade/admin-users.facade.ts | 4 ++-- src/app/features/admin/users/models/admin-user.model.ts | 3 ++- .../admin/users/services/admin-users-gateway.interface.ts | 4 ++-- .../admin/users/services/admin-users-local.gateway.ts | 8 ++++---- src/app/models/item.model.ts | 4 +++- 7 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/app/features/admin/orders/models/admin-order.model.ts b/src/app/features/admin/orders/models/admin-order.model.ts index dbb0550..a0d50e3 100644 --- a/src/app/features/admin/orders/models/admin-order.model.ts +++ b/src/app/features/admin/orders/models/admin-order.model.ts @@ -1,3 +1,5 @@ +import { UUID } from '../../../../shared/types/primitive.types'; + export type AdminOrderStatus = 'pending' | 'processing' | 'shipped' | 'delivered' | 'cancelled' | 'refunded'; export type AdminOrderPaymentStatus = 'unpaid' | 'paid' | 'refund_requested' | 'refunded'; @@ -57,7 +59,7 @@ export interface AdminOrder { * Absent means marketplace-owned, exactly like every order today - * nothing reads this field yet, no behavior change. */ - sellerId?: string; + sellerId?: UUID; } export interface AdminOrderListFilters { diff --git a/src/app/features/admin/products/models/admin-product.model.ts b/src/app/features/admin/products/models/admin-product.model.ts index 0ac5e45..d2a49d5 100644 --- a/src/app/features/admin/products/models/admin-product.model.ts +++ b/src/app/features/admin/products/models/admin-product.model.ts @@ -1,3 +1,5 @@ +import { UUID } from '../../../../shared/types/primitive.types'; + export type AdminProductStockStatus = 'in_stock' | 'low_stock' | 'out_of_stock'; export type AdminProductSort = 'title' | 'price' | 'priority' | 'stock' | 'updated'; export type AdminProductEditorMode = 'create' | 'edit' | 'duplicate'; @@ -117,7 +119,7 @@ export interface AdminProduct { * Absent means marketplace-owned, exactly like every product today - * nothing reads this field yet, nothing breaks by it being undefined. */ - sellerId?: string; + sellerId?: UUID; } export interface AdminProductListFilters { diff --git a/src/app/features/admin/users/facade/admin-users.facade.ts b/src/app/features/admin/users/facade/admin-users.facade.ts index aeb89d2..c324be7 100644 --- a/src/app/features/admin/users/facade/admin-users.facade.ts +++ b/src/app/features/admin/users/facade/admin-users.facade.ts @@ -1,6 +1,6 @@ import { Injectable, inject, signal } from '@angular/core'; import { take } from 'rxjs/operators'; -import { AdminInvitation, AdminRole, AdminSession, AdminUser, AdminUserAuditEntry, AdminUserScope, AdminUserStatus } from '../models/admin-user.model'; +import { AdminInvitation, AdminUserRoleRecord, AdminSession, AdminUser, AdminUserAuditEntry, AdminUserScope, AdminUserStatus } from '../models/admin-user.model'; import { AdminUsersLocalGateway } from '../services/admin-users-local.gateway'; @Injectable({ providedIn: 'root' }) @@ -8,7 +8,7 @@ export class AdminUsersFacade { private readonly gateway = inject(AdminUsersLocalGateway); readonly users = signal([]); - readonly roles = signal([]); + readonly roles = signal([]); readonly invitations = signal([]); readonly loading = signal(false); readonly error = signal(false); diff --git a/src/app/features/admin/users/models/admin-user.model.ts b/src/app/features/admin/users/models/admin-user.model.ts index b62e1d3..de6fd2b 100644 --- a/src/app/features/admin/users/models/admin-user.model.ts +++ b/src/app/features/admin/users/models/admin-user.model.ts @@ -2,7 +2,8 @@ export type AdminUserScope = 'marketplace' | 'office'; export type AdminUserStatus = 'active' | 'invited' | 'suspended'; export type AdminInvitationStatus = 'pending' | 'accepted' | 'expired' | 'revoked'; -export interface AdminRole { +/** Users-admin display/permissions shape - unrelated to core/auth/models/permission.model.ts's AdminRole (the real JWT/auth role union). */ +export interface AdminUserRoleRecord { id: string; name: string; permissions: string[]; diff --git a/src/app/features/admin/users/services/admin-users-gateway.interface.ts b/src/app/features/admin/users/services/admin-users-gateway.interface.ts index bfac666..7b2a270 100644 --- a/src/app/features/admin/users/services/admin-users-gateway.interface.ts +++ b/src/app/features/admin/users/services/admin-users-gateway.interface.ts @@ -1,9 +1,9 @@ import { Observable } from 'rxjs'; -import { AdminInvitation, AdminRole, AdminSession, AdminUser, AdminUserAuditEntry, AdminUserScope, AdminUserStatus } from '../models/admin-user.model'; +import { AdminInvitation, AdminUserRoleRecord, AdminSession, AdminUser, AdminUserAuditEntry, AdminUserScope, AdminUserStatus } from '../models/admin-user.model'; export interface AdminUsersGateway { loadUsers(): Observable; - loadRoles(): Observable; + loadRoles(): Observable; loadInvitations(): Observable; loadSessions(userId: string): Observable; loadAudit(userId: string): Observable; diff --git a/src/app/features/admin/users/services/admin-users-local.gateway.ts b/src/app/features/admin/users/services/admin-users-local.gateway.ts index dcb8b52..f7e2fbe 100644 --- a/src/app/features/admin/users/services/admin-users-local.gateway.ts +++ b/src/app/features/admin/users/services/admin-users-local.gateway.ts @@ -1,11 +1,11 @@ import { Injectable, inject } from '@angular/core'; import { Observable, of } from 'rxjs'; import { delay } from 'rxjs/operators'; -import { AdminInvitation, AdminRole, AdminSession, AdminUser, AdminUserAuditEntry, AdminUserScope, AdminUserStatus } from '../models/admin-user.model'; +import { AdminInvitation, AdminUserRoleRecord, AdminSession, AdminUser, AdminUserAuditEntry, AdminUserScope, AdminUserStatus } from '../models/admin-user.model'; import { AdminUsersGateway } from './admin-users-gateway.interface'; import { AdminAuthService } from '../../../../core/admin-auth/admin-auth.service'; -const BUILT_IN_ROLES: AdminRole[] = [ +const BUILT_IN_ROLES: AdminUserRoleRecord[] = [ { id: 'owner', name: 'Owner', permissions: ['*'], builtIn: true }, { id: 'admin', name: 'Admin', permissions: ['products.manage', 'categories.manage', 'orders.manage', 'media.manage', 'users.manage'], builtIn: true }, { id: 'editor', name: 'Editor', permissions: ['products.manage', 'categories.manage', 'media.manage'], builtIn: true }, @@ -16,7 +16,7 @@ const BUILT_IN_ROLES: AdminRole[] = [ export class AdminUsersLocalGateway implements AdminUsersGateway { private readonly adminAuth = inject(AdminAuthService); private users: AdminUser[] | null = null; - private roles: AdminRole[] = [...BUILT_IN_ROLES]; + private roles: AdminUserRoleRecord[] = [...BUILT_IN_ROLES]; private invitations: AdminInvitation[] = []; private sessions: Record = {}; private audit: Record = {}; @@ -25,7 +25,7 @@ export class AdminUsersLocalGateway implements AdminUsersGateway { return of(this.ensureUsers()).pipe(delay(50)); } - loadRoles(): Observable { + loadRoles(): Observable { return of(this.roles).pipe(delay(50)); } diff --git a/src/app/models/item.model.ts b/src/app/models/item.model.ts index cc2df22..5cfedeb 100644 --- a/src/app/models/item.model.ts +++ b/src/app/models/item.model.ts @@ -1,3 +1,5 @@ +import { UUID } from '../shared/types/primitive.types'; + interface Photo { photo?: string; video?: string; @@ -182,7 +184,7 @@ export interface Item { * Absent means marketplace-owned, exactly like every product today - * nothing reads this field yet, nothing breaks by it being undefined. */ - sellerId?: string; + sellerId?: UUID; } export interface CartItem extends Item {