This commit is contained in:
jason
2026-03-16 14:38:00 -05:00
commit 3d05e3929d
193 changed files with 40238 additions and 0 deletions

14
shared/package.json Normal file
View File

@@ -0,0 +1,14 @@
{
"name": "@mrp/shared",
"version": "0.1.0",
"private": true,
"type": "module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"scripts": {
"dev": "tsc -w -p tsconfig.json",
"build": "tsc -p tsconfig.json",
"test": "vitest run --passWithNoTests",
"lint": "tsc -p tsconfig.json --noEmit"
}
}

191
shared/src/admin/types.ts Normal file
View File

@@ -0,0 +1,191 @@
export interface AuditEventDto {
id: string;
actorId: string | null;
actorName: string | null;
entityType: string;
entityId: string | null;
action: string;
summary: string;
metadataJson: string;
createdAt: string;
}
export interface AdminPermissionOptionDto {
key: string;
description: string;
}
export interface AdminRoleDto {
id: string;
name: string;
description: string;
permissionKeys: string[];
userCount: number;
createdAt: string;
updatedAt: string;
}
export interface AdminRoleInput {
name: string;
description: string;
permissionKeys: string[];
}
export interface AdminUserDto {
id: string;
email: string;
firstName: string;
lastName: string;
isActive: boolean;
roleIds: string[];
roleNames: string[];
permissionKeys: string[];
createdAt: string;
updatedAt: string;
}
export interface AdminUserInput {
email: string;
firstName: string;
lastName: string;
isActive: boolean;
roleIds: string[];
password: string | null;
}
export interface AdminAuthSessionDto {
id: string;
userId: string;
userEmail: string;
userName: string;
status: "ACTIVE" | "EXPIRED" | "REVOKED";
reviewState: "NORMAL" | "REVIEW";
reviewReasons: string[];
isCurrent: boolean;
createdAt: string;
lastSeenAt: string;
expiresAt: string;
revokedAt: string | null;
revokedReason: string | null;
revokedByName: string | null;
ipAddress: string | null;
userAgent: string | null;
}
export interface StartupValidationCheckDto {
id: string;
label: string;
status: "PASS" | "WARN" | "FAIL";
message: string;
}
export interface StartupValidationReportDto {
status: "PASS" | "WARN" | "FAIL";
generatedAt: string;
durationMs: number;
passCount: number;
warnCount: number;
failCount: number;
checks: StartupValidationCheckDto[];
}
export interface BackupChecklistItemDto {
id: string;
label: string;
detail: string;
}
export interface BackupVerificationItemDto extends BackupChecklistItemDto {
evidence: string;
}
export interface RestoreDrillStepDto extends BackupChecklistItemDto {
expectedOutcome: string;
}
export interface BackupGuidanceDto {
dataPath: string;
databasePath: string;
uploadsPath: string;
recommendedBackupTarget: string;
backupSteps: BackupChecklistItemDto[];
restoreSteps: BackupChecklistItemDto[];
verificationChecklist: BackupVerificationItemDto[];
restoreDrillSteps: RestoreDrillStepDto[];
}
export interface SupportLogEntryDto {
id: string;
level: "INFO" | "WARN" | "ERROR";
source: string;
message: string;
contextJson: string;
createdAt: string;
}
export interface SupportLogFiltersDto {
level?: SupportLogEntryDto["level"];
source?: string;
query?: string;
start?: string;
end?: string;
limit?: number;
}
export interface SupportLogSummaryDto {
totalCount: number;
filteredCount: number;
sourceCount: number;
retentionDays: number;
oldestEntryAt: string | null;
newestEntryAt: string | null;
levelCounts: Record<SupportLogEntryDto["level"], number>;
}
export interface SupportLogListDto {
entries: SupportLogEntryDto[];
summary: SupportLogSummaryDto;
availableSources: string[];
filters: SupportLogFiltersDto;
}
export interface SupportSnapshotDto {
generatedAt: string;
diagnostics: AdminDiagnosticsDto;
userCount: number;
roleCount: number;
activeUserEmails: string[];
backupGuidance: BackupGuidanceDto;
supportLogs: SupportLogListDto;
}
export interface AdminDiagnosticsDto {
serverTime: string;
nodeVersion: string;
databaseUrl: string;
dataDir: string;
uploadsDir: string;
clientOrigin: string;
companyProfilePresent: boolean;
userCount: number;
activeUserCount: number;
activeSessionCount: number;
reviewSessionCount: number;
roleCount: number;
permissionCount: number;
customerCount: number;
vendorCount: number;
inventoryItemCount: number;
warehouseCount: number;
workOrderCount: number;
projectCount: number;
purchaseOrderCount: number;
salesDocumentCount: number;
shipmentCount: number;
attachmentCount: number;
auditEventCount: number;
supportLogCount: number;
startup: StartupValidationReportDto;
recentAuditEvents: AuditEventDto[];
recentSupportLogs: SupportLogEntryDto[];
}

