51 lines
2.4 KiB
TypeScript
51 lines
2.4 KiB
TypeScript
import type { Db } from "../db/database.js";
|
|
import { createModelRow, deleteModelRow, getModel, resolveCompany, updateModelCell } from "../db/queries.js";
|
|
import { fail, ok } from "./result.js";
|
|
import type { RpcHandlers } from "./types.js";
|
|
|
|
function errorDetail(operation: string, error: unknown): { operation: string; message?: string } {
|
|
return {
|
|
operation,
|
|
message: error instanceof Error ? error.message : undefined,
|
|
};
|
|
}
|
|
|
|
export function modelHandlers(db: Db): RpcHandlers<"model.get" | "model.updateCell" | "model.createRow" | "model.deleteRow" | "model.runScenario"> {
|
|
return {
|
|
"model.get": ({ companyId, tab }) => {
|
|
const company = resolveCompany(db, companyId);
|
|
if (!company) return fail("NOT_FOUND", `Company "${companyId}" not found.`);
|
|
try {
|
|
return ok("model.get", getModel(db, company.id, tab));
|
|
} catch (error) {
|
|
return fail("INTERNAL_ERROR", "Could not load model for company.", errorDetail("getModel", error));
|
|
}
|
|
},
|
|
"model.updateCell": ({ companyId, tab, row, col, value }) => {
|
|
const company = resolveCompany(db, companyId);
|
|
if (!company) return fail("NOT_FOUND", `Company "${companyId}" not found.`);
|
|
return ok("model.updateCell", updateModelCell(db, company.id, tab, row, col, value));
|
|
},
|
|
"model.createRow": ({ companyId, tab, label, kind, values }) => {
|
|
const company = resolveCompany(db, companyId);
|
|
if (!company) return fail("NOT_FOUND", `Company "${companyId}" not found.`);
|
|
return ok("model.createRow", createModelRow(db, company.id, tab, { label, kind, values: values ?? [] }));
|
|
},
|
|
"model.deleteRow": ({ companyId, tab, row }) => {
|
|
const company = resolveCompany(db, companyId);
|
|
if (!company) return fail("NOT_FOUND", `Company "${companyId}" not found.`);
|
|
return ok("model.deleteRow", { ok: deleteModelRow(db, company.id, tab, row) });
|
|
},
|
|
"model.runScenario": ({ companyId, overrides }) => {
|
|
const company = resolveCompany(db, companyId);
|
|
if (!company) return fail("NOT_FOUND", `Company "${companyId}" not found.`);
|
|
const model = getModel(db, company.id, "operating");
|
|
const rows = model.rows.map((row, rowIndex) => ({
|
|
...row,
|
|
values: row.values.map((value, colIndex) => overrides[`${rowIndex}-${colIndex}`] ?? value),
|
|
}));
|
|
return ok("model.runScenario", { headers: model.headers, rows });
|
|
},
|
|
};
|
|
}
|