import { approveEstimateVersion, createEstimate, createEstimateExport, createEstimateRevision, submitEstimateVersion, updateEstimateDraft, } from "../../packages/application/src/index.js"; import { PrismaClient } from "../../packages/db/src/index.js"; import { EstimateExportFormat } from "../../packages/shared/src/index.js"; const prisma = new PrismaClient(); async function main() { const created = await createEstimate(prisma, { name: "Codex Smoke Estimate", baseCurrency: "EUR", assumptions: [ { category: "commercial", key: "delivery_model", label: "Delivery Model", valueType: "string", value: "hybrid", sortOrder: 0, }, ], scopeItems: [ { sequenceNo: 1, scopeType: "SHOT", name: "Smoke Scope", technicalSpec: {}, sortOrder: 0, metadata: {}, }, ], demandLines: [ { lineType: "LABOR", name: "Senior Comp", hours: 40, costRateCents: 5000, billRateCents: 9000, costTotalCents: 200000, priceTotalCents: 360000, currency: "EUR", monthlySpread: {}, staffingAttributes: {}, metadata: {}, }, ], resourceSnapshots: [], metrics: [ { key: "total_hours", label: "Total Hours", metricGroup: "summary", valueDecimal: 40, metadata: {}, }, { key: "total_cost", label: "Total Cost", metricGroup: "summary", valueDecimal: 2000, valueCents: 200000, currency: "EUR", metadata: {}, }, { key: "total_price", label: "Total Price", metricGroup: "summary", valueDecimal: 3600, valueCents: 360000, currency: "EUR", metadata: {}, }, { key: "margin", label: "Margin", metricGroup: "summary", valueDecimal: 1600, valueCents: 160000, currency: "EUR", metadata: {}, }, { key: "margin_percent", label: "Margin %", metricGroup: "summary", valueDecimal: 44.4444, metadata: {}, }, ], }); try { const workingVersion = created.versions[0]; const updated = await updateEstimateDraft(prisma, { id: created.id, name: "Codex Smoke Estimate Updated", baseCurrency: "EUR", versionLabel: "Working Draft", versionNotes: "updated by smoke test", assumptions: [ { id: workingVersion.assumptions[0]?.id, category: "commercial", key: "delivery_model", label: "Delivery Model", valueType: "string", value: "onsite", sortOrder: 0, }, ], scopeItems: workingVersion.scopeItems.map((item, index) => ({ id: item.id, sequenceNo: item.sequenceNo, scopeType: item.scopeType, ...(item.description ? { description: item.description } : {}), name: item.name, technicalSpec: {}, sortOrder: index, metadata: {}, })), demandLines: workingVersion.demandLines.map((line) => ({ id: line.id, ...(line.scopeItemId ? { scopeItemId: line.scopeItemId } : {}), ...(line.roleId ? { roleId: line.roleId } : {}), ...(line.resourceId ? { resourceId: line.resourceId } : {}), lineType: line.lineType, name: line.name, hours: 48, costRateCents: line.costRateCents, billRateCents: line.billRateCents, costTotalCents: 240000, priceTotalCents: 432000, currency: line.currency, monthlySpread: {}, staffingAttributes: {}, metadata: {}, })), resourceSnapshots: workingVersion.resourceSnapshots.map((snapshot) => ({ id: snapshot.id, ...(snapshot.resourceId ? { resourceId: snapshot.resourceId } : {}), ...(snapshot.sourceEid ? { sourceEid: snapshot.sourceEid } : {}), displayName: snapshot.displayName, ...(snapshot.chapter ? { chapter: snapshot.chapter } : {}), ...(snapshot.roleId ? { roleId: snapshot.roleId } : {}), currency: snapshot.currency, lcrCents: snapshot.lcrCents, ucrCents: snapshot.ucrCents, ...(snapshot.fte != null ? { fte: snapshot.fte } : {}), ...(snapshot.location ? { location: snapshot.location } : {}), ...(snapshot.country ? { country: snapshot.country } : {}), ...(snapshot.level ? { level: snapshot.level } : {}), ...(snapshot.workType ? { workType: snapshot.workType } : {}), attributes: typeof snapshot.attributes === "object" && snapshot.attributes !== null && !Array.isArray(snapshot.attributes) ? snapshot.attributes : {}, })), metrics: [ { key: "total_hours", label: "Total Hours", metricGroup: "summary", valueDecimal: 48, metadata: {}, }, { key: "total_cost", label: "Total Cost", metricGroup: "summary", valueDecimal: 2400, valueCents: 240000, currency: "EUR", metadata: {}, }, { key: "total_price", label: "Total Price", metricGroup: "summary", valueDecimal: 4320, valueCents: 432000, currency: "EUR", metadata: {}, }, { key: "margin", label: "Margin", metricGroup: "summary", valueDecimal: 1920, valueCents: 192000, currency: "EUR", metadata: {}, }, { key: "margin_percent", label: "Margin %", metricGroup: "summary", valueDecimal: 44.4444, metadata: {}, }, ], }); const submitted = await submitEstimateVersion(prisma, { estimateId: created.id, }); const approved = await approveEstimateVersion(prisma, { estimateId: created.id, }); const revised = await createEstimateRevision(prisma, { estimateId: created.id, sourceVersionId: approved.versions.find((version) => version.status === "APPROVED")?.id ?? approved.versions[0]?.id, }); const exported = await createEstimateExport(prisma, { estimateId: created.id, versionId: revised.versions.find((version) => version.status === "WORKING")?.id, format: EstimateExportFormat.JSON, }); const refreshed = await prisma.estimate.findUnique({ where: { id: created.id }, include: { versions: { include: { assumptions: true, demandLines: true, metrics: true, exports: true, }, orderBy: { versionNumber: "desc" }, }, }, }); console.log( JSON.stringify({ createdId: created.id, updatedName: updated.name, versionLabel: updated.versions[0]?.label ?? null, assumptionValue: refreshed?.versions[0]?.assumptions[0]?.value ?? null, updatedHours: refreshed?.versions[0]?.demandLines[0]?.hours ?? null, metricKeys: refreshed?.versions[0]?.metrics.map((metric) => metric.key) ?? [], submittedStatus: submitted.versions.find((version) => version.status === "SUBMITTED")?.status ?? null, approvedStatus: approved.versions.find((version) => version.status === "APPROVED")?.status ?? null, revisionVersionNumber: revised.versions.find((version) => version.status === "WORKING") ?.versionNumber ?? null, exportFileName: exported.versions[0]?.exports[0]?.fileName ?? refreshed?.versions[0]?.exports[0]?.fileName ?? null, }), ); } finally { await prisma.estimate.delete({ where: { id: created.id } }); } } main() .catch((error) => { console.error(error); process.exit(1); }) .finally(async () => { await prisma.$disconnect(); });