@rubydogjp/openkk-sqlite-adapter 26.2.0

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 (82) hide show
  1. package/LICENSE +21 -0
  2. package/dist/adapter.d.ts +4 -0
  3. package/dist/adapter.d.ts.map +1 -0
  4. package/dist/adapter.js +21 -0
  5. package/dist/adapter.js.map +1 -0
  6. package/dist/closing-store.d.ts +5 -0
  7. package/dist/closing-store.d.ts.map +1 -0
  8. package/dist/closing-store.js +113 -0
  9. package/dist/closing-store.js.map +1 -0
  10. package/dist/entry-store.d.ts +6 -0
  11. package/dist/entry-store.d.ts.map +1 -0
  12. package/dist/entry-store.js +266 -0
  13. package/dist/entry-store.js.map +1 -0
  14. package/dist/fiscal-period-guard.d.ts +6 -0
  15. package/dist/fiscal-period-guard.d.ts.map +1 -0
  16. package/dist/fiscal-period-guard.js +34 -0
  17. package/dist/fiscal-period-guard.js.map +1 -0
  18. package/dist/fiscal-period-record.d.ts +5 -0
  19. package/dist/fiscal-period-record.d.ts.map +1 -0
  20. package/dist/fiscal-period-record.js +32 -0
  21. package/dist/fiscal-period-record.js.map +1 -0
  22. package/dist/fiscal-period-store.d.ts +4 -0
  23. package/dist/fiscal-period-store.d.ts.map +1 -0
  24. package/dist/fiscal-period-store.js +364 -0
  25. package/dist/fiscal-period-store.js.map +1 -0
  26. package/dist/fiscal-period-transition.d.ts +4 -0
  27. package/dist/fiscal-period-transition.d.ts.map +1 -0
  28. package/dist/fiscal-period-transition.js +30 -0
  29. package/dist/fiscal-period-transition.js.map +1 -0
  30. package/dist/fixed-asset-store.d.ts +4 -0
  31. package/dist/fixed-asset-store.d.ts.map +1 -0
  32. package/dist/fixed-asset-store.js +142 -0
  33. package/dist/fixed-asset-store.js.map +1 -0
  34. package/dist/index.d.ts +5 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +4 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/master-data-store.d.ts +3 -0
  39. package/dist/master-data-store.d.ts.map +1 -0
  40. package/dist/master-data-store.js +39 -0
  41. package/dist/master-data-store.js.map +1 -0
  42. package/dist/migrate.d.ts +6 -0
  43. package/dist/migrate.d.ts.map +1 -0
  44. package/dist/migrate.js +53 -0
  45. package/dist/migrate.js.map +1 -0
  46. package/dist/opening-store.d.ts +7 -0
  47. package/dist/opening-store.d.ts.map +1 -0
  48. package/dist/opening-store.js +150 -0
  49. package/dist/opening-store.js.map +1 -0
  50. package/dist/persistence-codec.d.ts +9 -0
  51. package/dist/persistence-codec.d.ts.map +1 -0
  52. package/dist/persistence-codec.js +210 -0
  53. package/dist/persistence-codec.js.map +1 -0
  54. package/dist/record-validation.d.ts +11 -0
  55. package/dist/record-validation.d.ts.map +1 -0
  56. package/dist/record-validation.js +75 -0
  57. package/dist/record-validation.js.map +1 -0
  58. package/dist/runtime.d.ts +3 -0
  59. package/dist/runtime.d.ts.map +1 -0
  60. package/dist/runtime.js +7 -0
  61. package/dist/runtime.js.map +1 -0
  62. package/dist/schema.d.ts +7 -0
  63. package/dist/schema.d.ts.map +1 -0
  64. package/dist/schema.js +688 -0
  65. package/dist/schema.js.map +1 -0
  66. package/dist/seed-store.d.ts +4 -0
  67. package/dist/seed-store.d.ts.map +1 -0
  68. package/dist/seed-store.js +174 -0
  69. package/dist/seed-store.js.map +1 -0
  70. package/dist/sql-db.d.ts +9 -0
  71. package/dist/sql-db.d.ts.map +1 -0
  72. package/dist/sql-db.js +2 -0
  73. package/dist/sql-db.js.map +1 -0
  74. package/dist/table-types.d.ts +27 -0
  75. package/dist/table-types.d.ts.map +1 -0
  76. package/dist/table-types.js +2 -0
  77. package/dist/table-types.js.map +1 -0
  78. package/dist/transaction.d.ts +4 -0
  79. package/dist/transaction.d.ts.map +1 -0
  80. package/dist/transaction.js +21 -0
  81. package/dist/transaction.js.map +1 -0
  82. package/package.json +42 -0