View File

@@ -0,0 +1,26 @@
export const permissions = {
adminManage: "admin.manage",
companyRead: "company.read",
companyWrite: "company.write",
crmRead: "crm.read",
crmWrite: "crm.write",
inventoryRead: "inventory.read",
inventoryWrite: "inventory.write",
manufacturingRead: "manufacturing.read",
manufacturingWrite: "manufacturing.write",
filesRead: "files.read",
filesWrite: "files.write",
ganttRead: "gantt.read",
salesRead: "sales.read",
salesWrite: "sales.write",
projectsRead: "projects.read",
projectsWrite: "projects.write",
purchasingRead: "purchasing.read",
purchasingWrite: "purchasing.write",
shippingRead: "shipping.read",
shippingWrite: "shipping.write",
} as const;
export type PermissionKey = (typeof permissions)[keyof typeof permissions];
export const defaultAdminPermissions: PermissionKey[] = Object.values(permissions);

24
shared/src/auth/types.ts Normal file
View File

@@ -0,0 +1,24 @@
import type { PermissionKey } from "./permissions.js";
export interface AuthUser {
id: string;
email: string;
firstName: string;
lastName: string;
roles: string[];
permissions: PermissionKey[];
}
export interface LoginRequest {
email: string;
password: string;
}
export interface LoginResponse {
token: string;
user: AuthUser;
}
export interface LogoutResponse {
success: true;
}

15
shared/src/common/api.ts Normal file
View File

@@ -0,0 +1,15 @@
export interface ApiSuccess<T> {
ok: true;
data: T;
}
export interface ApiError {
ok: false;
error: {
message: string;
code: string;
};
}
export type ApiResponse<T> = ApiSuccess<T> | ApiError;

View File

@@ -0,0 +1,29 @@
export interface BrandTheme {
primaryColor: string;
accentColor: string;
surfaceColor: string;
fontFamily: string;
logoFileId: string | null;
}
export interface CompanyProfileDto {
id: string;
companyName: string;
legalName: string;
email: string;
phone: string;
website: string;
taxId: string;
addressLine1: string;
addressLine2: string;
city: string;
state: string;
postalCode: string;
country: string;
theme: BrandTheme;
logoUrl: string | null;
updatedAt: string;
}
export type CompanyProfileInput = Omit<CompanyProfileDto, "id" | "logoUrl" | "updatedAt">;

149
shared/src/crm/types.ts Normal file
View File

@@ -0,0 +1,149 @@
export const crmRecordStatuses = ["LEAD", "ACTIVE", "ON_HOLD", "INACTIVE"] as const;
export const crmContactEntryTypes = ["NOTE", "CALL", "EMAIL", "MEETING"] as const;
export const crmLifecycleStages = ["PROSPECT", "ACTIVE", "DORMANT", "CHURNED"] as const;
export type CrmRecordStatus = (typeof crmRecordStatuses)[number];
export type CrmContactEntryType = (typeof crmContactEntryTypes)[number];
export type CrmLifecycleStage = (typeof crmLifecycleStages)[number];
export const crmContactRoles = ["PRIMARY", "PURCHASING", "AP", "SHIPPING", "ENGINEERING", "SALES", "OTHER"] as const;
export type CrmContactRole = (typeof crmContactRoles)[number];
export interface CrmContactEntryDto {
id: string;
type: CrmContactEntryType;
summary: string;
body: string;
contactAt: string;
createdAt: string;
createdBy: {
id: string | null;
name: string;
email: string | null;
};
}
export interface CrmContactEntryInput {
type: CrmContactEntryType;
summary: string;
body: string;
contactAt: string;
}
export interface CrmContactDto {
id: string;
fullName: string;
role: CrmContactRole;
email: string;
phone: string;
isPrimary: boolean;
createdAt: string;
}
export interface CrmContactInput {
fullName: string;
role: CrmContactRole;
email: string;
phone: string;
isPrimary: boolean;
}
export interface CrmCustomerChildDto {
id: string;
name: string;
status: CrmRecordStatus;
}
export interface CrmCustomerHierarchyOptionDto {
id: string;
name: string;
status: CrmRecordStatus;
isReseller: boolean;
}
export interface CrmRecordRollupsDto {
lastContactAt: string | null;
contactHistoryCount: number;
contactCount: number;
attachmentCount: number;
childCustomerCount?: number;
}
export interface CrmRecordSummaryDto {
id: string;
name: string;
email: string;
phone: string;
city: string;
state: string;
country: string;
status: CrmRecordStatus;
lifecycleStage?: CrmLifecycleStage;
preferredAccount?: boolean;
strategicAccount?: boolean;
requiresApproval?: boolean;
blockedAccount?: boolean;
isReseller?: boolean;
parentCustomerId?: string | null;
parentCustomerName?: string | null;
rollups?: CrmRecordRollupsDto;
updatedAt: string;
}
export interface CrmRecordDetailDto extends CrmRecordSummaryDto {
addressLine1: string;
addressLine2: string;
postalCode: string;
notes: string;
createdAt: string;
contactHistory: CrmContactEntryDto[];
isReseller?: boolean;
resellerDiscountPercent?: number | null;
parentCustomerId?: string | null;
parentCustomerName?: string | null;
childCustomers?: CrmCustomerChildDto[];
paymentTerms?: string | null;
currencyCode?: string | null;
taxExempt?: boolean;
creditHold?: boolean;
contacts?: CrmContactDto[];
lifecycleStage?: CrmLifecycleStage;
preferredAccount?: boolean;
strategicAccount?: boolean;
requiresApproval?: boolean;
blockedAccount?: boolean;
rollups?: CrmRecordRollupsDto;
}
export interface CrmRecordInput {
name: string;
email: string;
phone: string;
addressLine1: string;
addressLine2: string;
city: string;
state: string;
postalCode: string;
country: string;
status: CrmRecordStatus;
notes: string;
isReseller?: boolean;
resellerDiscountPercent?: number | null;
parentCustomerId?: string | null;
paymentTerms?: string | null;
currencyCode?: string | null;
taxExempt?: boolean;
creditHold?: boolean;
lifecycleStage?: CrmLifecycleStage;
preferredAccount?: boolean;
strategicAccount?: boolean;
requiresApproval?: boolean;
blockedAccount?: boolean;
}
export type CustomerSummaryDto = CrmRecordSummaryDto;
export type CustomerDetailDto = CrmRecordDetailDto;
export type CustomerInput = CrmRecordInput;
export type VendorSummaryDto = CrmRecordSummaryDto;
export type VendorDetailDto = CrmRecordDetailDto;
export type VendorInput = CrmRecordInput;

