// vibe_erp REST API types. // // Hand-written rather than codegen'd from /v3/api-docs to keep the // build pipeline simple — the framework already has springdoc-openapi // serving the live spec, but adding @openapitools/openapi-generator-cli // would pull in another Java toolchain into the npm build. v1 SPA can // stay typed by hand; v1.x can revisit codegen if drift becomes a // real problem. Every type here mirrors the matching @RestController's // response DTO under pbc/*/http/. // // **BigDecimal as string.** The Spring Boot Jackson default serializes // java.math.BigDecimal as a JSON number, which JavaScript would coerce // to a 64-bit float and lose precision on quantities like 12345.6789. // In practice the framework configures `spring.jackson.write-bigdecimal-as-plain` // (default for Spring Boot 3) which still emits a JSON *number*; the SPA // stores them as `string` because we never do client-side arithmetic on // them — display only. If a future SPA needs sums it should round-trip // through decimal.js, not Number(). export interface MetaInfo { name: string apiVersion: string implementationVersion: string buildTime: string | null activeProfiles: string[] } // ─── Auth (pbc-identity AuthController) ────────────────────────────── export interface LoginRequest { username: string password: string } export interface TokenPair { accessToken: string accessExpiresAt: string refreshToken: string refreshExpiresAt: string tokenType: string } // ─── Identity (pbc-identity) ───────────────────────────────────────── export interface User { id: string username: string displayName: string email: string | null enabled: boolean } export interface Role { id: string code: string name: string description: string | null } // ─── Catalog (pbc-catalog) ─────────────────────────────────────────── export type ItemType = 'GOOD' | 'SERVICE' | 'DIGITAL' export interface Item { id: string code: string name: string description: string | null itemType: ItemType baseUomCode: string active: boolean ext: Record } export interface Uom { id: string code: string name: string dimension: string } // ─── Partners (pbc-partners) ───────────────────────────────────────── export type PartnerType = 'CUSTOMER' | 'SUPPLIER' | 'BOTH' export interface Partner { id: string code: string name: string type: PartnerType taxId: string | null website: string | null email: string | null phone: string | null active: boolean ext: Record } // ─── Inventory (pbc-inventory) ─────────────────────────────────────── export type LocationType = 'WAREHOUSE' | 'BIN' | 'VIRTUAL' export interface Location { id: string code: string name: string type: LocationType active: boolean ext: Record } // Note: balances/movements use a UUID `locationId`, not `locationCode`. // The list pages join against `Location.id → code` client-side. export interface StockBalance { id: string itemCode: string locationId: string quantity: string | number } export type MovementReason = | 'RECEIPT' | 'ISSUE' | 'ADJUSTMENT' | 'SALES_SHIPMENT' | 'PURCHASE_RECEIPT' | 'TRANSFER_OUT' | 'TRANSFER_IN' | 'MATERIAL_ISSUE' | 'PRODUCTION_RECEIPT' export interface StockMovement { id: string itemCode: string locationId: string delta: string | number reason: MovementReason reference: string | null occurredAt: string resultingQuantity?: string | number } // ─── Sales orders (pbc-orders-sales) ───────────────────────────────── export type SalesOrderStatus = 'DRAFT' | 'CONFIRMED' | 'SHIPPED' | 'CANCELLED' export interface SalesOrderLine { id: string lineNo: number itemCode: string quantity: string | number unitPrice: string | number currencyCode: string lineTotal: string | number } export interface SalesOrder { id: string code: string partnerCode: string status: SalesOrderStatus orderDate: string currencyCode: string totalAmount: string | number lines: SalesOrderLine[] ext: Record } // ─── Purchase orders (pbc-orders-purchase) ─────────────────────────── export type PurchaseOrderStatus = 'DRAFT' | 'CONFIRMED' | 'RECEIVED' | 'CANCELLED' export interface PurchaseOrderLine { id: string lineNo: number itemCode: string quantity: string | number unitPrice: string | number currencyCode: string lineTotal: string | number } export interface PurchaseOrder { id: string code: string partnerCode: string status: PurchaseOrderStatus orderDate: string expectedDate: string | null currencyCode: string totalAmount: string | number lines: PurchaseOrderLine[] ext: Record } // ─── Production (pbc-production) ───────────────────────────────────── export type WorkOrderStatus = 'DRAFT' | 'IN_PROGRESS' | 'COMPLETED' | 'CANCELLED' export type WorkOrderOperationStatus = 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' export interface WorkOrderInput { id: string lineNo: number itemCode: string quantityPerUnit: string | number sourceLocationCode: string } export interface WorkOrderOperation { id: string lineNo: number operationCode: string workCenter: string standardMinutes: string | number status: WorkOrderOperationStatus actualMinutes: string | number | null startedAt: string | null completedAt: string | null } export interface WorkOrder { id: string code: string outputItemCode: string outputQuantity: string | number status: WorkOrderStatus dueDate: string | null sourceSalesOrderCode: string | null inputs: WorkOrderInput[] operations: WorkOrderOperation[] ext: Record } export interface ShopFloorEntry { workOrderId: string workOrderCode: string outputItemCode: string outputQuantity: string | number sourceSalesOrderCode: string | null currentOperationLineNo: number | null currentOperationCode: string | null currentWorkCenter: string | null currentOperationStatus: WorkOrderOperationStatus | null operationsCompleted: number operationsTotal: number totalStandardMinutes: string | number totalActualMinutes: string | number } // ─── Finance (pbc-finance) ─────────────────────────────────────────── export type AccountType = 'ASSET' | 'LIABILITY' | 'EQUITY' | 'REVENUE' | 'EXPENSE' export interface Account { id: string code: string name: string accountType: AccountType description: string | null active: boolean } export type JournalEntryType = 'AR' | 'AP' export type JournalEntryStatus = 'POSTED' | 'SETTLED' | 'REVERSED' export interface JournalEntry { id: string code: string type: JournalEntryType status: JournalEntryStatus partnerCode: string orderCode: string amount: string | number currencyCode: string postedAt: string }