build: rebuild API release bundle for the admin/expert table split
app.js, seed.js, the Prisma client in release/vendor and the new migration 20261026120000_split_admin_table, built with `pnpm build:release` (API only; the admin panel and user apps are unchanged by this work). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
06c8a5f434
commit
e2ec30f241
+26
-11
File diff suppressed because one or more lines are too long
+23
-8
@@ -130,6 +130,20 @@ exports.Prisma.CityScalarFieldEnum = {
|
||||
percentAux: 'percentAux'
|
||||
};
|
||||
|
||||
exports.Prisma.AdminScalarFieldEnum = {
|
||||
id: 'id',
|
||||
fullName: 'fullName',
|
||||
firstName: 'firstName',
|
||||
lastName: 'lastName',
|
||||
mobile: 'mobile',
|
||||
passwordHash: 'passwordHash',
|
||||
role: 'role',
|
||||
userTypeId: 'userTypeId',
|
||||
branchId: 'branchId',
|
||||
isActive: 'isActive',
|
||||
createdAt: 'createdAt'
|
||||
};
|
||||
|
||||
exports.Prisma.AdminUserScalarFieldEnum = {
|
||||
id: 'id',
|
||||
fullName: 'fullName',
|
||||
@@ -170,7 +184,7 @@ exports.Prisma.AppSessionScalarFieldEnum = {
|
||||
exports.Prisma.AdminSessionScalarFieldEnum = {
|
||||
id: 'id',
|
||||
jti: 'jti',
|
||||
adminUserId: 'adminUserId',
|
||||
adminId: 'adminId',
|
||||
iamSessionId: 'iamSessionId',
|
||||
iamSub: 'iamSub',
|
||||
ipAddress: 'ipAddress',
|
||||
@@ -370,7 +384,7 @@ exports.Prisma.OrderStatusEventScalarFieldEnum = {
|
||||
fromStatus: 'fromStatus',
|
||||
toStatus: 'toStatus',
|
||||
note: 'note',
|
||||
actorAdminUserId: 'actorAdminUserId',
|
||||
actorAdminId: 'actorAdminId',
|
||||
createdAt: 'createdAt'
|
||||
};
|
||||
|
||||
@@ -397,7 +411,7 @@ exports.Prisma.PreOrderStatusEventScalarFieldEnum = {
|
||||
id: 'id',
|
||||
preOrderId: 'preOrderId',
|
||||
changes: 'changes',
|
||||
actorAdminUserId: 'actorAdminUserId',
|
||||
actorAdminId: 'actorAdminId',
|
||||
ipAddress: 'ipAddress',
|
||||
createdAt: 'createdAt'
|
||||
};
|
||||
@@ -414,7 +428,7 @@ exports.Prisma.LedgerEntryScalarFieldEnum = {
|
||||
orderId: 'orderId',
|
||||
confirmed: 'confirmed',
|
||||
confirmedAt: 'confirmedAt',
|
||||
postedByAdminUserId: 'postedByAdminUserId',
|
||||
postedByAdminId: 'postedByAdminId',
|
||||
labName: 'labName',
|
||||
hallmark: 'hallmark',
|
||||
accountName: 'accountName',
|
||||
@@ -549,7 +563,7 @@ exports.Prisma.PromotionExclusionScalarFieldEnum = {
|
||||
exports.Prisma.BranchAllocationScalarFieldEnum = {
|
||||
id: 'id',
|
||||
branchId: 'branchId',
|
||||
allocatorAdminUserId: 'allocatorAdminUserId',
|
||||
allocatorAdminId: 'allocatorAdminId',
|
||||
note: 'note',
|
||||
createdAt: 'createdAt'
|
||||
};
|
||||
@@ -567,7 +581,7 @@ exports.Prisma.SmsMessageScalarFieldEnum = {
|
||||
recipients: 'recipients',
|
||||
body: 'body',
|
||||
sentCount: 'sentCount',
|
||||
sentByAdminUserId: 'sentByAdminUserId',
|
||||
sentByAdminId: 'sentByAdminId',
|
||||
createdAt: 'createdAt'
|
||||
};
|
||||
|
||||
@@ -576,7 +590,7 @@ exports.Prisma.NotificationScalarFieldEnum = {
|
||||
title: 'title',
|
||||
body: 'body',
|
||||
audience: 'audience',
|
||||
sentByAdminUserId: 'sentByAdminUserId',
|
||||
sentByAdminId: 'sentByAdminId',
|
||||
createdAt: 'createdAt'
|
||||
};
|
||||
|
||||
@@ -609,7 +623,7 @@ exports.Prisma.UploadedFileScalarFieldEnum = {
|
||||
mimeType: 'mimeType',
|
||||
sizeBytes: 'sizeBytes',
|
||||
purpose: 'purpose',
|
||||
uploadedByAdminUserId: 'uploadedByAdminUserId',
|
||||
uploadedByAdminId: 'uploadedByAdminId',
|
||||
createdAt: 'createdAt'
|
||||
};
|
||||
|
||||
@@ -782,6 +796,7 @@ exports.MessageAudience = exports.$Enums.MessageAudience = {
|
||||
|
||||
exports.Prisma.ModelName = {
|
||||
City: 'City',
|
||||
Admin: 'Admin',
|
||||
AdminUser: 'AdminUser',
|
||||
AppSession: 'AppSession',
|
||||
AdminSession: 'AdminSession',
|
||||
|
||||
+4830
-3253
File diff suppressed because it is too large
Load Diff
+26
-11
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "prisma-client-8945b25ad1891f9eaff8d38ca7f3c1b19a3f2d11c0c8521549c219186ff7566b",
|
||||
"name": "prisma-client-d98bddf3599c950eb3fcd511efa7f226c4ef4c5c3cbc261683fb1118a763a924",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"browser": "index-browser.js",
|
||||
|
||||
+92
-48
@@ -140,6 +140,61 @@ model City {
|
||||
@@index([parentId])
|
||||
}
|
||||
|
||||
/// A staff account for the ADMIN PANEL — and nothing else.
|
||||
///
|
||||
/// Split out of AdminUser (which now holds sales experts only) so that:
|
||||
/// * the same mobile can be an admin AND a sales expert — they are two
|
||||
/// separate roles, each unique only within its own table;
|
||||
/// * the expert table (production: ~12,000 rows) is never written by panel
|
||||
/// staff management.
|
||||
/// Migration 20261026120000_split_admin_table copies the existing non-expert
|
||||
/// AdminUser rows here WITH THEIR IDS, so issued panel tokens and every
|
||||
/// "who did this" column keep resolving. The old rows are left in AdminUser,
|
||||
/// dormant; no code reads them as admins any more.
|
||||
///
|
||||
/// ⚠️ fullName/firstName/lastName are kept in sync by the DB trigger
|
||||
/// `admin_sync_full_name_trg` (it shares the function admin_user_sync_full_name) — same semantics as AdminUser: the parts win.
|
||||
model Admin {
|
||||
id String @id @default(cuid())
|
||||
|
||||
fullName String
|
||||
firstName String?
|
||||
lastName String?
|
||||
|
||||
mobile String @unique
|
||||
passwordHash String
|
||||
/// Never SALES_EXPERT — that role lives in AdminUser. Enforced in
|
||||
/// AdminUsersService, not in the database, so the enum stays shared.
|
||||
role AdminRole
|
||||
userTypeId Int?
|
||||
userType UserType? @relation(fields: [userTypeId], references: [id])
|
||||
branchId String?
|
||||
branch Branch? @relation(fields: [branchId], references: [id])
|
||||
isActive Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
supervisedWorkshops Workshop[] @relation("WorkshopSupervisor")
|
||||
branchAllocations BranchAllocation[] @relation("AllocationAuthor")
|
||||
postedLedgerEntries LedgerEntry[]
|
||||
orderStatusEvents OrderStatusEvent[]
|
||||
preOrderStatusEvents PreOrderStatusEvent[]
|
||||
sentSmsMessages SmsMessage[] @relation("SmsAuthor")
|
||||
sentNotifications Notification[] @relation("NotificationAuthor")
|
||||
uploadedFiles UploadedFile[] @relation("FileUploader")
|
||||
|
||||
/// Issued admin-panel tokens, recorded only while session tracking is on
|
||||
/// (AUTH_SESSION_TRACKING, or implicitly whenever the IAM is enabled) so a
|
||||
/// token can be revoked before it expires. See AdminSession.
|
||||
sessions AdminSession[]
|
||||
|
||||
@@index([role])
|
||||
@@index([userTypeId])
|
||||
@@index([firstName])
|
||||
@@index([lastName])
|
||||
}
|
||||
|
||||
/// A SALES EXPERT (role SALES_EXPERT). Panel staff live in `Admin`; rows here with
|
||||
/// any other role are pre-split leftovers and are ignored by the code.
|
||||
model AdminUser {
|
||||
id String @id @default(cuid())
|
||||
|
||||
@@ -185,26 +240,13 @@ model AdminUser {
|
||||
pasazhName String? // legacy pasazh_name
|
||||
memberCode String? // legacy mcode
|
||||
|
||||
referredCustomers Customer[] @relation("ReferralAgent")
|
||||
referredCustomers Customer[] @relation("ReferralAgent")
|
||||
/// Orders credited to this sales expert — see Order.salesAgentId.
|
||||
creditedOrders Order[] @relation("OrderSalesAgent")
|
||||
supervisedWorkshops Workshop[] @relation("WorkshopSupervisor")
|
||||
branchAllocations BranchAllocation[] @relation("AllocationAuthor")
|
||||
postedLedgerEntries LedgerEntry[]
|
||||
orderStatusEvents OrderStatusEvent[]
|
||||
preOrderStatusEvents PreOrderStatusEvent[]
|
||||
sentSmsMessages SmsMessage[] @relation("SmsAuthor")
|
||||
sentNotifications Notification[] @relation("NotificationAuthor")
|
||||
uploadedFiles UploadedFile[] @relation("FileUploader")
|
||||
creditedOrders Order[] @relation("OrderSalesAgent")
|
||||
|
||||
/// Only ever set for role = SALES_EXPERT (D17).
|
||||
salesExpertProfile SalesExpertProfile?
|
||||
|
||||
/// Issued admin-panel tokens, recorded only while session tracking is on
|
||||
/// (AUTH_SESSION_TRACKING, or implicitly whenever the IAM is enabled) so a
|
||||
/// token can be revoked before it expires. See AdminSession.
|
||||
sessions AdminSession[]
|
||||
|
||||
@@index([role])
|
||||
@@index([userTypeId])
|
||||
@@index([avatarFileId])
|
||||
@@ -274,8 +316,8 @@ model AdminSession {
|
||||
/// The token's `jti` claim. Unique: one row per issued token.
|
||||
jti String @unique
|
||||
|
||||
adminUserId String
|
||||
adminUser AdminUser @relation(fields: [adminUserId], references: [id], onDelete: Cascade)
|
||||
adminId String @map("adminUserId")
|
||||
admin Admin @relation(fields: [adminId], references: [id], onDelete: Cascade)
|
||||
|
||||
/// Set when the login was verified by the IAM: its session id (`sid`) and the
|
||||
/// stable user id (`sub`) there. Back-channel logout arrives keyed by these —
|
||||
@@ -294,7 +336,7 @@ model AdminSession {
|
||||
revokedAt DateTime?
|
||||
revokedReason String?
|
||||
|
||||
@@index([adminUserId])
|
||||
@@index([adminId], map: "AdminSession_adminUserId_idx")
|
||||
@@index([iamSessionId])
|
||||
@@index([iamSub])
|
||||
@@index([expiresAt])
|
||||
@@ -571,6 +613,7 @@ model Branch {
|
||||
cityId String?
|
||||
city City? @relation(fields: [cityId], references: [id])
|
||||
adminUsers AdminUser[]
|
||||
admins Admin[]
|
||||
orders Order[]
|
||||
allocations BranchAllocation[]
|
||||
}
|
||||
@@ -583,7 +626,7 @@ model Workshop {
|
||||
phone String?
|
||||
/// The supervisor created alongside the workshop by the legacy Add form.
|
||||
supervisorId String?
|
||||
supervisor AdminUser? @relation("WorkshopSupervisor", fields: [supervisorId], references: [id])
|
||||
supervisor Admin? @relation("WorkshopSupervisor", fields: [supervisorId], references: [id])
|
||||
isActive Boolean @default(true)
|
||||
preOrders PreOrder[]
|
||||
}
|
||||
@@ -826,15 +869,15 @@ model OrderItem {
|
||||
}
|
||||
|
||||
model OrderStatusEvent {
|
||||
id String @id @default(cuid())
|
||||
orderId String
|
||||
order Order @relation(fields: [orderId], references: [id])
|
||||
fromStatus OrderStatus?
|
||||
toStatus OrderStatus
|
||||
note String?
|
||||
actorAdminUserId String?
|
||||
actorAdminUser AdminUser? @relation(fields: [actorAdminUserId], references: [id])
|
||||
createdAt DateTime @default(now())
|
||||
id String @id @default(cuid())
|
||||
orderId String
|
||||
order Order @relation(fields: [orderId], references: [id])
|
||||
fromStatus OrderStatus?
|
||||
toStatus OrderStatus
|
||||
note String?
|
||||
actorAdminId String? @map("actorAdminUserId")
|
||||
actorAdmin Admin? @relation(fields: [actorAdminId], references: [id])
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([orderId])
|
||||
}
|
||||
@@ -875,15 +918,15 @@ model PreOrder {
|
||||
}
|
||||
|
||||
model PreOrderStatusEvent {
|
||||
id String @id @default(cuid())
|
||||
preOrderId String
|
||||
preOrder PreOrder @relation(fields: [preOrderId], references: [id])
|
||||
id String @id @default(cuid())
|
||||
preOrderId String
|
||||
preOrder PreOrder @relation(fields: [preOrderId], references: [id])
|
||||
/// Field-level diff, e.g. {"status": {"old": "PLACED", "new": "ADMIN_APPROVED"}}
|
||||
changes Json
|
||||
actorAdminUserId String?
|
||||
actorAdminUser AdminUser? @relation(fields: [actorAdminUserId], references: [id])
|
||||
ipAddress String?
|
||||
createdAt DateTime @default(now())
|
||||
changes Json
|
||||
actorAdminId String? @map("actorAdminUserId")
|
||||
actorAdmin Admin? @relation(fields: [actorAdminId], references: [id])
|
||||
ipAddress String?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([preOrderId])
|
||||
}
|
||||
@@ -912,10 +955,10 @@ model LedgerEntry {
|
||||
order Order? @relation(fields: [orderId], references: [id])
|
||||
|
||||
/// Pending entries don't count toward the cached customer balance until confirmed.
|
||||
confirmed Boolean @default(false)
|
||||
confirmedAt DateTime?
|
||||
postedByAdminUserId String?
|
||||
postedByAdminUser AdminUser? @relation(fields: [postedByAdminUserId], references: [id])
|
||||
confirmed Boolean @default(false)
|
||||
confirmedAt DateTime?
|
||||
postedByAdminId String? @map("postedByAdminUserId")
|
||||
postedByAdmin Admin? @relation(fields: [postedByAdminId], references: [id])
|
||||
|
||||
/// Instrument metadata from the legacy "cash" document form. Which fields are
|
||||
/// filled depends on sourceType: a melted-gold receipt carries lab/hallmark and
|
||||
@@ -997,6 +1040,7 @@ model UserType {
|
||||
|
||||
permissions Permission[]
|
||||
adminUsers AdminUser[]
|
||||
admins Admin[]
|
||||
|
||||
@@map("user_type")
|
||||
}
|
||||
@@ -1251,8 +1295,8 @@ model BranchAllocation {
|
||||
branch Branch @relation(fields: [branchId], references: [id])
|
||||
|
||||
/// Legacy `allocator_user` — the admin who filed the allocation.
|
||||
allocatorAdminUserId String?
|
||||
allocatorAdminUser AdminUser? @relation("AllocationAuthor", fields: [allocatorAdminUserId], references: [id])
|
||||
allocatorAdminId String? @map("allocatorAdminUserId")
|
||||
allocatorAdmin Admin? @relation("AllocationAuthor", fields: [allocatorAdminId], references: [id])
|
||||
|
||||
note String?
|
||||
createdAt DateTime @default(now())
|
||||
@@ -1299,8 +1343,8 @@ model SmsMessage {
|
||||
/// How many numbers the send actually resolved to.
|
||||
sentCount Int @default(0)
|
||||
|
||||
sentByAdminUserId String?
|
||||
sentByAdminUser AdminUser? @relation("SmsAuthor", fields: [sentByAdminUserId], references: [id])
|
||||
sentByAdminId String? @map("sentByAdminUserId")
|
||||
sentByAdmin Admin? @relation("SmsAuthor", fields: [sentByAdminId], references: [id])
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@ -1313,8 +1357,8 @@ model Notification {
|
||||
body String
|
||||
audience MessageAudience @default(ALL_CUSTOMERS)
|
||||
|
||||
sentByAdminUserId String?
|
||||
sentByAdminUser AdminUser? @relation("NotificationAuthor", fields: [sentByAdminUserId], references: [id])
|
||||
sentByAdminId String? @map("sentByAdminUserId")
|
||||
sentByAdmin Admin? @relation("NotificationAuthor", fields: [sentByAdminId], references: [id])
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@ -1379,8 +1423,8 @@ model UploadedFile {
|
||||
/// 'customer.nationalId'. Kept loose so a new form needs no schema change.
|
||||
purpose String?
|
||||
|
||||
uploadedByAdminUserId String?
|
||||
uploadedByAdminUser AdminUser? @relation("FileUploader", fields: [uploadedByAdminUserId], references: [id])
|
||||
uploadedByAdminId String? @map("uploadedByAdminUserId")
|
||||
uploadedByAdmin Admin? @relation("FileUploader", fields: [uploadedByAdminId], references: [id])
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
customerAvatars Customer[] @relation("CustomerAvatar")
|
||||
|
||||
+23
-8
@@ -130,6 +130,20 @@ exports.Prisma.CityScalarFieldEnum = {
|
||||
percentAux: 'percentAux'
|
||||
};
|
||||
|
||||
exports.Prisma.AdminScalarFieldEnum = {
|
||||
id: 'id',
|
||||
fullName: 'fullName',
|
||||
firstName: 'firstName',
|
||||
lastName: 'lastName',
|
||||
mobile: 'mobile',
|
||||
passwordHash: 'passwordHash',
|
||||
role: 'role',
|
||||
userTypeId: 'userTypeId',
|
||||
branchId: 'branchId',
|
||||
isActive: 'isActive',
|
||||
createdAt: 'createdAt'
|
||||
};
|
||||
|
||||
exports.Prisma.AdminUserScalarFieldEnum = {
|
||||
id: 'id',
|
||||
fullName: 'fullName',
|
||||
@@ -170,7 +184,7 @@ exports.Prisma.AppSessionScalarFieldEnum = {
|
||||
exports.Prisma.AdminSessionScalarFieldEnum = {
|
||||
id: 'id',
|
||||
jti: 'jti',
|
||||
adminUserId: 'adminUserId',
|
||||
adminId: 'adminId',
|
||||
iamSessionId: 'iamSessionId',
|
||||
iamSub: 'iamSub',
|
||||
ipAddress: 'ipAddress',
|
||||
@@ -370,7 +384,7 @@ exports.Prisma.OrderStatusEventScalarFieldEnum = {
|
||||
fromStatus: 'fromStatus',
|
||||
toStatus: 'toStatus',
|
||||
note: 'note',
|
||||
actorAdminUserId: 'actorAdminUserId',
|
||||
actorAdminId: 'actorAdminId',
|
||||
createdAt: 'createdAt'
|
||||
};
|
||||
|
||||
@@ -397,7 +411,7 @@ exports.Prisma.PreOrderStatusEventScalarFieldEnum = {
|
||||
id: 'id',
|
||||
preOrderId: 'preOrderId',
|
||||
changes: 'changes',
|
||||
actorAdminUserId: 'actorAdminUserId',
|
||||
actorAdminId: 'actorAdminId',
|
||||
ipAddress: 'ipAddress',
|
||||
createdAt: 'createdAt'
|
||||
};
|
||||
@@ -414,7 +428,7 @@ exports.Prisma.LedgerEntryScalarFieldEnum = {
|
||||
orderId: 'orderId',
|
||||
confirmed: 'confirmed',
|
||||
confirmedAt: 'confirmedAt',
|
||||
postedByAdminUserId: 'postedByAdminUserId',
|
||||
postedByAdminId: 'postedByAdminId',
|
||||
labName: 'labName',
|
||||
hallmark: 'hallmark',
|
||||
accountName: 'accountName',
|
||||
@@ -549,7 +563,7 @@ exports.Prisma.PromotionExclusionScalarFieldEnum = {
|
||||
exports.Prisma.BranchAllocationScalarFieldEnum = {
|
||||
id: 'id',
|
||||
branchId: 'branchId',
|
||||
allocatorAdminUserId: 'allocatorAdminUserId',
|
||||
allocatorAdminId: 'allocatorAdminId',
|
||||
note: 'note',
|
||||
createdAt: 'createdAt'
|
||||
};
|
||||
@@ -567,7 +581,7 @@ exports.Prisma.SmsMessageScalarFieldEnum = {
|
||||
recipients: 'recipients',
|
||||
body: 'body',
|
||||
sentCount: 'sentCount',
|
||||
sentByAdminUserId: 'sentByAdminUserId',
|
||||
sentByAdminId: 'sentByAdminId',
|
||||
createdAt: 'createdAt'
|
||||
};
|
||||
|
||||
@@ -576,7 +590,7 @@ exports.Prisma.NotificationScalarFieldEnum = {
|
||||
title: 'title',
|
||||
body: 'body',
|
||||
audience: 'audience',
|
||||
sentByAdminUserId: 'sentByAdminUserId',
|
||||
sentByAdminId: 'sentByAdminId',
|
||||
createdAt: 'createdAt'
|
||||
};
|
||||
|
||||
@@ -609,7 +623,7 @@ exports.Prisma.UploadedFileScalarFieldEnum = {
|
||||
mimeType: 'mimeType',
|
||||
sizeBytes: 'sizeBytes',
|
||||
purpose: 'purpose',
|
||||
uploadedByAdminUserId: 'uploadedByAdminUserId',
|
||||
uploadedByAdminId: 'uploadedByAdminId',
|
||||
createdAt: 'createdAt'
|
||||
};
|
||||
|
||||
@@ -782,6 +796,7 @@ exports.MessageAudience = exports.$Enums.MessageAudience = {
|
||||
|
||||
exports.Prisma.ModelName = {
|
||||
City: 'City',
|
||||
Admin: 'Admin',
|
||||
AdminUser: 'AdminUser',
|
||||
AppSession: 'AppSession',
|
||||
AdminSession: 'AdminSession',
|
||||
|
||||
Reference in New Issue
Block a user