11
shared/src/files/types.ts Normal file
View File

@@ -0,0 +1,11 @@
export interface FileAttachmentDto {
id: string;
originalName: string;
mimeType: string;
sizeBytes: number;
relativePath: string;
ownerType: string;
ownerId: string;
createdAt: string;
}

47
shared/src/gantt/types.ts Normal file
View File

@@ -0,0 +1,47 @@
export interface GanttTaskDto {
id: string;
text: string;
start: string;
end: string;
progress: number;
type: "task" | "project" | "milestone";
parentId?: string | null;
status?: string;
ownerLabel?: string | null;
detailHref?: string | null;
}
export interface GanttLinkDto {
id: string;
source: string;
target: string;
type: string;
}
export interface PlanningSummaryDto {
activeProjects: number;
atRiskProjects: number;
overdueProjects: number;
activeWorkOrders: number;
overdueWorkOrders: number;
unscheduledWorkOrders: number;
horizonStart: string;
horizonEnd: string;
}
export interface PlanningExceptionDto {
id: string;
kind: "PROJECT" | "WORK_ORDER";
title: string;
status: string;
dueDate: string | null;
ownerLabel: string | null;
detailHref: string;
}
export interface PlanningTimelineDto {
tasks: GanttTaskDto[];
links: GanttLinkDto[];
summary: PlanningSummaryDto;
exceptions: PlanningExceptionDto[];
}

14
shared/src/index.ts Normal file
View File

@@ -0,0 +1,14 @@
export * from "./admin/types.js";
export * from "./auth/permissions.js";
export * from "./auth/types.js";
export * from "./common/api.js";
export * from "./company/types.js";
export * from "./crm/types.js";
export * from "./files/types.js";
export * from "./gantt/types.js";
export * from "./inventory/types.js";
export * from "./manufacturing/types.js";
export * from "./projects/types.js";
export * from "./purchasing/types.js";
export * from "./sales/types.js";
export * from "./shipping/types.js";

View File

