@soostori/desktop-adapter 0.1.0-alpha.3

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.
Files changed (81) hide show
  1. package/dist/auth-pin.d.ts +16 -0
  2. package/dist/auth-pin.d.ts.map +1 -0
  3. package/dist/auth-pin.js +14 -0
  4. package/dist/auth-pin.js.map +1 -0
  5. package/dist/business-repository.d.ts +31 -0
  6. package/dist/business-repository.d.ts.map +1 -0
  7. package/dist/business-repository.js +61 -0
  8. package/dist/business-repository.js.map +1 -0
  9. package/dist/categories-repository.d.ts +15 -0
  10. package/dist/categories-repository.d.ts.map +1 -0
  11. package/dist/categories-repository.js +35 -0
  12. package/dist/categories-repository.js.map +1 -0
  13. package/dist/customers-repository.d.ts +20 -0
  14. package/dist/customers-repository.d.ts.map +1 -0
  15. package/dist/customers-repository.js +95 -0
  16. package/dist/customers-repository.js.map +1 -0
  17. package/dist/debts-repository.d.ts +48 -0
  18. package/dist/debts-repository.d.ts.map +1 -0
  19. package/dist/debts-repository.js +57 -0
  20. package/dist/debts-repository.js.map +1 -0
  21. package/dist/devices-repository.d.ts +29 -0
  22. package/dist/devices-repository.d.ts.map +1 -0
  23. package/dist/devices-repository.js +120 -0
  24. package/dist/devices-repository.js.map +1 -0
  25. package/dist/domain-repositories.d.ts +12 -0
  26. package/dist/domain-repositories.d.ts.map +1 -0
  27. package/dist/domain-repositories.js +12 -0
  28. package/dist/domain-repositories.js.map +1 -0
  29. package/dist/index.d.ts +25 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +25 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/inventory-repository.d.ts +31 -0
  34. package/dist/inventory-repository.d.ts.map +1 -0
  35. package/dist/inventory-repository.js +127 -0
  36. package/dist/inventory-repository.js.map +1 -0
  37. package/dist/products-repository-mappers.d.ts +77 -0
  38. package/dist/products-repository-mappers.d.ts.map +1 -0
  39. package/dist/products-repository-mappers.js +75 -0
  40. package/dist/products-repository-mappers.js.map +1 -0
  41. package/dist/products-repository-read.d.ts +17 -0
  42. package/dist/products-repository-read.d.ts.map +1 -0
  43. package/dist/products-repository-read.js +51 -0
  44. package/dist/products-repository-read.js.map +1 -0
  45. package/dist/products-repository-stock.d.ts +28 -0
  46. package/dist/products-repository-stock.d.ts.map +1 -0
  47. package/dist/products-repository-stock.js +57 -0
  48. package/dist/products-repository-stock.js.map +1 -0
  49. package/dist/products-repository-types.d.ts +51 -0
  50. package/dist/products-repository-types.d.ts.map +1 -0
  51. package/dist/products-repository-types.js +5 -0
  52. package/dist/products-repository-types.js.map +1 -0
  53. package/dist/products-repository-variants.d.ts +19 -0
  54. package/dist/products-repository-variants.d.ts.map +1 -0
  55. package/dist/products-repository-variants.js +26 -0
  56. package/dist/products-repository-variants.js.map +1 -0
  57. package/dist/products-repository-write.d.ts +14 -0
  58. package/dist/products-repository-write.d.ts.map +1 -0
  59. package/dist/products-repository-write.js +99 -0
  60. package/dist/products-repository-write.js.map +1 -0
  61. package/dist/products-repository.d.ts +69 -0
  62. package/dist/products-repository.d.ts.map +1 -0
  63. package/dist/products-repository.js +48 -0
  64. package/dist/products-repository.js.map +1 -0
  65. package/dist/sales-repository.d.ts +95 -0
  66. package/dist/sales-repository.d.ts.map +1 -0
  67. package/dist/sales-repository.js +160 -0
  68. package/dist/sales-repository.js.map +1 -0
  69. package/dist/sqlite-database.d.ts +16 -0
  70. package/dist/sqlite-database.d.ts.map +1 -0
  71. package/dist/sqlite-database.js +24 -0
  72. package/dist/sqlite-database.js.map +1 -0
  73. package/dist/sqlite-repository.d.ts +18 -0
  74. package/dist/sqlite-repository.d.ts.map +1 -0
  75. package/dist/sqlite-repository.js +61 -0
  76. package/dist/sqlite-repository.js.map +1 -0
  77. package/dist/sqlite-transaction.d.ts +13 -0
  78. package/dist/sqlite-transaction.d.ts.map +1 -0
  79. package/dist/sqlite-transaction.js +35 -0
  80. package/dist/sqlite-transaction.js.map +1 -0
  81. package/package.json +40 -0
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Auth adapter — wires Desktop PIN auth to @soostori/auth.
3
+ *
4
+ * PIN hashing is already aligned:
5
+ * Desktop: pbkdf2Sync(pin, salt, 100_000, 32, 'sha256')
6
+ * SDK: pbkdf2Sync(pin, salt, PIN_PBKDF2_ITERATIONS=100_000, 32, 'sha256')
7
+ *
8
+ * Session persistence (electron-store) lives in soostori-desktop/electron/auth/electron-store-session.ts,
9
+ * not here — this file is platform-agnostic.
10
+ */
11
+ import { hashPin, verifyPin } from '@soostori/auth/pin-node';
12
+ import { ROLE_PERMISSIONS, hasPermission } from '@soostori/auth';
13
+ import type { SessionStorage } from '@soostori/auth';
14
+ export { hashPin, verifyPin, ROLE_PERMISSIONS, hasPermission };
15
+ export type { SessionStorage };
16
+ //# sourceMappingURL=auth-pin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-pin.d.ts","sourceRoot":"","sources":["../src/auth-pin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEpD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,aAAa,EAAE,CAAA;AAC9D,YAAY,EAAE,cAAc,EAAE,CAAA"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Auth adapter — wires Desktop PIN auth to @soostori/auth.
3
+ *
4
+ * PIN hashing is already aligned:
5
+ * Desktop: pbkdf2Sync(pin, salt, 100_000, 32, 'sha256')
6
+ * SDK: pbkdf2Sync(pin, salt, PIN_PBKDF2_ITERATIONS=100_000, 32, 'sha256')
7
+ *
8
+ * Session persistence (electron-store) lives in soostori-desktop/electron/auth/electron-store-session.ts,
9
+ * not here — this file is platform-agnostic.
10
+ */
11
+ import { hashPin, verifyPin } from '@soostori/auth/pin-node';
12
+ import { ROLE_PERMISSIONS, hasPermission } from '@soostori/auth';
13
+ export { hashPin, verifyPin, ROLE_PERMISSIONS, hasPermission };
14
+ //# sourceMappingURL=auth-pin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-pin.js","sourceRoot":"","sources":["../src/auth-pin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAGhE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,aAAa,EAAE,CAAA"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Business repository — maps Desktop shops table to canonical business types.
3
+ *
4
+ * Desktop schema: shops(id, name, currency, owner_id, created_at, slug, tax_rate, plan, subscription_expiry, status)
5
+ *
6
+ * The canonical Business type (from @soostori/core) is used directly here.
7
+ * This adapter is a Phase 9.1 scaffold — richer business/person/membership
8
+ * contracts from @soostori/business are deferred to Phase 9.2.
9
+ */
10
+ import type { UUID, ShopId } from '@soostori/core';
11
+ /** Canonical Shop type (aliased from core's expanded types). */
12
+ export interface DesktopShop {
13
+ id: ShopId;
14
+ name: string;
15
+ slug: string;
16
+ taxRate: number;
17
+ plan: string;
18
+ subscriptionExpiry: string | null;
19
+ status: 'active' | 'inactive' | 'suspended';
20
+ currency: string;
21
+ createdAt: string;
22
+ updatedAt: string;
23
+ ownerPersonId: UUID;
24
+ }
25
+ export declare class DesktopBusinessRepository {
26
+ findShop(id: UUID): Promise<DesktopShop | null>;
27
+ findAllShops(): Promise<DesktopShop[]>;
28
+ updateShop(id: UUID, changes: Partial<DesktopShop>): Promise<DesktopShop>;
29
+ getActiveShop(_deviceId: UUID): Promise<DesktopShop | null>;
30
+ }
31
+ //# sourceMappingURL=business-repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"business-repository.d.ts","sourceRoot":"","sources":["../src/business-repository.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAGlD,gEAAgE;AAChE,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,MAAM,EAAE,QAAQ,GAAG,UAAU,GAAG,WAAW,CAAA;IAC3C,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,IAAI,CAAA;CACpB;AAwBD,qBAAa,yBAAyB;IAC9B,QAAQ,CAAC,EAAE,EAAE,IAAI,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAK/C,YAAY,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAKtC,UAAU,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;IAgBzE,aAAa,CAAC,SAAS,EAAE,IAAI,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;CAIlE"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Business repository — maps Desktop shops table to canonical business types.
3
+ *
4
+ * Desktop schema: shops(id, name, currency, owner_id, created_at, slug, tax_rate, plan, subscription_expiry, status)
5
+ *
6
+ * The canonical Business type (from @soostori/core) is used directly here.
7
+ * This adapter is a Phase 9.1 scaffold — richer business/person/membership
8
+ * contracts from @soostori/business are deferred to Phase 9.2.
9
+ */
10
+ import { getDatabase } from './sqlite-database.js';
11
+ import { asShopId } from '@soostori/core';
12
+ function rowToShop(row) {
13
+ return {
14
+ id: asShopId(row.id),
15
+ name: row.name,
16
+ slug: row.slug ?? row.name.toLowerCase().replace(/\s+/g, '-'),
17
+ taxRate: row.tax_rate,
18
+ plan: row.plan,
19
+ subscriptionExpiry: row.subscription_expiry,
20
+ status: (row.status ?? 'active'),
21
+ currency: row.currency,
22
+ createdAt: row.created_at,
23
+ updatedAt: row.created_at,
24
+ ownerPersonId: (row.owner_id ?? row.id),
25
+ };
26
+ }
27
+ export class DesktopBusinessRepository {
28
+ async findShop(id) {
29
+ const row = getDatabase().prepare('SELECT * FROM shops WHERE id = ?').get(id);
30
+ return row ? rowToShop(row) : null;
31
+ }
32
+ async findAllShops() {
33
+ const rows = getDatabase().prepare('SELECT * FROM shops').all();
34
+ return rows.map(rowToShop);
35
+ }
36
+ async updateShop(id, changes) {
37
+ const db = getDatabase();
38
+ const map = {
39
+ name: 'name', slug: 'slug', taxRate: 'tax_rate',
40
+ plan: 'plan', subscriptionExpiry: 'subscription_expiry', status: 'status',
41
+ };
42
+ const sets = [];
43
+ const vals = [];
44
+ for (const [k, dbCol] of Object.entries(map)) {
45
+ const v = changes[k];
46
+ if (v !== undefined) {
47
+ sets.push(`${dbCol} = ?`);
48
+ vals.push(v);
49
+ }
50
+ }
51
+ if (sets.length > 0)
52
+ db.prepare(`UPDATE shops SET ${sets.join(', ')} WHERE id = ?`).run(...vals, id);
53
+ const row = db.prepare('SELECT * FROM shops WHERE id = ?').get(id);
54
+ return rowToShop(row);
55
+ }
56
+ async getActiveShop(_deviceId) {
57
+ const row = getDatabase().prepare('SELECT * FROM shops LIMIT 1').get();
58
+ return row ? rowToShop(row) : null;
59
+ }
60
+ }
61
+ //# sourceMappingURL=business-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"business-repository.js","sourceRoot":"","sources":["../src/business-repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Categories repository — implements @soostori/storage Repository<Category> over Desktop categories table.
3
+ *
4
+ * Desktop table: categories(id, name, description, icon, color, display_order, is_active, created_at, updated_at)
5
+ * SDK Category canonical shape: { id, shopId, name, color, description, isActive, createdAt, updatedAt }
6
+ *
7
+ * Desktop-only fields (not in SDK): icon, display_order — surfaced in metadata for round-trip fidelity.
8
+ */
9
+ import { SqliteRepository } from './sqlite-repository.js';
10
+ import type { Category } from '@soostori/core';
11
+ export declare class CategoriesRepository extends SqliteRepository<Category> {
12
+ protected tableName(): string;
13
+ findByName(name: string): Promise<Category | null>;
14
+ }
15
+ //# sourceMappingURL=categories-repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"categories-repository.d.ts","sourceRoot":"","sources":["../src/categories-repository.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,KAAK,EAAE,QAAQ,EAA+B,MAAM,gBAAgB,CAAA;AAsB3E,qBAAa,oBAAqB,SAAQ,gBAAgB,CAAC,QAAQ,CAAC;IAClE,SAAS,CAAC,SAAS,IAAI,MAAM;IAIvB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;CAOzD"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Categories repository — implements @soostori/storage Repository<Category> over Desktop categories table.
3
+ *
4
+ * Desktop table: categories(id, name, description, icon, color, display_order, is_active, created_at, updated_at)
5
+ * SDK Category canonical shape: { id, shopId, name, color, description, isActive, createdAt, updatedAt }
6
+ *
7
+ * Desktop-only fields (not in SDK): icon, display_order — surfaced in metadata for round-trip fidelity.
8
+ */
9
+ import { SqliteRepository } from './sqlite-repository.js';
10
+ import { asCategoryId } from '@soostori/core';
11
+ function rowToCategory(row) {
12
+ return {
13
+ id: asCategoryId(row.id),
14
+ shopId: null,
15
+ name: row.name,
16
+ color: row.color ?? '#6366f1',
17
+ description: row.description ?? null,
18
+ isActive: row.is_active === 1,
19
+ createdAt: row.created_at,
20
+ updatedAt: row.updated_at,
21
+ };
22
+ }
23
+ export class CategoriesRepository extends SqliteRepository {
24
+ tableName() {
25
+ return 'categories';
26
+ }
27
+ async findByName(name) {
28
+ const { getDatabase } = await import('./sqlite-database.js');
29
+ const row = getDatabase()
30
+ .prepare('SELECT * FROM categories WHERE name = ? COLLATE NOCASE')
31
+ .get(name);
32
+ return row ? rowToCategory(row) : null;
33
+ }
34
+ }
35
+ //# sourceMappingURL=categories-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"categories-repository.js","sourceRoot":"","sources":["../src/categories-repository.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAEzD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAQ7C,SAAS,aAAa,CAAC,GAAgB;IACrC,OAAO;QACL,EAAE,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,EAAE,IAAyB;QACjC,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,SAAS;QAC7B,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,IAAI;QACpC,QAAQ,EAAE,GAAG,CAAC,SAAS,KAAK,CAAC;QAC7B,SAAS,EAAE,GAAG,CAAC,UAAqB;QACpC,SAAS,EAAE,GAAG,CAAC,UAAqB;KACrC,CAAA;AACH,CAAC;AAED,MAAM,OAAO,oBAAqB,SAAQ,gBAA0B;IACxD,SAAS;QACjB,OAAO,YAAY,CAAA;IACrB,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,IAAY;QAC3B,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAA;QAC5D,MAAM,GAAG,GAAG,WAAW,EAAE;aACtB,OAAO,CAAC,wDAAwD,CAAC;aACjE,GAAG,CAAC,IAAI,CAA4B,CAAA;QACvC,OAAO,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACxC,CAAC;CACF"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Customers repository — implements @soostori/storage Repository<Customer> over Desktop customers table.
3
+ *
4
+ * Desktop table: customers(id, name, phone, email, address, notes, is_active, id_number, created_at, updated_at)
5
+ * SDK Customer canonical shape: { id, shopId, name, phone, email, idNumber, address, notes, isActive, createdAt, updatedAt }
6
+ *
7
+ * Note: Desktop customers table has no shop_id column. shopId is set to null in mapped entities.
8
+ * Soft-delete is used (is_active flag) rather than hard delete.
9
+ */
10
+ import type { Customer, CustomerId } from '@soostori/core';
11
+ export declare class CustomersRepository {
12
+ findById(id: CustomerId): Promise<Customer | null>;
13
+ findMany(filter?: {
14
+ isActive?: boolean;
15
+ }): Promise<Customer[]>;
16
+ create(data: Omit<Customer, 'shopId' | 'createdAt' | 'updatedAt'>): Promise<Customer>;
17
+ update(id: CustomerId, changes: Partial<Omit<Customer, 'id' | 'shopId' | 'createdAt' | 'updatedAt'>>): Promise<Customer>;
18
+ softDelete(id: CustomerId): Promise<void>;
19
+ }
20
+ //# sourceMappingURL=customers-repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"customers-repository.d.ts","sourceRoot":"","sources":["../src/customers-repository.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAmB,MAAM,gBAAgB,CAAA;AAyB3E,qBAAa,mBAAmB;IACxB,QAAQ,CAAC,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAOlD,QAAQ,CAAC,MAAM,GAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAOlE,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC;IAqBrF,MAAM,CAAC,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,GAAG,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC;IAiBxH,UAAU,CAAC,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAKhD"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Customers repository — implements @soostori/storage Repository<Customer> over Desktop customers table.
3
+ *
4
+ * Desktop table: customers(id, name, phone, email, address, notes, is_active, id_number, created_at, updated_at)
5
+ * SDK Customer canonical shape: { id, shopId, name, phone, email, idNumber, address, notes, isActive, createdAt, updatedAt }
6
+ *
7
+ * Note: Desktop customers table has no shop_id column. shopId is set to null in mapped entities.
8
+ * Soft-delete is used (is_active flag) rather than hard delete.
9
+ */
10
+ import { getDatabase } from './sqlite-database.js';
11
+ import { asCustomerId } from '@soostori/core';
12
+ function rowToCustomer(row) {
13
+ return {
14
+ id: asCustomerId(row.id),
15
+ shopId: null,
16
+ name: row.name,
17
+ phone: row.phone ?? null,
18
+ email: row.email ?? null,
19
+ idNumber: row.id_number ?? null,
20
+ address: row.address ?? null,
21
+ notes: row.notes ?? null,
22
+ isActive: row.is_active === 1,
23
+ createdAt: row.created_at,
24
+ updatedAt: row.updated_at,
25
+ };
26
+ }
27
+ export class CustomersRepository {
28
+ async findById(id) {
29
+ const row = getDatabase()
30
+ .prepare('SELECT * FROM customers WHERE id = ?')
31
+ .get(id);
32
+ return row ? rowToCustomer(row) : null;
33
+ }
34
+ async findMany(filter = {}) {
35
+ const rows = filter.isActive === false
36
+ ? getDatabase().prepare('SELECT * FROM customers WHERE is_active = 0').all()
37
+ : getDatabase().prepare('SELECT * FROM customers WHERE is_active = 1 ORDER BY name ASC').all();
38
+ return rows.map(rowToCustomer);
39
+ }
40
+ async create(data) {
41
+ const db = getDatabase();
42
+ const now = new Date().toISOString();
43
+ const id = data.id ?? asCustomerId(crypto.randomUUID());
44
+ db.prepare(`
45
+ INSERT INTO customers (id, name, phone, email, address, notes, id_number, is_active, created_at, updated_at)
46
+ VALUES (?, ?, ?, ?, ?, ?, ?, 1, ?, ?)
47
+ `).run(id, data.name, data.phone ?? null, data.email ?? null, data.address ?? null, data.notes ?? null, data.idNumber ?? null, now, now);
48
+ return (await this.findById(id));
49
+ }
50
+ async update(id, changes) {
51
+ const db = getDatabase();
52
+ const now = new Date().toISOString();
53
+ const fields = [];
54
+ const values = [];
55
+ if (changes.name !== undefined) {
56
+ fields.push('name = ?');
57
+ values.push(changes.name);
58
+ }
59
+ if (changes.phone !== undefined) {
60
+ fields.push('phone = ?');
61
+ values.push(changes.phone ?? null);
62
+ }
63
+ if (changes.email !== undefined) {
64
+ fields.push('email = ?');
65
+ values.push(changes.email ?? null);
66
+ }
67
+ if (changes.address !== undefined) {
68
+ fields.push('address = ?');
69
+ values.push(changes.address ?? null);
70
+ }
71
+ if (changes.notes !== undefined) {
72
+ fields.push('notes = ?');
73
+ values.push(changes.notes ?? null);
74
+ }
75
+ if (changes.idNumber !== undefined) {
76
+ fields.push('id_number = ?');
77
+ values.push(changes.idNumber ?? null);
78
+ }
79
+ if (changes.isActive !== undefined) {
80
+ fields.push('is_active = ?');
81
+ values.push(changes.isActive ? '1' : '0');
82
+ }
83
+ fields.push('updated_at = ?');
84
+ values.push(now);
85
+ values.push(id);
86
+ db.prepare(`UPDATE customers SET ${fields.join(', ')} WHERE id = ?`).run(...values);
87
+ return (await this.findById(id));
88
+ }
89
+ async softDelete(id) {
90
+ const db = getDatabase();
91
+ const now = new Date().toISOString();
92
+ db.prepare('UPDATE customers SET is_active = 0, updated_at = ? WHERE id = ?').run(now, id);
93
+ }
94
+ }
95
+ //# sourceMappingURL=customers-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"customers-repository.js","sourceRoot":"","sources":["../src/customers-repository.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAElD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAQ7C,SAAS,aAAa,CAAC,GAAgB;IACrC,OAAO;QACL,EAAE,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,EAAE,IAAyB;QACjC,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,IAAI;QACxB,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,IAAI;QACxB,QAAQ,EAAE,GAAG,CAAC,SAAS,IAAI,IAAI;QAC/B,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,IAAI;QAC5B,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,IAAI;QACxB,QAAQ,EAAE,GAAG,CAAC,SAAS,KAAK,CAAC;QAC7B,SAAS,EAAE,GAAG,CAAC,UAAqB;QACpC,SAAS,EAAE,GAAG,CAAC,UAAqB;KACrC,CAAA;AACH,CAAC;AAED,MAAM,OAAO,mBAAmB;IAC9B,KAAK,CAAC,QAAQ,CAAC,EAAc;QAC3B,MAAM,GAAG,GAAG,WAAW,EAAE;aACtB,OAAO,CAAC,sCAAsC,CAAC;aAC/C,GAAG,CAAC,EAAY,CAA4B,CAAA;QAC/C,OAAO,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACxC,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,SAAiC,EAAE;QAChD,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,KAAK,KAAK;YACpC,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,6CAA6C,CAAC,CAAC,GAAG,EAAmB;YAC7F,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,+DAA+D,CAAC,CAAC,GAAG,EAAmB,CAAA;QACjH,OAAO,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;IAChC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAA0D;QACrE,MAAM,EAAE,GAAG,WAAW,EAAE,CAAA;QACxB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;QACpC,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,IAAI,YAAY,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAA;QACvD,EAAE,CAAC,OAAO,CAAC;;;KAGV,CAAC,CAAC,GAAG,CACJ,EAAY,EACZ,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,KAAK,IAAI,IAAI,EAClB,IAAI,CAAC,KAAK,IAAI,IAAI,EAClB,IAAI,CAAC,OAAO,IAAI,IAAI,EACpB,IAAI,CAAC,KAAK,IAAI,IAAI,EAClB,IAAI,CAAC,QAAQ,IAAI,IAAI,EACrB,GAAG,EACH,GAAG,CACJ,CAAA;QACD,OAAO,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAE,CAAA;IACnC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAc,EAAE,OAA6E;QACxG,MAAM,EAAE,GAAG,WAAW,EAAE,CAAA;QACxB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;QACpC,MAAM,MAAM,GAAa,EAAE,CAAA;QAC3B,MAAM,MAAM,GAAsB,EAAE,CAAA;QACpC,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QAAC,CAAC;QACtF,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,CAAA;QAAC,CAAC;QACjG,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,CAAA;QAAC,CAAC;QACjG,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,CAAA;QAAC,CAAC;QACvG,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,CAAA;QAAC,CAAC;QACjG,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAA;QAAC,CAAC;QAC3G,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QAAC,CAAC;QAC/G,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAAC,MAAM,CAAC,IAAI,CAAC,EAAY,CAAC,CAAA;QAC1E,EAAE,CAAC,OAAO,CAAC,wBAAwB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAA;QACnF,OAAO,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAE,CAAA;IACnC,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,EAAc;QAC7B,MAAM,EAAE,GAAG,WAAW,EAAE,CAAA;QACxB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;QACpC,EAAE,CAAC,OAAO,CAAC,iEAAiE,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,EAAY,CAAC,CAAA;IACtG,CAAC;CACF"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Debts repository — implements debt management over Desktop debts + debt_payments tables.
3
+ * Desktop: debts(id, customer_id, sale_id, amount, amount_paid, status, due_date, notes, created_at, updated_at)
4
+ * debt_payments(id, debt_id, amount, payment_method, reference, notes, created_at)
5
+ */
6
+ import type { DebtId, DebtPaymentId, CustomerId, SaleId, ISO8601 } from '@soostori/core';
7
+ export type DebtStatus = 'pending' | 'partial' | 'paid';
8
+ export interface Debt {
9
+ id: DebtId;
10
+ customerId: CustomerId | null;
11
+ saleId: SaleId | null;
12
+ amount: number;
13
+ amountPaid: number;
14
+ status: DebtStatus;
15
+ dueDate: string | null;
16
+ notes: string | null;
17
+ createdAt: ISO8601;
18
+ updatedAt: ISO8601;
19
+ }
20
+ export interface DebtPayment {
21
+ id: DebtPaymentId;
22
+ debtId: DebtId;
23
+ amount: number;
24
+ paymentMethod: string;
25
+ reference: string | null;
26
+ notes: string | null;
27
+ createdAt: ISO8601;
28
+ }
29
+ export declare class DebtsRepository {
30
+ findById(id: DebtId): Promise<Debt | null>;
31
+ findMany(filter?: {
32
+ customerId?: string;
33
+ status?: DebtStatus;
34
+ }): Promise<Debt[]>;
35
+ createDebt(data: {
36
+ customerId?: string;
37
+ saleId?: string;
38
+ amount: number;
39
+ dueDate?: string;
40
+ notes?: string;
41
+ }): Promise<Debt>;
42
+ recordPayment(debtId: DebtId, amount: number, paymentMethod: string, reference?: string, notes?: string): Promise<{
43
+ debt: Debt;
44
+ payment: DebtPayment;
45
+ }>;
46
+ findPayments(debtId: DebtId): Promise<DebtPayment[]>;
47
+ }
48
+ //# sourceMappingURL=debts-repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debts-repository.d.ts","sourceRoot":"","sources":["../src/debts-repository.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAGxF,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAA;AACvD,MAAM,WAAW,IAAI;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE;AACxO,MAAM,WAAW,WAAW;IAAG,EAAE,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE;AAQ7K,qBAAa,eAAe;IACpB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAK1C,QAAQ,CAAC,MAAM,GAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,UAAU,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAWpF,UAAU,CAAC,IAAI,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ3H,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,OAAO,EAAE,WAAW,CAAA;KAAE,CAAC;IAevJ,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;CAG3D"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Debts repository — implements debt management over Desktop debts + debt_payments tables.
3
+ * Desktop: debts(id, customer_id, sale_id, amount, amount_paid, status, due_date, notes, created_at, updated_at)
4
+ * debt_payments(id, debt_id, amount, payment_method, reference, notes, created_at)
5
+ */
6
+ import { getDatabase } from './sqlite-database.js';
7
+ import { newId, asDebtId } from '@soostori/core';
8
+ const toDebt = (r) => ({ id: r.id, customerId: r.customer_id, saleId: r.sale_id, amount: r.amount, amountPaid: r.amount_paid, status: r.status, dueDate: r.due_date, notes: r.notes, createdAt: r.created_at, updatedAt: r.updated_at });
9
+ const toPayment = (r) => ({ id: r.id, debtId: r.debt_id, amount: r.amount, paymentMethod: r.payment_method, reference: r.reference, notes: r.notes, createdAt: r.created_at });
10
+ export class DebtsRepository {
11
+ async findById(id) {
12
+ const row = getDatabase().prepare('SELECT * FROM debts WHERE id = ?').get(id);
13
+ return row ? toDebt(row) : null;
14
+ }
15
+ async findMany(filter = {}) {
16
+ const db = getDatabase();
17
+ const conditions = [];
18
+ const values = [];
19
+ if (filter.customerId) {
20
+ conditions.push('customer_id = ?');
21
+ values.push(filter.customerId);
22
+ }
23
+ if (filter.status) {
24
+ conditions.push('status = ?');
25
+ values.push(filter.status);
26
+ }
27
+ const where = conditions.length > 0 ? ' WHERE ' + conditions.join(' AND ') : '';
28
+ const rows = (values.length ? db.prepare('SELECT * FROM debts' + where + ' ORDER BY created_at DESC').all(...values) : db.prepare('SELECT * FROM debts' + where + ' ORDER BY created_at DESC').all());
29
+ return rows.map(toDebt);
30
+ }
31
+ async createDebt(data) {
32
+ const db = getDatabase();
33
+ const now = new Date().toISOString();
34
+ const id = newId();
35
+ db.prepare(`INSERT INTO debts (id, customer_id, sale_id, amount, amount_paid, status, due_date, notes, created_at, updated_at) VALUES (?, ?, ?, ?, 0, 'pending', ?, ?, ?, ?)`).run(id, data.customerId ?? null, data.saleId ?? null, data.amount, data.dueDate ?? null, data.notes ?? null, now, now);
36
+ return (await this.findById(asDebtId(id)));
37
+ }
38
+ async recordPayment(debtId, amount, paymentMethod, reference, notes) {
39
+ const db = getDatabase();
40
+ const now = new Date().toISOString();
41
+ const debt = await this.findById(debtId);
42
+ if (!debt)
43
+ throw new Error('Debt not found');
44
+ const newPaid = debt.amountPaid + amount;
45
+ const newStatus = newPaid >= debt.amount ? 'paid' : 'partial';
46
+ db.prepare('UPDATE debts SET amount_paid = ?, status = ?, updated_at = ? WHERE id = ?').run(newPaid, newStatus, now, debtId);
47
+ const paymentId = asDebtId(newId());
48
+ db.prepare('INSERT INTO debt_payments (id, debt_id, amount, payment_method, reference, notes, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)').run(paymentId, debtId, amount, paymentMethod, reference ?? null, notes ?? null, now);
49
+ const updatedDebt = await this.findById(debtId);
50
+ const paymentRow = db.prepare('SELECT * FROM debt_payments WHERE id = ?').get(paymentId);
51
+ return { debt: updatedDebt, payment: toPayment(paymentRow) };
52
+ }
53
+ async findPayments(debtId) {
54
+ return getDatabase().prepare('SELECT * FROM debt_payments WHERE debt_id = ? ORDER BY created_at DESC').all(debtId).map(toPayment);
55
+ }
56
+ }
57
+ //# sourceMappingURL=debts-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debts-repository.js","sourceRoot":"","sources":["../src/debts-repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Device repository — implements @soostori/devices DevicesRepository over Desktop SQLite.
3
+ *
4
+ * Desktop schema: devices(id, shop_id, employee_id, device_name, device_type,
5
+ * capabilities, is_host, is_online, connection_token, last_seen, created_at,
6
+ * status, authorized_at, app_version, hostname, platform)
7
+ *
8
+ * SDK Device shape: { id, shopId, deviceName, deviceType, status, isLanHost,
9
+ * lastSeenAt, authorizedAt, activeEmployeeId, appVersion, hostname, platform }
10
+ *
11
+ * CONFLICT resolved by Phase 9.1.1 schema migration (adds missing columns).
12
+ * Desktop is_host (boolean) → SDK isLanHost (boolean): same semantics.
13
+ */
14
+ import type { DevicesRepository } from '@soostori/devices';
15
+ import type { Device, DeviceIdentity, PrimaryDeviceState } from '@soostori/devices';
16
+ import type { UUID, ShopId, ISO8601 } from '@soostori/core';
17
+ export declare class DesktopDevicesRepository implements DevicesRepository {
18
+ getLocalIdentity(): Promise<DeviceIdentity | null>;
19
+ saveLocalIdentity(_identity: DeviceIdentity): Promise<void>;
20
+ findDevice(id: UUID): Promise<Device | null>;
21
+ findByShop(shopId: ShopId): Promise<Device[]>;
22
+ registerDevice(device: Device): Promise<void>;
23
+ updateDevice(id: UUID, changes: Partial<Device>): Promise<Device>;
24
+ revokeDevice(id: UUID, _at: ISO8601): Promise<void>;
25
+ countActiveDevices(shopId: ShopId): Promise<number>;
26
+ getPrimaryState(_shopId: ShopId): Promise<PrimaryDeviceState | null>;
27
+ savePrimaryState(_shopId: ShopId, _state: PrimaryDeviceState): Promise<void>;
28
+ }
29
+ //# sourceMappingURL=devices-repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devices-repository.d.ts","sourceRoot":"","sources":["../src/devices-repository.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAC1D,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AACnF,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AA4B3D,qBAAa,wBAAyB,YAAW,iBAAiB;IAC1D,gBAAgB,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAKlD,iBAAiB,CAAC,SAAS,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3D,UAAU,CAAC,EAAE,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAK5C,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAO7C,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB7C,YAAY,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAmBjE,YAAY,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAInD,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAOnD,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAsBpE,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;CAGnF"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Device repository — implements @soostori/devices DevicesRepository over Desktop SQLite.
3
+ *
4
+ * Desktop schema: devices(id, shop_id, employee_id, device_name, device_type,
5
+ * capabilities, is_host, is_online, connection_token, last_seen, created_at,
6
+ * status, authorized_at, app_version, hostname, platform)
7
+ *
8
+ * SDK Device shape: { id, shopId, deviceName, deviceType, status, isLanHost,
9
+ * lastSeenAt, authorizedAt, activeEmployeeId, appVersion, hostname, platform }
10
+ *
11
+ * CONFLICT resolved by Phase 9.1.1 schema migration (adds missing columns).
12
+ * Desktop is_host (boolean) → SDK isLanHost (boolean): same semantics.
13
+ */
14
+ import { getDatabase } from './sqlite-database.js';
15
+ import { asDeviceId } from '@soostori/core';
16
+ function rowToDevice(row) {
17
+ return {
18
+ id: asDeviceId(row.id),
19
+ shopId: row.shop_id,
20
+ deviceName: row.device_name,
21
+ deviceType: row.device_type,
22
+ status: (row.status ?? 'offline'),
23
+ isLanHost: row.is_host === 1,
24
+ lastSeenAt: row.last_seen,
25
+ authorizedAt: row.authorized_at,
26
+ activeEmployeeId: row.employee_id,
27
+ appVersion: row.app_version ?? null,
28
+ hostname: row.hostname ?? null,
29
+ platform: row.platform ?? null,
30
+ };
31
+ }
32
+ export class DesktopDevicesRepository {
33
+ async getLocalIdentity() {
34
+ // Desktop stores identity in app_settings singleton.
35
+ return null;
36
+ }
37
+ async saveLocalIdentity(_identity) {
38
+ // Desktop uses app_settings singleton; handled by Electron main process
39
+ }
40
+ async findDevice(id) {
41
+ const row = getDatabase().prepare('SELECT * FROM devices WHERE id = ?').get(id);
42
+ return row ? rowToDevice(row) : null;
43
+ }
44
+ async findByShop(shopId) {
45
+ const rows = getDatabase().prepare('SELECT * FROM devices WHERE shop_id = ? ORDER BY created_at DESC').all(shopId);
46
+ return rows.map(rowToDevice);
47
+ }
48
+ async registerDevice(device) {
49
+ const db = getDatabase();
50
+ const existing = db.prepare('SELECT id FROM devices WHERE id = ?').get(device.id);
51
+ if (existing) {
52
+ db.prepare(`
53
+ UPDATE devices SET device_name = ?, device_type = ?, status = ?,
54
+ is_host = ?, last_seen = ? WHERE id = ?
55
+ `).run(device.deviceName, device.deviceType, device.status, device.isLanHost ? 1 : 0, device.lastSeenAt ?? new Date().toISOString(), device.id);
56
+ }
57
+ else {
58
+ db.prepare(`
59
+ INSERT INTO devices (id, shop_id, device_name, device_type, capabilities, is_host,
60
+ is_online, last_seen, status, authorized_at, created_at)
61
+ VALUES (?, ?, ?, ?, ?, ?, 1, ?, ?, ?, ?)
62
+ `).run(device.id, device.shopId, device.deviceName, device.deviceType, '{"sales":true,"inventory":true,"printing":true}', device.isLanHost ? 1 : 0, device.lastSeenAt ?? new Date().toISOString(), device.status, device.authorizedAt, new Date().toISOString());
63
+ }
64
+ }
65
+ async updateDevice(id, changes) {
66
+ const db = getDatabase();
67
+ const fieldMap = {
68
+ deviceName: 'device_name', deviceType: 'device_type', status: 'status',
69
+ isLanHost: 'is_host', lastSeenAt: 'last_seen', authorizedAt: 'authorized_at',
70
+ activeEmployeeId: 'employee_id', appVersion: 'app_version', hostname: 'hostname', platform: 'platform',
71
+ };
72
+ const sets = [];
73
+ const vals = [];
74
+ for (const [sdkKey, dbCol] of Object.entries(fieldMap)) {
75
+ const v = changes[sdkKey];
76
+ if (v !== undefined) {
77
+ sets.push(`${dbCol} = ?`);
78
+ vals.push(v);
79
+ }
80
+ }
81
+ if (sets.length > 0) {
82
+ db.prepare(`UPDATE devices SET ${sets.join(', ')} WHERE id = ?`).run(...vals, id);
83
+ }
84
+ const row = db.prepare('SELECT * FROM devices WHERE id = ?').get(id);
85
+ return rowToDevice(row);
86
+ }
87
+ async revokeDevice(id, _at) {
88
+ getDatabase().prepare("UPDATE devices SET status = 'revoked' WHERE id = ?").run(id);
89
+ }
90
+ async countActiveDevices(shopId) {
91
+ const row = getDatabase().prepare("SELECT COUNT(*) as count FROM devices WHERE shop_id = ? AND status != 'revoked'").get(shopId);
92
+ return row.count;
93
+ }
94
+ async getPrimaryState(_shopId) {
95
+ const db = getDatabase();
96
+ const primary = db.prepare('SELECT id, last_seen FROM devices WHERE is_host = 1 LIMIT 1').get();
97
+ if (!primary)
98
+ return null;
99
+ const now = Date.now();
100
+ const lastSeen = primary.last_seen ? new Date(primary.last_seen).getTime() : 0;
101
+ const stalenessMs = now - lastSeen;
102
+ let status = 'online';
103
+ if (stalenessMs > 60_000)
104
+ status = 'lost';
105
+ else if (stalenessMs > 15_000)
106
+ status = 'stale';
107
+ return {
108
+ primaryId: asDeviceId(primary.id),
109
+ electedAt: null,
110
+ lastHeartbeatAt: primary.last_seen,
111
+ stalenessMs,
112
+ status,
113
+ electionPending: false,
114
+ };
115
+ }
116
+ async savePrimaryState(_shopId, _state) {
117
+ // Desktop: primary state is derived from is_host column. No separate storage needed.
118
+ }
119
+ }
120
+ //# sourceMappingURL=devices-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devices-repository.js","sourceRoot":"","sources":["../src/devices-repository.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAIlD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAU3C,SAAS,WAAW,CAAC,GAAc;IACjC,OAAO;QACL,EAAE,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,EAAE,GAAG,CAAC,OAAiB;QAC7B,UAAU,EAAE,GAAG,CAAC,WAAW;QAC3B,UAAU,EAAE,GAAG,CAAC,WAAmC;QACnD,MAAM,EAAE,CAAC,GAAG,CAAC,MAAM,IAAI,SAAS,CAAqB;QACrD,SAAS,EAAE,GAAG,CAAC,OAAO,KAAK,CAAC;QAC5B,UAAU,EAAE,GAAG,CAAC,SAA2B;QAC3C,YAAY,EAAE,GAAG,CAAC,aAA+B;QACjD,gBAAgB,EAAE,GAAG,CAAC,WAAyC;QAC/D,UAAU,EAAE,GAAG,CAAC,WAAW,IAAI,IAAI;QACnC,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,IAAI;QAC9B,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,IAAI;KAC/B,CAAA;AACH,CAAC;AAED,MAAM,OAAO,wBAAwB;IACnC,KAAK,CAAC,gBAAgB;QACpB,qDAAqD;QACrD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,SAAyB;QAC/C,wEAAwE;IAC1E,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,EAAQ;QACvB,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC,GAAG,CAAC,EAAE,CAA0B,CAAA;QACxG,OAAO,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACtC,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,MAAc;QAC7B,MAAM,IAAI,GAAG,WAAW,EAAE,CAAC,OAAO,CAChC,kEAAkE,CACnE,CAAC,GAAG,CAAC,MAAM,CAAgB,CAAA;QAC5B,OAAO,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;IAC9B,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,MAAc;QACjC,MAAM,EAAE,GAAG,WAAW,EAAE,CAAA;QACxB,MAAM,QAAQ,GAAG,EAAE,CAAC,OAAO,CAAC,qCAAqC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QACjF,IAAI,QAAQ,EAAE,CAAC;YACb,EAAE,CAAC,OAAO,CAAC;;;OAGV,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EACxD,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,UAAU,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,CAAA;QACvF,CAAC;aAAM,CAAC;YACN,EAAE,CAAC,OAAO,CAAC;;;;OAIV,CAAC,CAAC,GAAG,CACJ,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,EAC9D,iDAAiD,EACjD,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACxB,MAAM,CAAC,UAAU,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAC7C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAC7D,CAAA;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,EAAQ,EAAE,OAAwB;QACnD,MAAM,EAAE,GAAG,WAAW,EAAE,CAAA;QACxB,MAAM,QAAQ,GAA2B;YACvC,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ;YACtE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe;YAC5E,gBAAgB,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU;SACvG,CAAA;QACD,MAAM,IAAI,GAAa,EAAE,CAAC;QAAC,MAAM,IAAI,GAAc,EAAE,CAAA;QACrD,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvD,MAAM,CAAC,GAAG,OAAO,CAAC,MAAsB,CAAC,CAAA;YACzC,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;gBAAC,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC;gBAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YAAC,CAAC;QAClE,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,EAAE,CAAC,OAAO,CAAC,sBAAsB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,CAAA;QACnF,CAAC;QACD,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAc,CAAA;QACjF,OAAO,WAAW,CAAC,GAAG,CAAC,CAAA;IACzB,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,EAAQ,EAAE,GAAY;QACvC,WAAW,EAAE,CAAC,OAAO,CAAC,oDAAoD,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACrF,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,MAAc;QACrC,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC,OAAO,CAC/B,iFAAiF,CAClF,CAAC,GAAG,CAAC,MAAM,CAAsB,CAAA;QAClC,OAAO,GAAG,CAAC,KAAK,CAAA;IAClB,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,OAAe;QACnC,MAAM,EAAE,GAAG,WAAW,EAAE,CAAA;QACxB,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,CACxB,6DAA6D,CAC9D,CAAC,GAAG,EAA0D,CAAA;QAC/D,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAA;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;QAC9E,MAAM,WAAW,GAAG,GAAG,GAAG,QAAQ,CAAA;QAClC,IAAI,MAAM,GAAiC,QAAQ,CAAA;QACnD,IAAI,WAAW,GAAG,MAAM;YAAE,MAAM,GAAG,MAAM,CAAA;aACpC,IAAI,WAAW,GAAG,MAAM;YAAE,MAAM,GAAG,OAAO,CAAA;QAC/C,OAAO;YACL,SAAS,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACjC,SAAS,EAAE,IAAI;YACf,eAAe,EAAE,OAAO,CAAC,SAA2B;YACpD,WAAW;YACX,MAAM;YACN,eAAe,EAAE,KAAK;SACvB,CAAA;IACH,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,OAAe,EAAE,MAA0B;QAChE,qFAAqF;IACvF,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Domain repositories index — exports all domain repositories for Phase 9.2 wiring.
3
+ *
4
+ * These repositories expose Desktop's existing SQLite tables through the canonical
5
+ * SDK Repository<T> interface. No existing IPC handlers or table schemas are modified.
6
+ */
7
+ export { ProductsRepository } from './products-repository.js';
8
+ export { CategoriesRepository } from './categories-repository.js';
9
+ export { CustomersRepository } from './customers-repository.js';
10
+ export { DesktopSalesRepository, type PaymentMethod } from './sales-repository.js';
11
+ export { DebtsRepository } from './debts-repository.js';
12
+ //# sourceMappingURL=domain-repositories.d.ts.map