All display labels in MARKETS/ENTITY_TYPES/FIELDS/ENRICHMENTS/FREQUENCIES/DELIVERY_FORMATS + SERVICES/FLOW_LABEL are now {en,sv} with stable IDs/values (pricing logic, EntityType/Frequency unions, config keys unchanged). Added entityLabel()/FREQUENCY_LABEL/FORMAT_LABEL. Updated all render sites (configurator, tjanster, beskriv, katalog/[id]) to resolve via useT(). Also fixed 2 pre-existing tsc nits (auth BufferSource cast, orders-store sql.json param type). tsc 0, build green. 0pt is now fully English-by-default with SV toggle.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
104 lines
3.7 KiB
TypeScript
104 lines
3.7 KiB
TypeScript
import { getSql } from "@/lib/db";
|
|
import { computeEstimate, type EntityType, type Frequency } from "@/lib/data";
|
|
import { serviceById } from "@/lib/services";
|
|
|
|
export interface OrderConfig {
|
|
markets?: string[];
|
|
type?: EntityType;
|
|
fieldIds?: string[];
|
|
enrichmentIds?: string[];
|
|
volume?: number;
|
|
frequency?: Frequency;
|
|
confidence?: number;
|
|
formats?: string[];
|
|
service_type?: string;
|
|
}
|
|
|
|
export interface Order {
|
|
order_id: string;
|
|
flow: string;
|
|
status: string;
|
|
config: OrderConfig;
|
|
total_ore: number;
|
|
deposit_ore: number;
|
|
balance_ore: number;
|
|
est_days: number;
|
|
est_confidence: number;
|
|
created_at: string;
|
|
}
|
|
|
|
// Non-durable fallback used only until a database is provisioned.
|
|
const mem = new Map<string, Order>();
|
|
|
|
function estimateFor(config: OrderConfig) {
|
|
return computeEstimate({
|
|
markets: config.markets ?? [],
|
|
type: config.type ?? "Bolag",
|
|
fieldIds: config.fieldIds ?? [],
|
|
enrichmentIds: config.enrichmentIds ?? [],
|
|
volume: config.volume ?? 1000,
|
|
frequency: config.frequency ?? "Engångs",
|
|
confidence: config.confidence ?? 92,
|
|
serviceMult: serviceById(config.service_type ?? "")?.mult ?? 1,
|
|
});
|
|
}
|
|
|
|
export async function createOrder(flow: string, config: OrderConfig): Promise<Order> {
|
|
const est = estimateFor(config);
|
|
const sql = getSql();
|
|
if (sql) {
|
|
const [row] = await sql<{ order_id: string; created_at: string }[]>`
|
|
INSERT INTO orders (flow, status, config, total_ore, deposit_ore, balance_ore, est_days, est_confidence)
|
|
VALUES (${flow}, 'draft', ${sql.json(config as Parameters<typeof sql.json>[0])}, ${est.price * 100}, ${est.deposit * 100},
|
|
${est.remainder * 100}, ${est.timelineDays}, ${est.estConfidence / 100})
|
|
RETURNING order_id, created_at`;
|
|
return {
|
|
order_id: row.order_id, flow, status: "draft", config,
|
|
total_ore: est.price * 100, deposit_ore: est.deposit * 100, balance_ore: est.remainder * 100,
|
|
est_days: est.timelineDays, est_confidence: est.estConfidence / 100, created_at: row.created_at,
|
|
};
|
|
}
|
|
const id = (globalThis.crypto?.randomUUID?.() ?? `SX-${Math.floor(1000 + Math.random() * 9000)}`);
|
|
const order: Order = {
|
|
order_id: id, flow, status: "draft", config,
|
|
total_ore: est.price * 100, deposit_ore: est.deposit * 100, balance_ore: est.remainder * 100,
|
|
est_days: est.timelineDays, est_confidence: est.estConfidence / 100, created_at: new Date().toISOString(),
|
|
};
|
|
mem.set(id, order);
|
|
return order;
|
|
}
|
|
|
|
export async function getOrder(id: string): Promise<Order | null> {
|
|
const sql = getSql();
|
|
if (sql) {
|
|
const rows = await sql<Order[]>`
|
|
SELECT order_id, flow, status, config, total_ore, deposit_ore, balance_ore, est_days, est_confidence, created_at
|
|
FROM orders WHERE order_id::text = ${id} LIMIT 1`;
|
|
return rows[0] ?? null;
|
|
}
|
|
return mem.get(id) ?? null;
|
|
}
|
|
|
|
export async function listOrders(): Promise<Order[]> {
|
|
const sql = getSql();
|
|
if (sql) {
|
|
return sql<Order[]>`
|
|
SELECT order_id, flow, status, config, total_ore, deposit_ore, balance_ore, est_days, est_confidence, created_at
|
|
FROM orders ORDER BY created_at DESC LIMIT 100`;
|
|
}
|
|
return [...mem.values()].sort((a, b) => b.created_at.localeCompare(a.created_at));
|
|
}
|
|
|
|
export async function setStatus(id: string, status: string): Promise<Order | null> {
|
|
const sql = getSql();
|
|
if (sql) {
|
|
const rows = await sql<Order[]>`
|
|
UPDATE orders SET status = ${status}, updated_at = now() WHERE order_id::text = ${id}
|
|
RETURNING order_id, flow, status, config, total_ore, deposit_ore, balance_ore, est_days, est_confidence, created_at`;
|
|
return rows[0] ?? null;
|
|
}
|
|
const o = mem.get(id);
|
|
if (o) { o.status = status; mem.set(id, o); }
|
|
return o ?? null;
|
|
}
|