@@ -0,0 +1,329 @@
export const inventoryItemTypes = ["PURCHASED", "MANUFACTURED", "ASSEMBLY", "SERVICE"] as const;
export const inventoryItemStatuses = ["DRAFT", "ACTIVE", "OBSOLETE"] as const;
export const inventoryUnitsOfMeasure = ["EA", "FT", "IN", "LB", "KG", "SET"] as const;
export const inventoryTransactionTypes = ["RECEIPT", "ISSUE", "ADJUSTMENT_IN", "ADJUSTMENT_OUT"] as const;
export const inventoryReservationStatuses = ["ACTIVE", "RELEASED", "CONSUMED"] as const;
export type InventoryItemType = (typeof inventoryItemTypes)[number];
export type InventoryItemStatus = (typeof inventoryItemStatuses)[number];
export type InventoryUnitOfMeasure = (typeof inventoryUnitsOfMeasure)[number];
export type InventoryTransactionType = (typeof inventoryTransactionTypes)[number];
export type InventoryReservationStatus = (typeof inventoryReservationStatuses)[number];
export interface InventorySkuFamilyDto {
id: string;
code: string;
sequenceCode: string;
name: string;
description: string;
nextSequenceNumber: number;
isActive: boolean;
childNodeCount: number;
itemCount: number;
}
export interface InventorySkuFamilyInput {
code: string;
sequenceCode: string;
name: string;
description: string;
isActive: boolean;
}
export interface InventorySkuNodeDto {
id: string;
familyId: string;
parentNodeId: string | null;
code: string;
label: string;
description: string;
path: string;
level: number;
sortOrder: number;
isActive: boolean;
childCount: number;
}
export interface InventorySkuNodeInput {
familyId: string;
parentNodeId: string | null;
code: string;
label: string;
description: string;
sortOrder: number;
isActive: boolean;
}
export interface InventorySkuCatalogTreeDto {
families: InventorySkuFamilyDto[];
nodes: InventorySkuNodeDto[];
}
export interface InventorySkuBuilderInput {
familyId: string;
nodeId: string | null;
}
export interface InventorySkuNodePathEntryDto {
id: string;
code: string;
label: string;
level: number;
}
export interface InventorySkuBuilderSelectionDto {
familyId: string;
familyCode: string;
familyName: string;
sequenceCode: string;
nodeId: string | null;
nodePath: InventorySkuNodePathEntryDto[];
sequenceNumber: number | null;
generatedSku: string;
segments: string[];
}
export interface InventorySkuBuilderPreviewDto extends InventorySkuBuilderSelectionDto {
nextSequenceNumber: number;
availableLevels: number;
hasChildren: boolean;
}
export interface InventoryBomLineDto {
id: string;
componentItemId: string;
componentSku: string;
componentName: string;
quantity: number;
unitOfMeasure: InventoryUnitOfMeasure;
notes: string;
position: number;
}
export interface InventoryBomLineInput {
componentItemId: string;
quantity: number;
unitOfMeasure: InventoryUnitOfMeasure;
notes: string;
position: number;
}
export interface InventoryItemOperationDto {
id: string;
stationId: string;
stationCode: string;
stationName: string;
setupMinutes: number;
runMinutesPerUnit: number;
moveMinutes: number;
estimatedMinutesPerUnit: number;
position: number;
notes: string;
}
export interface InventoryItemOperationInput {
stationId: string;
setupMinutes: number;
runMinutesPerUnit: number;
moveMinutes: number;
position: number;
notes: string;
}
export interface InventoryItemOptionDto {
id: string;
sku: string;
name: string;
isPurchasable: boolean;
defaultCost: number | null;
defaultPrice: number | null;
preferredVendorId: string | null;
preferredVendorName: string | null;
}
export interface WarehouseLocationOptionDto {
warehouseId: string;
warehouseCode: string;
warehouseName: string;
locationId: string;
locationCode: string;
locationName: string;
}
export interface WarehouseLocationDto {
id: string;
code: string;
name: string;
notes: string;
}
export interface WarehouseLocationInput {
code: string;
name: string;
notes: string;
}
export interface WarehouseSummaryDto {
id: string;
code: string;
name: string;
locationCount: number;
updatedAt: string;
}
export interface WarehouseDetailDto extends WarehouseSummaryDto {
notes: string;
createdAt: string;
locations: WarehouseLocationDto[];
}
export interface WarehouseInput {
code: string;
name: string;
notes: string;
locations: WarehouseLocationInput[];
}
export interface InventoryItemSummaryDto {
id: string;
sku: string;
name: string;
type: InventoryItemType;
status: InventoryItemStatus;
unitOfMeasure: InventoryUnitOfMeasure;
isSellable: boolean;
isPurchasable: boolean;
onHandQuantity: number;
availableQuantity: number;
bomLineCount: number;
updatedAt: string;
}
export interface InventoryStockBalanceDto {
warehouseId: string;
warehouseCode: string;
warehouseName: string;
locationId: string;
locationCode: string;
locationName: string;
quantityOnHand: number;
quantityReserved: number;
quantityAvailable: number;
}
export interface InventoryTransactionDto {
id: string;
transactionType: InventoryTransactionType;
quantity: number;
signedQuantity: number;
notes: string;
reference: string;
createdAt: string;
warehouseId: string;
warehouseCode: string;
warehouseName: string;
locationId: string;
locationCode: string;
locationName: string;
createdByName: string;
}
export interface InventoryTransactionInput {
transactionType: InventoryTransactionType;
quantity: number;
warehouseId: string;
locationId: string;
reference: string;
notes: string;
}
export interface InventoryTransferDto {
id: string;
quantity: number;
notes: string;
createdAt: string;
createdByName: string;
fromWarehouseId: string;
fromWarehouseCode: string;
fromWarehouseName: string;
fromLocationId: string;
fromLocationCode: string;
fromLocationName: string;
toWarehouseId: string;
toWarehouseCode: string;
toWarehouseName: string;
toLocationId: string;
toLocationCode: string;
toLocationName: string;
}
export interface InventoryTransferInput {
quantity: number;
fromWarehouseId: string;
fromLocationId: string;
toWarehouseId: string;
toLocationId: string;
notes: string;
}
export interface InventoryReservationDto {
id: string;
quantity: number;
status: InventoryReservationStatus;
sourceType: string;
sourceId: string | null;
sourceLabel: string | null;
notes: string;
createdAt: string;
warehouseId: string | null;
warehouseCode: string | null;
warehouseName: string | null;
locationId: string | null;
locationCode: string | null;
locationName: string | null;
}
export interface InventoryReservationInput {
quantity: number;
warehouseId: string | null;
locationId: string | null;
notes: string;
}
export interface InventoryItemDetailDto extends InventoryItemSummaryDto {
description: string;
defaultCost: number | null;
defaultPrice: number | null;
preferredVendorId: string | null;
preferredVendorName: string | null;
skuBuilder: InventorySkuBuilderSelectionDto | null;
notes: string;
createdAt: string;
bomLines: InventoryBomLineDto[];
operations: InventoryItemOperationDto[];
onHandQuantity: number;
reservedQuantity: number;
availableQuantity: number;
stockBalances: InventoryStockBalanceDto[];
recentTransactions: InventoryTransactionDto[];
transfers: InventoryTransferDto[];
reservations: InventoryReservationDto[];
}
export interface InventoryItemInput {
sku: string;
skuBuilder: InventorySkuBuilderInput | null;
name: string;
description: string;
type: InventoryItemType;
status: InventoryItemStatus;
unitOfMeasure: InventoryUnitOfMeasure;
isSellable: boolean;
isPurchasable: boolean;
defaultCost: number | null;
defaultPrice: number | null;
preferredVendorId: string | null;
notes: string;
bomLines: InventoryBomLineInput[];
operations: InventoryItemOperationInput[];
}