@@ -0,0 +1,7 @@
1
+ export type SchemaMigration = {
2
+ version: number;
3
+ sql: string;
4
+ };
5
+ export declare const SCHEMA_MIGRATIONS: SchemaMigration[];
6
+ export declare const SCHEMA_VERSION: number;
7
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AA8qBF,eAAO,MAAM,iBAAiB,EAAE,eAAe,EAK9C,CAAC;AAEF,eAAO,MAAM,cAAc,QAC+B,CAAC"}
package/dist/schema.js ADDED
@@ -0,0 +1,688 @@
1
+ const MIGRATION_V1 = {
2
+ version: 1,
3
+ sql: `
4
+ CREATE TABLE openkk_meta (
5
+ key TEXT PRIMARY KEY,
6
+ value TEXT NOT NULL
7
+ );
8
+
9
+ CREATE TABLE fiscal_periods (
10
+ id TEXT PRIMARY KEY,
11
+ user_id TEXT NOT NULL,
12
+ data TEXT NOT NULL,
13
+ created_at INTEGER NOT NULL,
14
+ updated_at INTEGER NOT NULL
15
+ );
16
+ CREATE INDEX idx_fiscal_periods_user_id ON fiscal_periods(user_id);
17
+
18
+ CREATE TABLE entries (
19
+ id TEXT PRIMARY KEY,
20
+ fiscal_period_id TEXT NOT NULL,
21
+ date TEXT NOT NULL,
22
+ data TEXT NOT NULL,
23
+ created_at INTEGER NOT NULL,
24
+ updated_at INTEGER NOT NULL
25
+ );
26
+ CREATE INDEX idx_entries_fiscal_period_id ON entries(fiscal_period_id);
27
+ CREATE INDEX idx_entries_fp_date ON entries(fiscal_period_id, date);
28
+
29
+ CREATE TABLE fixed_assets (
30
+ id TEXT PRIMARY KEY,
31
+ fiscal_period_id TEXT NOT NULL,
32
+ data TEXT NOT NULL,
33
+ created_at INTEGER NOT NULL,
34
+ updated_at INTEGER NOT NULL
35
+ );
36
+ CREATE INDEX idx_fixed_assets_fiscal_period_id ON fixed_assets(fiscal_period_id);
37
+
38
+ CREATE TABLE closings (
39
+ fiscal_period_id TEXT NOT NULL,
40
+ year INTEGER NOT NULL,
41
+ is_provisional INTEGER NOT NULL,
42
+ PRIMARY KEY (fiscal_period_id, year)
43
+ );
44
+ `.trim(),
45
+ };
46
+ const MIGRATION_V2 = {
47
+ version: 2,
48
+ sql: `
49
+ CREATE TEMP TABLE openkk_migration_guard (
50
+ value INTEGER NOT NULL CHECK (value = 0)
51
+ );
52
+ INSERT INTO openkk_migration_guard(value)
53
+ SELECT COUNT(*) FROM entries e
54
+ LEFT JOIN fiscal_periods fp ON fp.id = e.fiscal_period_id
55
+ WHERE fp.id IS NULL;
56
+ DELETE FROM openkk_migration_guard;
57
+ INSERT INTO openkk_migration_guard(value)
58
+ SELECT COUNT(*) FROM fixed_assets fa
59
+ LEFT JOIN fiscal_periods fp ON fp.id = fa.fiscal_period_id
60
+ WHERE fp.id IS NULL;
61
+ DELETE FROM openkk_migration_guard;
62
+ INSERT INTO openkk_migration_guard(value)
63
+ SELECT COUNT(*) FROM closings c
64
+ LEFT JOIN fiscal_periods fp ON fp.id = c.fiscal_period_id
65
+ WHERE fp.id IS NULL;
66
+ DROP TABLE openkk_migration_guard;
67
+
68
+ CREATE TEMP TABLE openkk_legacy_openings AS
69
+ SELECT
70
+ id AS fiscal_period_id,
71
+ CASE
72
+ WHEN json_type(data, '$.opening') = 'object'
73
+ THEN json_extract(data, '$.opening')
74
+ ELSE '{}'
75
+ END AS data,
76
+ created_at,
77
+ updated_at
78
+ FROM fiscal_periods;
79
+
80
+ CREATE TABLE fiscal_periods_v2 (
81
+ id TEXT PRIMARY KEY,
82
+ user_id TEXT NOT NULL,
83
+ data TEXT NOT NULL CHECK (
84
+ json_valid(data)
85
+ AND json_type(data, '$.id') IS 'text'
86
+ AND json_extract(data, '$.id') = id
87
+ AND json_type(data, '$.name') IS 'text'
88
+ AND json_type(data, '$.startDate') IS 'text'
89
+ AND json_type(data, '$.endDate') IS 'text'
90
+ AND json_type(data, '$.phase') IS 'text'
91
+ AND json_extract(data, '$.phase') IN ('pre_opening', 'journalizing', 'pre_closing', 'post_closing')
92
+ AND json_type(data, '$.archiveStatus') IS 'text'
93
+ AND json_extract(data, '$.archiveStatus') IN ('active', 'archived')
94
+ AND (json_type(data, '$.settingsCompleted') IS 'true' OR json_type(data, '$.settingsCompleted') IS 'false')
95
+ AND (json_type(data, '$.openingBalancesCompleted') IS 'true' OR json_type(data, '$.openingBalancesCompleted') IS 'false')
96
+ AND (json_type(data, '$.documentsReceivedCompleted') IS 'true' OR json_type(data, '$.documentsReceivedCompleted') IS 'false')
97
+ AND json_type(data, '$.opening') IS NULL
98
+ ),
99
+ created_at INTEGER NOT NULL,
100
+ updated_at INTEGER NOT NULL
101
+ );
102
+ INSERT INTO fiscal_periods_v2(id, user_id, data, created_at, updated_at)
103
+ SELECT
104
+ id,
105
+ user_id,
106
+ json_set(
107
+ json_remove(data, '$.opening', '$.stage', '$.archived'),
108
+ '$.phase', CASE
109
+ WHEN EXISTS (
110
+ SELECT 1 FROM closings c
111
+ WHERE c.fiscal_period_id = fiscal_periods.id AND c.is_provisional = 0
112
+ ) THEN 'post_closing'
113
+ WHEN EXISTS (
114
+ SELECT 1 FROM closings c
115
+ WHERE c.fiscal_period_id = fiscal_periods.id AND c.is_provisional = 1
116
+ ) THEN 'pre_closing'
117
+ WHEN json_extract(data, '$.stage') = 'post_closing' THEN 'post_closing'
118
+ WHEN json_extract(data, '$.stage') = 'journalizing' THEN 'journalizing'
119
+ ELSE 'pre_opening'
120
+ END,
121
+ '$.archiveStatus', CASE
122
+ WHEN json_extract(data, '$.archived') = 1 THEN 'archived'
123
+ ELSE 'active'
124
+ END
125
+ ),
126
+ created_at,
127
+ updated_at
128
+ FROM fiscal_periods;
129
+ DROP TABLE fiscal_periods;
130
+ ALTER TABLE fiscal_periods_v2 RENAME TO fiscal_periods;
131
+ CREATE INDEX idx_fiscal_periods_user_created_id
132
+ ON fiscal_periods(user_id, created_at, id);
133
+
134
+ CREATE TABLE openings (
135
+ id TEXT PRIMARY KEY,
136
+ fiscal_period_id TEXT NOT NULL UNIQUE REFERENCES fiscal_periods(id) ON DELETE CASCADE,
137
+ created_at INTEGER NOT NULL,
138
+ updated_at INTEGER NOT NULL
139
+ );
140
+
141
+ CREATE TABLE opening_balance_lines (
142
+ opening_id TEXT NOT NULL REFERENCES openings(id) ON DELETE CASCADE,
143
+ id TEXT NOT NULL,
144
+ account_id TEXT NOT NULL,
145
+ amount REAL NOT NULL CHECK (amount >= 0),
146
+ position INTEGER NOT NULL CHECK (position >= 0),
147
+ PRIMARY KEY (opening_id, id),
148
+ UNIQUE (opening_id, account_id)
149
+ );
150
+ CREATE INDEX idx_opening_balance_lines_order
151
+ ON opening_balance_lines(opening_id, position, id);
152
+
153
+ CREATE TABLE opening_journals (
154
+ opening_id TEXT NOT NULL REFERENCES openings(id) ON DELETE CASCADE,
155
+ id TEXT NOT NULL,
156
+ date TEXT NOT NULL CHECK (date = date(date)),
157
+ description TEXT NOT NULL,
158
+ business_rate REAL NOT NULL CHECK (business_rate BETWEEN 0 AND 1),
159
+ position INTEGER NOT NULL CHECK (position >= 0),
160
+ PRIMARY KEY (opening_id, id)
161
+ );
162
+ CREATE INDEX idx_opening_journals_order
163
+ ON opening_journals(opening_id, position, id);
164
+
165
+ CREATE TABLE opening_journal_lines (
166
+ opening_id TEXT NOT NULL,
167
+ opening_journal_id TEXT NOT NULL,
168
+ id TEXT NOT NULL,
169
+ side TEXT NOT NULL CHECK (side IN ('debit', 'credit')),
170
+ book_account_id TEXT NOT NULL,
171
+ amount REAL NOT NULL CHECK (amount >= 0),
172
+ partner_name TEXT NOT NULL,
173
+ tax_category_id TEXT NOT NULL,
174
+ business_category_id TEXT NOT NULL,
175
+ position INTEGER NOT NULL CHECK (position >= 0),
176
+ PRIMARY KEY (opening_id, opening_journal_id, id),
177
+ FOREIGN KEY (opening_id, opening_journal_id)
178
+ REFERENCES opening_journals(opening_id, id) ON DELETE CASCADE
179
+ );
180
+ CREATE INDEX idx_opening_journal_lines_order
181
+ ON opening_journal_lines(opening_id, opening_journal_id, position, id);
182
+
183
+ INSERT INTO openings(id, fiscal_period_id, created_at, updated_at)
184
+ SELECT
185
+ COALESCE(json_extract(data, '$.id'), 'op-' || fiscal_period_id),
186
+ fiscal_period_id,
187
+ created_at,
188
+ updated_at
189
+ FROM openkk_legacy_openings;
190
+
191
+ INSERT INTO opening_balance_lines(opening_id, id, account_id, amount, position)
192
+ SELECT
193
+ o.id,
194
+ json_extract(line.value, '$.id'),
195
+ json_extract(line.value, '$.accountId'),
196
+ json_extract(line.value, '$.amount'),
197
+ CAST(line.key AS INTEGER)
198
+ FROM openkk_legacy_openings legacy
199
+ JOIN openings o ON o.fiscal_period_id = legacy.fiscal_period_id
200
+ JOIN json_each(legacy.data, '$.openingBalanceLines') line
201
+ WHERE json_type(legacy.data, '$.openingBalanceLines') = 'array';
202
+
203
+ INSERT INTO opening_journals(opening_id, id, date, description, business_rate, position)
204
+ SELECT
205
+ o.id,
206
+ json_extract(journal.value, '$.id'),
207
+ json_extract(journal.value, '$.date'),
208
+ json_extract(journal.value, '$.description'),
209
+ json_extract(journal.value, '$.businessRate'),
210
+ CAST(journal.key AS INTEGER)
211
+ FROM openkk_legacy_openings legacy
212
+ JOIN openings o ON o.fiscal_period_id = legacy.fiscal_period_id
213
+ JOIN json_each(legacy.data, '$.carryoverJournals') journal
214
+ WHERE json_type(legacy.data, '$.carryoverJournals') = 'array';
215
+
216
+ INSERT INTO opening_journal_lines(
217
+ opening_id, opening_journal_id, id, side, book_account_id, amount,
218
+ partner_name, tax_category_id, business_category_id, position
219
+ )
220
+ SELECT
221
+ o.id,
222
+ json_extract(journal.value, '$.id'),
223
+ json_extract(line.value, '$.id'),
224
+ json_extract(line.value, '$.side'),
225
+ json_extract(line.value, '$.bookAccountId'),
226
+ json_extract(line.value, '$.amount'),
227
+ COALESCE(json_extract(line.value, '$.partnerName'), ''),
228
+ COALESCE(json_extract(line.value, '$.taxCategoryName'), ''),
229
+ COALESCE(json_extract(line.value, '$.businessCategoryName'), ''),
230
+ CAST(line.key AS INTEGER)
231
+ FROM openkk_legacy_openings legacy
232
+ JOIN openings o ON o.fiscal_period_id = legacy.fiscal_period_id
233
+ JOIN json_each(legacy.data, '$.carryoverJournals') journal
234
+ JOIN json_each(journal.value, '$.lines') line
235
+ WHERE json_type(legacy.data, '$.carryoverJournals') = 'array';
236
+
237
+ DROP TABLE openkk_legacy_openings;
238
+
239
+ CREATE TEMP TABLE openkk_legacy_entry_lines AS
240
+ SELECT
241
+ e.id AS entry_id,
242
+ json_extract(line.value, '$.side') AS side,
243
+ json_extract(line.value, '$.bookAccountId') AS book_account_id,
244
+ json_extract(line.value, '$.amount') AS amount,
245
+ COALESCE(json_extract(line.value, '$.partnerName'), '') AS partner_name,
246
+ COALESCE(json_extract(line.value, '$.taxCategoryName'), '') AS tax_category_id,
247
+ COALESCE(json_extract(line.value, '$.businessCategoryName'), '') AS business_category_id,
248
+ CAST(line.key AS INTEGER) AS position
249
+ FROM entries e
250
+ JOIN json_each(e.data, '$.lines') line
251
+ WHERE json_type(e.data, '$.lines') = 'array';
252
+
253
+ CREATE TABLE entries_v2 (
254
+ id TEXT PRIMARY KEY,
255
+ fiscal_period_id TEXT NOT NULL REFERENCES fiscal_periods(id) ON DELETE CASCADE,
256
+ date TEXT NOT NULL CHECK (date = date(date)),
257
+ local_id TEXT NOT NULL,
258
+ description TEXT NOT NULL,
259
+ business_rate REAL NOT NULL CHECK (business_rate BETWEEN 0 AND 1),
260
+ created_at INTEGER NOT NULL,
261
+ updated_at INTEGER NOT NULL
262
+ );
263
+ INSERT INTO entries_v2(
264
+ id, fiscal_period_id, date, local_id, description, business_rate, created_at, updated_at
265
+ )
266
+ SELECT
267
+ id,
268
+ fiscal_period_id,
269
+ date,
270
+ COALESCE(json_extract(data, '$.localId'), ''),
271
+ json_extract(data, '$.description'),
272
+ json_extract(data, '$.businessRate'),
273
+ created_at,
274
+ updated_at
275
+ FROM entries;
276
+ DROP TABLE entries;
277
+ ALTER TABLE entries_v2 RENAME TO entries;
278
+ CREATE INDEX idx_entries_fp_date_created_id
279
+ ON entries(fiscal_period_id, date, created_at, id);
280
+ CREATE UNIQUE INDEX idx_entries_fp_local_id
281
+ ON entries(fiscal_period_id, local_id) WHERE local_id <> '';
282
+
283
+ CREATE TABLE entry_lines (
284
+ entry_id TEXT NOT NULL REFERENCES entries(id) ON DELETE CASCADE,
285
+ side TEXT NOT NULL CHECK (side IN ('debit', 'credit')),
286
+ book_account_id TEXT NOT NULL,
287
+ amount REAL NOT NULL CHECK (amount >= 0),
288
+ partner_name TEXT NOT NULL,
289
+ tax_category_id TEXT NOT NULL,
290
+ business_category_id TEXT NOT NULL,
291
+ position INTEGER NOT NULL CHECK (position >= 0),
292
+ PRIMARY KEY (entry_id, position)
293
+ );
294
+ INSERT INTO entry_lines(
295
+ entry_id, side, book_account_id, amount, partner_name,
296
+ tax_category_id, business_category_id, position
297
+ )
298
+ SELECT
299
+ entry_id, side, book_account_id, amount, partner_name,
300
+ tax_category_id, business_category_id, position
301
+ FROM openkk_legacy_entry_lines;
302
+ DROP TABLE openkk_legacy_entry_lines;
303
+
304
+ CREATE TABLE fixed_assets_v2 (
305
+ id TEXT PRIMARY KEY,
306
+ fiscal_period_id TEXT NOT NULL REFERENCES fiscal_periods(id) ON DELETE CASCADE,
307
+ data TEXT NOT NULL CHECK (
308
+ json_valid(data)
309
+ AND json_type(data, '$.id') IS 'text'
310
+ AND json_extract(data, '$.id') = id
311
+ AND json_type(data, '$.fiscalPeriodId') IS 'text'
312
+ AND json_extract(data, '$.fiscalPeriodId') = fiscal_period_id
313
+ AND json_type(data, '$.name') IS 'text'
314
+ AND json_type(data, '$.acquisitionDate') IS 'text'
315
+ AND (json_type(data, '$.acquisitionCost') IS 'integer' OR json_type(data, '$.acquisitionCost') IS 'real')
316
+ AND json_type(data, '$.usefulLife') IS 'integer'
317
+ AND json_type(data, '$.depreciationMethod') IS 'text'
318
+ AND json_extract(data, '$.depreciationMethod') = 'straight_line'
319
+ AND (json_type(data, '$.businessRate') IS 'integer' OR json_type(data, '$.businessRate') IS 'real')
320
+ AND json_type(data, '$.status') IS 'text'
321
+ AND json_extract(data, '$.status') IN ('active', 'sold', 'disposed', 'retired')
322
+ AND json_type(data, '$.disposalDate') IS 'text'
323
+ AND (json_type(data, '$.disposalPrice') IS 'integer' OR json_type(data, '$.disposalPrice') IS 'real')
324
+ AND json_type(data, '$.bookAccountId') IS 'text'
325
+ ),
326
+ created_at INTEGER NOT NULL,
327
+ updated_at INTEGER NOT NULL
328
+ );
329
+ INSERT INTO fixed_assets_v2 SELECT * FROM fixed_assets;
330
+ DROP TABLE fixed_assets;
331
+ ALTER TABLE fixed_assets_v2 RENAME TO fixed_assets;
332
+ CREATE INDEX idx_fixed_assets_fp_created_id
333
+ ON fixed_assets(fiscal_period_id, created_at, id);
334
+
335
+ CREATE TABLE pre_closings (
336
+ fiscal_period_id TEXT NOT NULL REFERENCES fiscal_periods(id) ON DELETE CASCADE,
337
+ year INTEGER NOT NULL CHECK (year BETWEEN 1 AND 9999),
338
+ PRIMARY KEY (fiscal_period_id, year)
339
+ );
340
+ INSERT INTO pre_closings(fiscal_period_id, year)
341
+ SELECT fiscal_period_id, year FROM closings WHERE is_provisional = 1;
342
+
343
+ CREATE TABLE closings_v2 (
344
+ fiscal_period_id TEXT NOT NULL REFERENCES fiscal_periods(id) ON DELETE CASCADE,
345
+ year INTEGER NOT NULL CHECK (year BETWEEN 1 AND 9999),
346
+ PRIMARY KEY (fiscal_period_id, year)
347
+ );
348
+ INSERT INTO closings_v2(fiscal_period_id, year)
349
+ SELECT fiscal_period_id, year FROM closings WHERE is_provisional = 0;
350
+ DROP TABLE closings;
351
+ ALTER TABLE closings_v2 RENAME TO closings;
352
+ `.trim(),
353
+ };
354
+ const MIGRATION_V3 = {
355
+ version: 3,
356
+ sql: `
357
+ CREATE TABLE entry_lines_v3 (
358
+ entry_id TEXT NOT NULL REFERENCES entries(id) ON DELETE CASCADE,
359
+ id TEXT NOT NULL,
360
+ side TEXT NOT NULL CHECK (side IN ('debit', 'credit')),
361
+ book_account_id TEXT NOT NULL,
362
+ amount REAL NOT NULL CHECK (amount >= 0),
363
+ partner_name TEXT NOT NULL,
364
+ tax_category_id TEXT NOT NULL,
365
+ business_category_id TEXT NOT NULL,
366
+ position INTEGER NOT NULL CHECK (position >= 0),
367
+ PRIMARY KEY (entry_id, position)
368
+ );
369
+ INSERT INTO entry_lines_v3(
370
+ entry_id, id, side, book_account_id, amount, partner_name,
371
+ tax_category_id, business_category_id, position
372
+ )
373
+ SELECT
374
+ entry_id,
375
+ entry_id || '-line-' || position,
376
+ side, book_account_id, amount, partner_name,
377
+ tax_category_id, business_category_id, position
378
+ FROM entry_lines;
379
+ DROP TABLE entry_lines;
380
+ ALTER TABLE entry_lines_v3 RENAME TO entry_lines;
381
+ `.trim(),
382
+ };
383
+ const MIGRATION_V4 = {
384
+ version: 4,
385
+ sql: `
386
+ CREATE TEMP TABLE openkk_v4_tax_category_ids (name TEXT PRIMARY KEY, id TEXT NOT NULL);
387
+ INSERT INTO openkk_v4_tax_category_ids(name, id) VALUES
388
+ ('課税 10%', 'tax_10'),
389
+ ('軽減税率 8%', 'tax_8'),
390
+ ('免税', 'tax_exempt'),
391
+ ('非課税', 'tax_non_taxable'),
392
+ ('対象外', 'tax_out_of_scope');
393
+
394
+ CREATE TEMP TABLE openkk_v4_business_category_ids (name TEXT PRIMARY KEY, id TEXT NOT NULL);
395
+ INSERT INTO openkk_v4_business_category_ids(name, id) VALUES
396
+ ('第1種(卸売業)', 'biz_1'),
397
+ ('第2種(小売業等)', 'biz_2'),
398
+ ('第3種(製造業等)', 'biz_3'),
399
+ ('第4種(その他)', 'biz_4'),
400
+ ('第5種(サービス業等)', 'biz_5'),
401
+ ('第6種(不動産業)', 'biz_6'),
402
+ ('対象外', 'biz_none');
403
+
404
+ CREATE TEMP TABLE openkk_v4_fiscal_periods AS SELECT * FROM fiscal_periods;
405
+ CREATE TEMP TABLE openkk_v4_opening_balance_lines AS
406
+ SELECT o.fiscal_period_id, line.id, line.account_id, line.amount, line.position
407
+ FROM opening_balance_lines line
408
+ JOIN openings o ON o.id = line.opening_id;
409
+ CREATE TEMP TABLE openkk_v4_opening_journals AS
410
+ SELECT o.fiscal_period_id, journal.id, journal.date, journal.description,
411
+ journal.business_rate, journal.position
412
+ FROM opening_journals journal
413
+ JOIN openings o ON o.id = journal.opening_id;
414
+ CREATE TEMP TABLE openkk_v4_opening_journal_lines AS
415
+ SELECT o.fiscal_period_id, line.opening_journal_id, line.id, line.side,
416
+ line.book_account_id, line.amount, line.partner_name, line.tax_category_id,
417
+ line.business_category_id, line.position
418
+ FROM opening_journal_lines line
419
+ JOIN openings o ON o.id = line.opening_id;
420
+ CREATE TEMP TABLE openkk_v4_entries AS SELECT * FROM entries;
421
+ CREATE TEMP TABLE openkk_v4_entry_lines AS SELECT * FROM entry_lines;
422
+ CREATE TEMP TABLE openkk_v4_fixed_assets AS SELECT * FROM fixed_assets;
423
+ CREATE TEMP TABLE openkk_v4_pre_closings AS SELECT * FROM pre_closings;
424
+ CREATE TEMP TABLE openkk_v4_closings AS SELECT * FROM closings;
425
+
426
+ DROP TABLE opening_journal_lines;
427
+ DROP TABLE opening_journals;
428
+ DROP TABLE opening_balance_lines;
429
+ DROP TABLE openings;
430
+ DROP TABLE entry_lines;
431
+ DROP TABLE entries;
432
+ DROP TABLE fixed_assets;
433
+ DROP TABLE pre_closings;
434
+ DROP TABLE closings;
435
+ DROP TABLE fiscal_periods;
436
+
437
+ CREATE TABLE fiscal_periods (
438
+ id TEXT PRIMARY KEY,
439
+ user_id TEXT NOT NULL,
440
+ data TEXT NOT NULL CHECK (
441
+ json_valid(data)
442
+ AND json_type(data, '$.id') IS 'text'
443
+ AND json_extract(data, '$.id') = id
444
+ AND json_type(data, '$.name') IS 'text'
445
+ AND json_type(data, '$.startDate') IS 'text'
446
+ AND json_type(data, '$.endDate') IS 'text'
447
+ AND json_type(data, '$.phase') IS 'text'
448
+ AND json_extract(data, '$.phase') IN ('pre_opening', 'journalizing', 'pre_closing', 'post_closing')
449
+ AND json_type(data, '$.archiveStatus') IS 'text'
450
+ AND json_extract(data, '$.archiveStatus') IN ('active', 'archived', 'purged')
451
+ AND (json_type(data, '$.archivedAt') IS 'text' OR json_type(data, '$.archivedAt') IS 'null')
452
+ AND (json_type(data, '$.openingBalancesCompleted') IS 'true' OR json_type(data, '$.openingBalancesCompleted') IS 'false')
453
+ AND (json_type(data, '$.documentsReceivedCompleted') IS 'true' OR json_type(data, '$.documentsReceivedCompleted') IS 'false')
454
+ ),
455
+ created_at INTEGER NOT NULL,
456
+ updated_at INTEGER NOT NULL
457
+ );
458
+ CREATE INDEX idx_fiscal_periods_user_created_id
459
+ ON fiscal_periods(user_id, created_at, id);
460
+
461
+ CREATE TABLE opening_balance_lines (
462
+ fiscal_period_id TEXT NOT NULL REFERENCES fiscal_periods(id) ON DELETE CASCADE,
463
+ id TEXT NOT NULL,
464
+ account_id TEXT NOT NULL,
465
+ amount REAL NOT NULL CHECK (amount >= 0),
466
+ position INTEGER NOT NULL CHECK (position >= 0),
467
+ PRIMARY KEY (fiscal_period_id, id),
468
+ UNIQUE (fiscal_period_id, account_id)
469
+ );
470
+ CREATE INDEX idx_opening_balance_lines_order
471
+ ON opening_balance_lines(fiscal_period_id, position, id);
472
+
473
+ CREATE TABLE opening_journals (
474
+ fiscal_period_id TEXT NOT NULL REFERENCES fiscal_periods(id) ON DELETE CASCADE,
475
+ id TEXT NOT NULL,
476
+ date TEXT NOT NULL CHECK (date = date(date)),
477
+ description TEXT NOT NULL,
478
+ business_rate REAL NOT NULL CHECK (business_rate BETWEEN 0 AND 1),
479
+ position INTEGER NOT NULL CHECK (position >= 0),
480
+ PRIMARY KEY (fiscal_period_id, id)
481
+ );
482
+ CREATE INDEX idx_opening_journals_order
483
+ ON opening_journals(fiscal_period_id, position, id);
484
+
485
+ CREATE TABLE opening_journal_lines (
486
+ fiscal_period_id TEXT NOT NULL,
487
+ opening_journal_id TEXT NOT NULL,
488
+ id TEXT NOT NULL,
489
+ side TEXT NOT NULL CHECK (side IN ('debit', 'credit')),
490
+ book_account_id TEXT NOT NULL,
491
+ amount REAL NOT NULL CHECK (amount >= 0),
492
+ partner_name TEXT NOT NULL,
493
+ tax_category_id TEXT NOT NULL,
494
+ business_category_id TEXT NOT NULL,
495
+ position INTEGER NOT NULL CHECK (position >= 0),
496
+ PRIMARY KEY (fiscal_period_id, opening_journal_id, id),
497
+ FOREIGN KEY (fiscal_period_id, opening_journal_id)
498
+ REFERENCES opening_journals(fiscal_period_id, id) ON DELETE CASCADE
499
+ );
500
+ CREATE INDEX idx_opening_journal_lines_order
501
+ ON opening_journal_lines(fiscal_period_id, opening_journal_id, position, id);
502
+
503
+ CREATE TABLE entries (
504
+ id TEXT PRIMARY KEY,
505
+ fiscal_period_id TEXT NOT NULL REFERENCES fiscal_periods(id) ON DELETE CASCADE,
506
+ date TEXT NOT NULL CHECK (date = date(date)),
507
+ local_id TEXT CHECK (local_id IS NULL OR length(trim(local_id)) > 0),
508
+ description TEXT NOT NULL,
509
+ business_rate REAL NOT NULL CHECK (business_rate BETWEEN 0 AND 1),
510
+ created_at INTEGER NOT NULL,
511
+ updated_at INTEGER NOT NULL
512
+ );
513
+ CREATE INDEX idx_entries_fp_date_created_id
514
+ ON entries(fiscal_period_id, date, created_at, id);
515
+ CREATE UNIQUE INDEX idx_entries_fp_local_id
516
+ ON entries(fiscal_period_id, local_id) WHERE local_id IS NOT NULL;
517
+
518
+ CREATE TABLE entry_lines (
519
+ entry_id TEXT NOT NULL REFERENCES entries(id) ON DELETE CASCADE,
520
+ id TEXT NOT NULL,
521
+ side TEXT NOT NULL CHECK (side IN ('debit', 'credit')),
522
+ book_account_id TEXT NOT NULL,
523
+ amount REAL NOT NULL CHECK (amount >= 0),
524
+ partner_name TEXT NOT NULL,
525
+ tax_category_id TEXT NOT NULL,
526
+ business_category_id TEXT NOT NULL,
527
+ position INTEGER NOT NULL CHECK (position >= 0),
528
+ PRIMARY KEY (entry_id, position)
529
+ );
530
+
531
+ CREATE TABLE fixed_assets (
532
+ id TEXT PRIMARY KEY,
533
+ fiscal_period_id TEXT NOT NULL REFERENCES fiscal_periods(id) ON DELETE CASCADE,
534
+ data TEXT NOT NULL CHECK (
535
+ json_valid(data)
536
+ AND json_type(data, '$.id') IS 'text'
537
+ AND json_extract(data, '$.id') = id
538
+ AND json_type(data, '$.fiscalPeriodId') IS 'text'
539
+ AND json_extract(data, '$.fiscalPeriodId') = fiscal_period_id
540
+ AND json_type(data, '$.name') IS 'text'
541
+ AND json_type(data, '$.acquisitionDate') IS 'text'
542
+ AND (json_type(data, '$.acquisitionCost') IS 'integer' OR json_type(data, '$.acquisitionCost') IS 'real')
543
+ AND json_type(data, '$.usefulLife') IS 'integer'
544
+ AND json_type(data, '$.depreciationMethod') IS 'text'
545
+ AND json_extract(data, '$.depreciationMethod') = 'straight_line'
546
+ AND (json_type(data, '$.businessRate') IS 'integer' OR json_type(data, '$.businessRate') IS 'real')
547
+ AND json_type(data, '$.status') IS 'text'
548
+ AND json_extract(data, '$.status') IN ('active', 'sold', 'disposed', 'retired')
549
+ AND json_type(data, '$.bookAccountId') IS 'text'
550
+ AND (
551
+ (json_extract(data, '$.status') = 'sold'
552
+ AND json_type(data, '$.disposalDate') IS 'text'
553
+ AND (json_type(data, '$.disposalPrice') IS 'integer' OR json_type(data, '$.disposalPrice') IS 'real'))
554
+ OR (json_extract(data, '$.status') = 'disposed'
555
+ AND json_type(data, '$.disposalDate') IS 'text'
556
+ AND json_type(data, '$.disposalPrice') IS 'null')
557
+ OR (json_extract(data, '$.status') IN ('active', 'retired')
558
+ AND json_type(data, '$.disposalDate') IS 'null'
559
+ AND json_type(data, '$.disposalPrice') IS 'null')
560
+ )
561
+ ),
562
+ created_at INTEGER NOT NULL,
563
+ updated_at INTEGER NOT NULL
564
+ );
565
+ CREATE INDEX idx_fixed_assets_fp_created_id
566
+ ON fixed_assets(fiscal_period_id, created_at, id);
567
+
568
+ CREATE TABLE pre_closings (
569
+ fiscal_period_id TEXT NOT NULL REFERENCES fiscal_periods(id) ON DELETE CASCADE,
570
+ year INTEGER NOT NULL CHECK (year BETWEEN 1 AND 9999),
571
+ PRIMARY KEY (fiscal_period_id, year)
572
+ );
573
+
574
+ CREATE TABLE closings (
575
+ fiscal_period_id TEXT NOT NULL REFERENCES fiscal_periods(id) ON DELETE CASCADE,
576
+ year INTEGER NOT NULL CHECK (year BETWEEN 1 AND 9999),
577
+ PRIMARY KEY (fiscal_period_id, year)
578
+ );
579
+
580
+ INSERT INTO fiscal_periods(id, user_id, data, created_at, updated_at)
581
+ SELECT
582
+ id,
583
+ user_id,
584
+ json_set(
585
+ json_remove(data, '$.archiveDataAvailable', '$.settingsCompleted'),
586
+ '$.phase', CASE
587
+ WHEN json_extract(data, '$.phase') = 'pre_opening'
588
+ AND json_extract(data, '$.settingsCompleted') = 1
589
+ THEN 'journalizing'
590
+ ELSE json_extract(data, '$.phase')
591
+ END,
592
+ '$.archiveStatus', CASE
593
+ WHEN json_extract(data, '$.archiveDataAvailable') = 0 THEN 'purged'
594
+ ELSE json_extract(data, '$.archiveStatus')
595
+ END,
596
+ '$.archivedAt', json_extract(data, '$.archivedAt')
597
+ ),
598
+ created_at,
599
+ updated_at
600
+ FROM openkk_v4_fiscal_periods;
601
+
602
+ INSERT INTO opening_balance_lines(fiscal_period_id, id, account_id, amount, position)
603
+ SELECT fiscal_period_id, id, account_id, amount, position
604
+ FROM openkk_v4_opening_balance_lines;
605
+
606
+ INSERT INTO opening_journals(fiscal_period_id, id, date, description, business_rate, position)
607
+ SELECT fiscal_period_id, id, date, description, business_rate, position
608
+ FROM openkk_v4_opening_journals;
609
+
610
+ INSERT INTO opening_journal_lines(
611
+ fiscal_period_id, opening_journal_id, id, side, book_account_id, amount,
612
+ partner_name, tax_category_id, business_category_id, position
613
+ )
614
+ SELECT
615
+ line.fiscal_period_id, line.opening_journal_id, line.id, line.side,
616
+ line.book_account_id, line.amount, line.partner_name,
617
+ COALESCE(tax.id, line.tax_category_id),
618
+ COALESCE(business.id, line.business_category_id),
619
+ line.position
620
+ FROM openkk_v4_opening_journal_lines line
621
+ LEFT JOIN openkk_v4_tax_category_ids tax ON tax.name = line.tax_category_id
622
+ LEFT JOIN openkk_v4_business_category_ids business ON business.name = line.business_category_id;
623
+
624
+ INSERT INTO entries(
625
+ id, fiscal_period_id, date, local_id, description, business_rate, created_at, updated_at
626
+ )
627
+ SELECT
628
+ id,
629
+ fiscal_period_id,
630
+ date,
631
+ CASE WHEN trim(local_id) = '' THEN NULL ELSE local_id END,
632
+ description,
633
+ business_rate,
634
+ created_at,
635
+ updated_at
636
+ FROM openkk_v4_entries;
637
+
638
+ INSERT INTO entry_lines(
639
+ entry_id, id, side, book_account_id, amount, partner_name,
640
+ tax_category_id, business_category_id, position
641
+ )
642
+ SELECT
643
+ line.entry_id, line.id, line.side, line.book_account_id, line.amount,
644
+ line.partner_name,
645
+ COALESCE(tax.id, line.tax_category_id),
646
+ COALESCE(business.id, line.business_category_id),
647
+ line.position
648
+ FROM openkk_v4_entry_lines line
649
+ LEFT JOIN openkk_v4_tax_category_ids tax ON tax.name = line.tax_category_id
650
+ LEFT JOIN openkk_v4_business_category_ids business ON business.name = line.business_category_id;
651
+
652
+ INSERT INTO fixed_assets(id, fiscal_period_id, data, created_at, updated_at)
653
+ SELECT id, fiscal_period_id,
654
+ CASE json_extract(data, '$.status')
655
+ WHEN 'sold' THEN data
656
+ WHEN 'disposed' THEN json_set(data, '$.disposalPrice', NULL)
657
+ ELSE json_set(data, '$.disposalDate', NULL, '$.disposalPrice', NULL)
658
+ END,
659
+ created_at, updated_at
660
+ FROM openkk_v4_fixed_assets;
661
+
662
+ INSERT INTO pre_closings(fiscal_period_id, year)
663
+ SELECT fiscal_period_id, year FROM openkk_v4_pre_closings;
664
+
665
+ INSERT INTO closings(fiscal_period_id, year)
666
+ SELECT fiscal_period_id, year FROM openkk_v4_closings;
667
+
668
+ DROP TABLE openkk_v4_closings;
669
+ DROP TABLE openkk_v4_pre_closings;
670
+ DROP TABLE openkk_v4_fixed_assets;
671
+ DROP TABLE openkk_v4_entry_lines;
672
+ DROP TABLE openkk_v4_entries;
673
+ DROP TABLE openkk_v4_opening_journal_lines;
674
+ DROP TABLE openkk_v4_opening_journals;
675
+ DROP TABLE openkk_v4_opening_balance_lines;
676
+ DROP TABLE openkk_v4_fiscal_periods;
677
+ DROP TABLE openkk_v4_business_category_ids;
678
+ DROP TABLE openkk_v4_tax_category_ids;
679
+ `.trim(),
680
+ };
681
+ export const SCHEMA_MIGRATIONS = [
682
+ MIGRATION_V1,
683
+ MIGRATION_V2,
684
+ MIGRATION_V3,
685
+ MIGRATION_V4,
686
+ ];
687
+ export const SCHEMA_VERSION = SCHEMA_MIGRATIONS[SCHEMA_MIGRATIONS.length - 1].version;
688
+ //# sourceMappingURL=schema.js.map