proposal-system/shared/api-contracts/src/index.ts
Adam Moussa 51ca6df403 fix(web): WEB-M3, M4, M8, M9, M11 — scope validation, category alignment, dashboard errors, line item skeleton, return-to-review
- WEB-M3: Add minimum length validation (10 chars) on scope of work field
  with inline MUI error message
- WEB-M4: Add 'Other' to shared ServiceCategory contract to align with
  API enum (already present in frontend and backend)
- WEB-M8: Show error alert with retry button instead of misleading zeros
  when dashboard stats fetch fails (both dispatcher and admin dashboards)
- WEB-M9: Add MUI Skeleton loading state for line items in admin workspace
- WEB-M11: Wire 'Return to Review' button on approved proposals — backend
  supports Approved->InReview transition, API client already had the method
2026-05-27 18:18:44 -04:00

62 lines
1.8 KiB
TypeScript

export type ProposalStatus = 'Draft' | 'InReview' | 'Approved' | 'Sent' | 'Revised';
// Fix: WEB-M4 — align with API enum (ProposalSystem.Domain.Entities.ServiceCategory includes 'Other')
export type ServiceCategory = 'HVAC' | 'Plumbing' | 'Electrical' | 'General' | 'Renovation' | 'Other';
export type Priority = 'Standard' | 'Urgent' | 'Emergency';
export type LineItemSource = 'AI' | 'Vendor' | 'Manual' | 'Historical';
export type PricingMode = 'UnitPrice' | 'TotalPrice' | 'Both';
export type UserRole = 'Dispatcher' | 'Admin' | 'SysAdmin';
export interface Proposal {
id: string;
proposalNumber: string;
workOrderNumber: string;
customerName: string;
customerAddress: string;
scopeOfWork: string;
refinedScope: string | null;
serviceCategory: ServiceCategory;
priority: Priority;
status: ProposalStatus;
totalBidAmount: number;
vendorTotalCost: number | null;
notes: string;
submittedById: string;
submittedAt: string;
assignedAdminId: string | null;
approvedById: string | null;
approvedAt: string | null;
sentAt: string | null;
currentRevision: number;
parentProposalId: string | null;
createdAt: string;
updatedAt: string;
}
export interface LineItem {
id: string;
proposalId: string;
description: string;
quantity: number;
unit: string;
unitPrice: number | null;
totalPrice: number;
pricingMode: PricingMode;
sortOrder: number;
source: LineItemSource;
createdAt: string;
updatedAt: string;
}
export interface CreateProposalRequest {
workOrderNumber: string;
customerName: string;
customerAddress: string;
scopeOfWork: string;
serviceCategory: ServiceCategory;
priority: Priority;
notes?: string;
}
export interface UpdateLineItemsRequest {
lineItems: Omit<LineItem, 'id' | 'proposalId' | 'createdAt' | 'updatedAt'>[];
}