View File

@@ -0,0 +1,161 @@
export const workOrderStatuses = ["DRAFT", "RELEASED", "IN_PROGRESS", "ON_HOLD", "COMPLETE", "CANCELLED"] as const;
export type WorkOrderStatus = (typeof workOrderStatuses)[number];
export interface ManufacturingStationDto {
id: string;
code: string;
name: string;
description: string;
queueDays: number;
isActive: boolean;
createdAt: string;
updatedAt: string;
}
export interface ManufacturingStationInput {
code: string;
name: string;
description: string;
queueDays: number;
isActive: boolean;
}
export interface ManufacturingProjectOptionDto {
id: string;
projectNumber: string;
name: string;
customerName: string;
status: string;
}
export interface ManufacturingItemOptionDto {
id: string;
sku: string;
name: string;
type: string;
unitOfMeasure: string;
operationCount: number;
totalEstimatedMinutesPerUnit: number;
}
export interface WorkOrderSummaryDto {
id: string;
workOrderNumber: string;
status: WorkOrderStatus;
itemId: string;
itemSku: string;
itemName: string;
projectId: string | null;
projectNumber: string | null;
projectName: string | null;
quantity: number;
completedQuantity: number;
dueDate: string | null;
warehouseId: string;
warehouseCode: string;
warehouseName: string;
locationId: string;
locationCode: string;
locationName: string;
salesOrderId: string | null;
salesOrderLineId: string | null;
salesOrderNumber: string | null;
operationCount: number;
totalPlannedMinutes: number;
updatedAt: string;
}
export interface WorkOrderOperationDto {
id: string;
stationId: string;
stationCode: string;
stationName: string;
sequence: number;
setupMinutes: number;
runMinutesPerUnit: number;
moveMinutes: number;
plannedMinutes: number;
plannedStart: string;
plannedEnd: string;
notes: string;
}
export interface WorkOrderMaterialRequirementDto {
componentItemId: string;
componentSku: string;
componentName: string;
unitOfMeasure: string;
quantityPer: number;
requiredQuantity: number;
issuedQuantity: number;
remainingQuantity: number;
onHandQuantity: number;
reservedQuantity: number;
availableQuantity: number;
shortageQuantity: number;
}
export interface WorkOrderMaterialIssueDto {
id: string;
componentItemId: string;
componentSku: string;
componentName: string;
quantity: number;
warehouseId: string;
warehouseCode: string;
warehouseName: string;
locationId: string;
locationCode: string;
locationName: string;
notes: string;
createdAt: string;
createdByName: string;
}
export interface WorkOrderCompletionDto {
id: string;
quantity: number;
notes: string;
createdAt: string;
createdByName: string;
}
export interface WorkOrderDetailDto extends WorkOrderSummaryDto {
notes: string;
createdAt: string;
itemType: string;
itemUnitOfMeasure: string;
projectCustomerName: string | null;
dueQuantity: number;
operations: WorkOrderOperationDto[];
materialRequirements: WorkOrderMaterialRequirementDto[];
materialIssues: WorkOrderMaterialIssueDto[];
completions: WorkOrderCompletionDto[];
}
export interface WorkOrderInput {
itemId: string;
projectId: string | null;
salesOrderId: string | null;
salesOrderLineId: string | null;
status: WorkOrderStatus;
quantity: number;
warehouseId: string;
locationId: string;
dueDate: string | null;
notes: string;
}
export interface WorkOrderMaterialIssueInput {
componentItemId: string;
warehouseId: string;
locationId: string;
quantity: number;
notes: string;
}
export interface WorkOrderCompletionInput {
quantity: number;
notes: string;
}

