@teincfood/core 0.9.24 → 0.9.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -189,7 +189,7 @@ export function createMemoryDriver() {
189
189
  }
190
190
  // orders insert (primary DB)
191
191
  if (s.includes("INSERT INTO orders")) {
192
- const [id, business_id, order_number, callout_number, status, order_type, is_pos, items, subtotal_minor, total_minor, tax_minor, tax_lines, payment, customer_name, customer_phone, pos_payment_method, delivery_id, business, user, inserted_at, hlc] = args;
192
+ const [id, business_id, order_number, callout_number, status, order_type, is_pos, items, subtotal_minor, total_minor, tax_minor, tax_lines, payment, paid_at, customer_name, customer_phone, pos_payment_method, delivery_id, business, user, inserted_at, updated_at, hlc] = args;
193
193
  const existing = tables.orders.find((r) => r.id === id);
194
194
  // LWW check via hlc (if existing and incoming older, skip) — only for
195
195
  // the local/LAN write path. The server write path (`upsertServerOrder`)
@@ -198,10 +198,10 @@ export function createMemoryDriver() {
198
198
  if (existing) {
199
199
  if (lwwGuarded && hlc && existing.hlc && hlc < existing.hlc)
200
200
  return { lastInsertRowId: 0, changes: 0 };
201
- Object.assign(existing, { business_id, order_number, callout_number, status, order_type, is_pos, items, subtotal_minor, total_minor, tax_minor, tax_lines, payment, customer_name, customer_phone, pos_payment_method, delivery_id, business, user, inserted_at, hlc });
201
+ Object.assign(existing, { business_id, order_number, callout_number, status, order_type, is_pos, items, subtotal_minor, total_minor, tax_minor, tax_lines, payment, paid_at: paid_at ?? existing.paid_at ?? null, customer_name, customer_phone, pos_payment_method, delivery_id, business, user, inserted_at, updated_at, hlc });
202
202
  return { lastInsertRowId: 0, changes: 1 };
203
203
  }
204
- tables.orders.push({ id, business_id, order_number, callout_number, status, order_type, is_pos, items, subtotal_minor, total_minor, tax_minor, tax_lines, payment, customer_name, customer_phone, pos_payment_method, delivery_id, business, user, inserted_at, hlc, deleted_at: null });
204
+ tables.orders.push({ id, business_id, order_number, callout_number, status, order_type, is_pos, items, subtotal_minor, total_minor, tax_minor, tax_lines, payment, paid_at: paid_at ?? null, customer_name, customer_phone, pos_payment_method, delivery_id, business, user, inserted_at, updated_at, hlc, deleted_at: null });
205
205
  return { lastInsertRowId: 1, changes: 1 };
206
206
  }
207
207
  // sync_jobs insert
@@ -263,10 +263,11 @@ export function createMemoryDriver() {
263
263
  return { lastInsertRowId: 0, changes: 1 };
264
264
  }
265
265
  if (s.includes("UPDATE orders SET payment = ?")) {
266
- const [payment, hlc, business_id, id1, id2] = args;
266
+ const [payment, paid_at, hlc, business_id, id1, id2] = args;
267
267
  const row = tables.orders.find((r) => r.business_id === business_id && (r.id === id1 || r.order_number === id2));
268
268
  if (row) {
269
269
  row.payment = payment;
270
+ row.paid_at = row.paid_at ?? paid_at ?? null;
270
271
  row.hlc = hlc;
271
272
  }
272
273
  return { lastInsertRowId: 0, changes: 1 };
@@ -356,6 +357,12 @@ export function createMemoryDriver() {
356
357
  const row = tables.orders.find((r) => r.business_id === business_id && (r.id === id1 || r.order_number === id2));
357
358
  return row ?? null;
358
359
  }
360
+ // orders business lookup by id/number (payment event with no business_id)
361
+ if (s.includes("SELECT business_id FROM orders WHERE id = ? OR order_number = ?")) {
362
+ const [id1, id2] = args;
363
+ const row = tables.orders.find((r) => r.id === id1 || r.order_number === id2);
364
+ return (row ? { business_id: row.business_id } : null);
365
+ }
359
366
  // orders hlc probe (absorb-if-applied touch detection)
360
367
  if (s.includes("SELECT hlc FROM orders WHERE business_id = ? AND id = ?")) {
361
368
  const [business_id, id] = args;
@@ -446,20 +453,20 @@ export function createMemoryDriver() {
446
453
  if (s.includes("json_extract(payment, '$.is_paid') = 1")) {
447
454
  rows = rows.filter((r) => {
448
455
  try {
449
- return JSON.parse(r.payment ?? "{}").is_paid === true;
456
+ return JSON.parse(r.payment ?? "{}").is_paid === true || r.paid_at != null;
450
457
  }
451
458
  catch {
452
- return false;
459
+ return r.paid_at != null;
453
460
  }
454
461
  });
455
462
  }
456
- else if (s.includes("json_extract(payment, '$.is_paid') IS NULL")) {
463
+ else if (s.includes("json_extract(payment, '$.is_paid'), 0) = 0")) {
457
464
  rows = rows.filter((r) => {
458
465
  try {
459
- return JSON.parse(r.payment ?? "{}").is_paid !== true;
466
+ return JSON.parse(r.payment ?? "{}").is_paid !== true && r.paid_at == null;
460
467
  }
461
468
  catch {
462
- return true;
469
+ return r.paid_at == null;
463
470
  }
464
471
  });
465
472
  }
@@ -501,7 +508,7 @@ export function createMemoryDriver() {
501
508
  const rows = tables.sync_jobs
502
509
  .filter((r) => r.business_id === business_id && r.entity_id === entity_id && r.status === "pending")
503
510
  .sort((a, b) => (a.created_at < b.created_at ? -1 : a.created_at > b.created_at ? 1 : a.rowid - b.rowid))
504
- .map((r) => ({ command_type: r.command_type }));
511
+ .map((r) => ({ command_type: r.command_type, payload: r.payload }));
505
512
  return rows;
506
513
  }
507
514
  if (s.includes("SELECT * FROM sync_jobs WHERE") || s.includes("SELECT id, command_type, status, created_at FROM sync_jobs")) {
@@ -10,6 +10,13 @@ export interface Business {
10
10
  is_open: boolean;
11
11
  /** Seller-facing open/close toggle (present when backend serializes it). */
12
12
  manually_closed?: boolean;
13
+ /**
14
+ * Fulfilment flow for orders taken on a terminal / in the business app.
15
+ * "staged" (default) = accept → preparing → ready → completed;
16
+ * "direct" = completed the moment the sale is rung up.
17
+ * Buyer-placed online orders always keep the staged pipeline.
18
+ */
19
+ pos_order_flow?: "staged" | "direct";
13
20
  owner_id: string;
14
21
  business_number: string;
15
22
  latitude: number;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@teincfood/core",
3
- "version": "0.9.24",
4
- "description": "TeincFood shared offline-first core \u2014 types, sync engine, local DB, reference data, and repositories for mobile + desktop",
3
+ "version": "0.9.26",
4
+ "description": "TeincFood shared offline-first core — types, sync engine, local DB, reference data, and repositories for mobile + desktop",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",