View File

@@ -0,0 +1,72 @@
export const projectStatuses = ["PLANNED", "ACTIVE", "ON_HOLD", "AT_RISK", "COMPLETE"] as const;
export const projectPriorities = ["LOW", "MEDIUM", "HIGH", "CRITICAL"] as const;
export type ProjectStatus = (typeof projectStatuses)[number];
export type ProjectPriority = (typeof projectPriorities)[number];
export interface ProjectCustomerOptionDto {
id: string;
name: string;
email: string;
}
export interface ProjectDocumentOptionDto {
id: string;
documentNumber: string;
customerName: string;
status: string;
}
export interface ProjectShipmentOptionDto {
id: string;
shipmentNumber: string;
salesOrderNumber: string;
customerName: string;
status: string;
}
export interface ProjectOwnerOptionDto {
id: string;
fullName: string;
email: string;
}
export interface ProjectSummaryDto {
id: string;
projectNumber: string;
name: string;
status: ProjectStatus;
priority: ProjectPriority;
customerId: string;
customerName: string;
ownerId: string | null;
ownerName: string | null;
dueDate: string | null;
updatedAt: string;
}
export interface ProjectDetailDto extends ProjectSummaryDto {
notes: string;
createdAt: string;
salesQuoteId: string | null;
salesQuoteNumber: string | null;
salesOrderId: string | null;
salesOrderNumber: string | null;
shipmentId: string | null;
shipmentNumber: string | null;
customerEmail: string;
customerPhone: string;
}
export interface ProjectInput {
name: string;
status: ProjectStatus;
priority: ProjectPriority;
customerId: string;
salesQuoteId: string | null;
salesOrderId: string | null;
shipmentId: string | null;
ownerId: string | null;
dueDate: string | null;
notes: string;
}

View File

@@ -0,0 +1,193 @@
import type { InventoryUnitOfMeasure } from "../inventory/types.js";
export const purchaseOrderStatuses = ["DRAFT", "ISSUED", "APPROVED", "CLOSED"] as const;
export type PurchaseOrderStatus = (typeof purchaseOrderStatuses)[number];
export interface PurchaseVendorOptionDto {
id: string;
name: string;
email: string;
paymentTerms: string | null;
currencyCode: string | null;
}
export interface PurchaseLineDto {
id: string;
itemId: string;
itemSku: string;
itemName: string;
description: string;
quantity: number;
unitOfMeasure: InventoryUnitOfMeasure;
unitCost: number;
lineTotal: number;
receivedQuantity: number;
remainingQuantity: number;
salesOrderId: string | null;
salesOrderLineId: string | null;
salesOrderNumber: string | null;
position: number;
}
export interface PurchaseLineInput {
itemId: string;
description: string;
quantity: number;
unitOfMeasure: InventoryUnitOfMeasure;
unitCost: number;
salesOrderId?: string | null;
salesOrderLineId?: string | null;
position: number;
}
export interface PurchaseOrderSummaryDto {
id: string;
documentNumber: string;
vendorId: string;
vendorName: string;
status: PurchaseOrderStatus;
subtotal: number;
taxPercent: number;
taxAmount: number;
freightAmount: number;
total: number;
issueDate: string;
updatedAt: string;
lineCount: number;
}
export interface PurchaseOrderDetailDto extends PurchaseOrderSummaryDto {
vendorEmail: string;
notes: string;
paymentTerms: string | null;
currencyCode: string | null;
createdAt: string;
lines: PurchaseLineDto[];
receipts: PurchaseReceiptDto[];
revisions: PurchaseOrderRevisionDto[];
}
export interface PurchaseOrderInput {
vendorId: string;
status: PurchaseOrderStatus;
issueDate: string;
taxPercent: number;
freightAmount: number;
notes: string;
revisionReason?: string;
lines: PurchaseLineInput[];
}
export interface PurchaseOrderRevisionSnapshotLineDto {
itemId: string;
itemSku: string;
itemName: string;
description: string;
quantity: number;
unitOfMeasure: InventoryUnitOfMeasure;
unitCost: number;
lineTotal: number;
receivedQuantity: number;
remainingQuantity: number;
salesOrderId: string | null;
salesOrderLineId: string | null;
salesOrderNumber: string | null;
position: number;
}
export interface PurchaseOrderRevisionSnapshotReceiptLineDto {
id: string;
purchaseOrderLineId: string;
itemId: string;
itemSku: string;
itemName: string;
quantity: number;
}
export interface PurchaseOrderRevisionSnapshotReceiptDto {
id: string;
receiptNumber: string;
purchaseOrderId: string;
receivedAt: string;
notes: string;
createdAt: string;
createdByName: string;
warehouseId: string;
warehouseCode: string;
warehouseName: string;
locationId: string;
locationCode: string;
locationName: string;
totalQuantity: number;
lineCount: number;
lines: PurchaseOrderRevisionSnapshotReceiptLineDto[];
}
export interface PurchaseOrderRevisionSnapshotDto {
documentNumber: string;
vendorId: string;
vendorName: string;
status: PurchaseOrderStatus;
issueDate: string;
taxPercent: number;
taxAmount: number;
freightAmount: number;
subtotal: number;
total: number;
notes: string;
paymentTerms: string | null;
currencyCode: string | null;
lines: PurchaseOrderRevisionSnapshotLineDto[];
receipts: PurchaseOrderRevisionSnapshotReceiptDto[];
}
export interface PurchaseOrderRevisionDto {
id: string;
revisionNumber: number;
reason: string;
createdAt: string;
createdByName: string | null;
snapshot: PurchaseOrderRevisionSnapshotDto;
}
export interface PurchaseReceiptLineDto {
id: string;
purchaseOrderLineId: string;
itemId: string;
itemSku: string;
itemName: string;
quantity: number;
}
export interface PurchaseReceiptDto {
id: string;
receiptNumber: string;
purchaseOrderId: string;
receivedAt: string;
notes: string;
createdAt: string;
createdByName: string;
warehouseId: string;
warehouseCode: string;
warehouseName: string;
locationId: string;
locationCode: string;
locationName: string;
totalQuantity: number;
lineCount: number;
lines: PurchaseReceiptLineDto[];
}
export interface PurchaseReceiptLineInput {
purchaseOrderLineId: string;
quantity: number;
}
export interface PurchaseReceiptInput {
receivedAt: string;
warehouseId: string;
locationId: string;
notes: string;
lines: PurchaseReceiptLineInput[];
}

229
shared/src/sales/types.ts Normal file
View File

@@ -0,0 +1,229 @@
import type { InventoryUnitOfMeasure } from "../inventory/types.js";
export const salesDocumentStatuses = ["DRAFT", "ISSUED", "APPROVED", "CLOSED"] as const;
export type SalesDocumentStatus = (typeof salesDocumentStatuses)[number];
export type SalesDocumentType = "QUOTE" | "ORDER";
export interface SalesCustomerOptionDto {
id: string;
name: string;
email: string;
resellerDiscountPercent: number;
}
export interface SalesLineDto {
id: string;
itemId: string;
itemSku: string;
itemName: string;
description: string;
quantity: number;
unitOfMeasure: InventoryUnitOfMeasure;
unitPrice: number;
lineTotal: number;
position: number;
}
export interface SalesLineInput {
itemId: string;
description: string;
quantity: number;
unitOfMeasure: InventoryUnitOfMeasure;
unitPrice: number;
position: number;
}
export interface SalesDocumentSummaryDto {
id: string;
documentNumber: string;
customerId: string;
customerName: string;
status: SalesDocumentStatus;
approvedAt: string | null;
approvedByName: string | null;
currentRevisionNumber: number;
subtotal: number;
discountPercent: number;
discountAmount: number;
taxPercent: number;
taxAmount: number;
freightAmount: number;
total: number;
issueDate: string;
updatedAt: string;
lineCount: number;
}
export interface SalesDocumentDetailDto extends SalesDocumentSummaryDto {
customerEmail: string;
notes: string;
expiresAt: string | null;
createdAt: string;
lines: SalesLineDto[];
revisions: SalesDocumentRevisionDto[];
}
export interface SalesDocumentRevisionSnapshotLineDto {
itemId: string;
itemSku: string;
itemName: string;
description: string;
quantity: number;
unitOfMeasure: InventoryUnitOfMeasure;
unitPrice: number;
lineTotal: number;
position: number;
}
export interface SalesDocumentRevisionSnapshotDto {
documentNumber: string;
customerId: string;
customerName: string;
status: SalesDocumentStatus;
approvedAt: string | null;
approvedByName: string | null;
issueDate: string;
expiresAt: string | null;
discountPercent: number;
discountAmount: number;
taxPercent: number;
taxAmount: number;
freightAmount: number;
subtotal: number;
total: number;
notes: string;
lines: SalesDocumentRevisionSnapshotLineDto[];
}
export interface SalesOrderPlanningNodeDto {
itemId: string;
itemSku: string;
itemName: string;
itemType: string;
unitOfMeasure: InventoryUnitOfMeasure;
level: number;
grossDemand: number;
availableBefore: number;
availableAfter: number;
linkedWorkOrderSupply: number;
linkedPurchaseSupply: number;
supplyFromStock: number;
openWorkOrderSupply: number;
openPurchaseSupply: number;
supplyFromOpenWorkOrders: number;
supplyFromOpenPurchaseOrders: number;
recommendedBuildQuantity: number;
recommendedPurchaseQuantity: number;
uncoveredQuantity: number;
bomQuantityPerParent: number | null;
children: SalesOrderPlanningNodeDto[];
}
export interface SalesOrderPlanningLineDto {
lineId: string;
itemId: string;
itemSku: string;
itemName: string;
quantity: number;
unitOfMeasure: InventoryUnitOfMeasure;
rootNode: SalesOrderPlanningNodeDto;
}
export interface SalesOrderPlanningItemDto {
itemId: string;
itemSku: string;
itemName: string;
itemType: string;
unitOfMeasure: InventoryUnitOfMeasure;
grossDemand: number;
onHandQuantity: number;
reservedQuantity: number;
availableQuantity: number;
linkedWorkOrderSupply: number;
linkedPurchaseSupply: number;
openWorkOrderSupply: number;
openPurchaseSupply: number;
supplyFromStock: number;
supplyFromOpenWorkOrders: number;
supplyFromOpenPurchaseOrders: number;
recommendedBuildQuantity: number;
recommendedPurchaseQuantity: number;
uncoveredQuantity: number;
}
export interface SalesOrderPlanningSummaryDto {
lineCount: number;
itemCount: number;
buildRecommendationCount: number;
purchaseRecommendationCount: number;
uncoveredItemCount: number;
totalBuildQuantity: number;
totalPurchaseQuantity: number;
totalUncoveredQuantity: number;
}
export interface SalesOrderPlanningDto {
orderId: string;
documentNumber: string;
status: SalesDocumentStatus;
generatedAt: string;
summary: SalesOrderPlanningSummaryDto;
lines: SalesOrderPlanningLineDto[];
items: SalesOrderPlanningItemDto[];
}
export interface DemandPlanningProjectSummaryDto {
projectId: string;
projectNumber: string;
projectName: string;
salesOrderId: string;
salesOrderNumber: string;
totalBuildQuantity: number;
totalPurchaseQuantity: number;
totalUncoveredQuantity: number;
buildRecommendationCount: number;
purchaseRecommendationCount: number;
uncoveredItemCount: number;
}
export interface DemandPlanningRollupSummaryDto {
orderCount: number;
projectCount: number;
itemCount: number;
buildRecommendationCount: number;
purchaseRecommendationCount: number;
uncoveredItemCount: number;
totalBuildQuantity: number;
totalPurchaseQuantity: number;
totalUncoveredQuantity: number;
}
export interface DemandPlanningRollupDto {
generatedAt: string;
summary: DemandPlanningRollupSummaryDto;
items: SalesOrderPlanningItemDto[];
projects: DemandPlanningProjectSummaryDto[];
}
export interface SalesDocumentInput {
customerId: string;
status: SalesDocumentStatus;
issueDate: string;
expiresAt: string | null;
discountPercent: number;
taxPercent: number;
freightAmount: number;
notes: string;
lines: SalesLineInput[];
revisionReason?: string;
}
export interface SalesDocumentRevisionDto {
id: string;
revisionNumber: number;
reason: string;
createdAt: string;
createdByName: string | null;
snapshot: SalesDocumentRevisionSnapshotDto;
}

View File

@@ -0,0 +1,42 @@
export const shipmentStatuses = ["DRAFT", "PICKING", "PACKED", "SHIPPED", "DELIVERED"] as const;
export type ShipmentStatus = (typeof shipmentStatuses)[number];
export interface ShipmentOrderOptionDto {
id: string;
documentNumber: string;
customerName: string;
status: string;
total: number;
}
export interface ShipmentSummaryDto {
id: string;
shipmentNumber: string;
salesOrderId: string;
salesOrderNumber: string;
customerName: string;
status: ShipmentStatus;
carrier: string;
trackingNumber: string;
packageCount: number;
shipDate: string | null;
updatedAt: string;
}
export interface ShipmentDetailDto extends ShipmentSummaryDto {
serviceLevel: string;
notes: string;
createdAt: string;
}
export interface ShipmentInput {
salesOrderId: string;
status: ShipmentStatus;
shipDate: string | null;
carrier: string;
serviceLevel: string;
trackingNumber: string;
packageCount: number;
notes: string;
}

13
shared/tsconfig.json Normal file
View File

@@ -0,0 +1,13 @@
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"module": "NodeNext",
"moduleResolution": "NodeNext",
"outDir": "dist",
"rootDir": "src",
"declaration": true
},
"include": [
"src"
]
}