@stonyx/orm 0.2.1-beta.9 → 0.2.1-beta.90

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 (171) hide show
  1. package/README.md +64 -6
  2. package/config/environment.js +37 -1
  3. package/dist/aggregates.d.ts +21 -0
  4. package/dist/aggregates.js +93 -0
  5. package/dist/attr.d.ts +2 -0
  6. package/dist/attr.js +22 -0
  7. package/dist/belongs-to.d.ts +11 -0
  8. package/dist/belongs-to.js +59 -0
  9. package/dist/cli.d.ts +22 -0
  10. package/dist/cli.js +148 -0
  11. package/dist/commands.d.ts +7 -0
  12. package/dist/commands.js +146 -0
  13. package/dist/db.d.ts +21 -0
  14. package/dist/db.js +180 -0
  15. package/dist/exports/db.d.ts +7 -0
  16. package/{src → dist}/exports/db.js +2 -4
  17. package/dist/has-many.d.ts +11 -0
  18. package/dist/has-many.js +58 -0
  19. package/dist/hooks.d.ts +62 -0
  20. package/dist/hooks.js +110 -0
  21. package/dist/index.d.ts +14 -0
  22. package/dist/index.js +34 -0
  23. package/dist/main.d.ts +46 -0
  24. package/dist/main.js +181 -0
  25. package/dist/manage-record.d.ts +13 -0
  26. package/dist/manage-record.js +123 -0
  27. package/dist/meta-request.d.ts +6 -0
  28. package/dist/meta-request.js +52 -0
  29. package/dist/migrate.d.ts +2 -0
  30. package/dist/migrate.js +57 -0
  31. package/dist/model-property.d.ts +9 -0
  32. package/dist/model-property.js +29 -0
  33. package/dist/model.d.ts +15 -0
  34. package/dist/model.js +18 -0
  35. package/dist/mysql/connection.d.ts +14 -0
  36. package/dist/mysql/connection.js +24 -0
  37. package/dist/mysql/migration-generator.d.ts +45 -0
  38. package/dist/mysql/migration-generator.js +254 -0
  39. package/dist/mysql/migration-runner.d.ts +12 -0
  40. package/dist/mysql/migration-runner.js +88 -0
  41. package/dist/mysql/mysql-db.d.ts +100 -0
  42. package/dist/mysql/mysql-db.js +425 -0
  43. package/dist/mysql/query-builder.d.ts +10 -0
  44. package/dist/mysql/query-builder.js +44 -0
  45. package/dist/mysql/schema-introspector.d.ts +19 -0
  46. package/dist/mysql/schema-introspector.js +291 -0
  47. package/dist/mysql/type-map.d.ts +21 -0
  48. package/dist/mysql/type-map.js +36 -0
  49. package/dist/orm-request.d.ts +38 -0
  50. package/dist/orm-request.js +474 -0
  51. package/dist/plural-registry.d.ts +4 -0
  52. package/dist/plural-registry.js +9 -0
  53. package/dist/postgres/connection.d.ts +15 -0
  54. package/dist/postgres/connection.js +32 -0
  55. package/dist/postgres/migration-generator.d.ts +45 -0
  56. package/dist/postgres/migration-generator.js +261 -0
  57. package/dist/postgres/migration-runner.d.ts +10 -0
  58. package/dist/postgres/migration-runner.js +87 -0
  59. package/dist/postgres/postgres-db.d.ts +119 -0
  60. package/dist/postgres/postgres-db.js +477 -0
  61. package/dist/postgres/query-builder.d.ts +27 -0
  62. package/dist/postgres/query-builder.js +98 -0
  63. package/dist/postgres/schema-introspector.d.ts +29 -0
  64. package/dist/postgres/schema-introspector.js +314 -0
  65. package/dist/postgres/type-map.d.ts +23 -0
  66. package/dist/postgres/type-map.js +56 -0
  67. package/dist/record.d.ts +75 -0
  68. package/dist/record.js +129 -0
  69. package/dist/relationships.d.ts +10 -0
  70. package/dist/relationships.js +41 -0
  71. package/dist/serializer.d.ts +17 -0
  72. package/dist/serializer.js +136 -0
  73. package/dist/setup-rest-server.d.ts +1 -0
  74. package/dist/setup-rest-server.js +52 -0
  75. package/dist/standalone-db.d.ts +58 -0
  76. package/dist/standalone-db.js +142 -0
  77. package/dist/store.d.ts +62 -0
  78. package/dist/store.js +286 -0
  79. package/dist/timescale/query-builder.d.ts +43 -0
  80. package/dist/timescale/query-builder.js +115 -0
  81. package/dist/timescale/timescale-db.d.ts +45 -0
  82. package/dist/timescale/timescale-db.js +84 -0
  83. package/dist/transforms.d.ts +2 -0
  84. package/dist/transforms.js +17 -0
  85. package/dist/types/orm-types.d.ts +142 -0
  86. package/dist/types/orm-types.js +1 -0
  87. package/dist/utils.d.ts +7 -0
  88. package/dist/utils.js +17 -0
  89. package/dist/view-resolver.d.ts +8 -0
  90. package/dist/view-resolver.js +171 -0
  91. package/dist/view.d.ts +11 -0
  92. package/dist/view.js +18 -0
  93. package/package.json +57 -15
  94. package/src/aggregates.ts +109 -0
  95. package/src/{attr.js → attr.ts} +2 -2
  96. package/src/belongs-to.ts +90 -0
  97. package/src/cli.ts +183 -0
  98. package/src/{commands.js → commands.ts} +179 -170
  99. package/src/{db.js → db.ts} +55 -29
  100. package/src/exports/db.ts +7 -0
  101. package/src/has-many.ts +92 -0
  102. package/src/{hooks.js → hooks.ts} +41 -27
  103. package/src/{index.js → index.ts} +11 -2
  104. package/src/main.ts +229 -0
  105. package/src/manage-record.ts +161 -0
  106. package/src/{meta-request.js → meta-request.ts} +17 -14
  107. package/src/{migrate.js → migrate.ts} +9 -9
  108. package/src/model-property.ts +35 -0
  109. package/src/model.ts +21 -0
  110. package/src/mysql/{connection.js → connection.ts} +43 -28
  111. package/src/mysql/migration-generator.ts +337 -0
  112. package/src/mysql/{migration-runner.js → migration-runner.ts} +121 -110
  113. package/src/mysql/mysql-db.ts +543 -0
  114. package/src/mysql/{query-builder.js → query-builder.ts} +69 -64
  115. package/src/mysql/schema-introspector.ts +358 -0
  116. package/src/mysql/{type-map.js → type-map.ts} +42 -37
  117. package/src/{orm-request.js → orm-request.ts} +186 -108
  118. package/src/plural-registry.ts +12 -0
  119. package/src/postgres/connection.ts +48 -0
  120. package/src/postgres/migration-generator.ts +348 -0
  121. package/src/postgres/migration-runner.ts +115 -0
  122. package/src/postgres/postgres-db.ts +616 -0
  123. package/src/postgres/query-builder.ts +148 -0
  124. package/src/postgres/schema-introspector.ts +386 -0
  125. package/src/postgres/type-map.ts +61 -0
  126. package/src/record.ts +186 -0
  127. package/src/relationships.ts +54 -0
  128. package/src/serializer.ts +161 -0
  129. package/src/{setup-rest-server.js → setup-rest-server.ts} +18 -16
  130. package/src/standalone-db.ts +185 -0
  131. package/src/store.ts +373 -0
  132. package/src/timescale/query-builder.ts +174 -0
  133. package/src/timescale/timescale-db.ts +119 -0
  134. package/src/transforms.ts +20 -0
  135. package/src/types/mysql2.d.ts +49 -0
  136. package/src/types/orm-types.ts +146 -0
  137. package/src/types/pg.d.ts +32 -0
  138. package/src/types/stonyx-cron.d.ts +5 -0
  139. package/src/types/stonyx-events.d.ts +4 -0
  140. package/src/types/stonyx-rest-server.d.ts +16 -0
  141. package/src/types/stonyx-utils.d.ts +33 -0
  142. package/src/types/stonyx.d.ts +21 -0
  143. package/src/utils.ts +22 -0
  144. package/src/view-resolver.ts +211 -0
  145. package/src/view.ts +22 -0
  146. package/.claude/code-style-rules.md +0 -44
  147. package/.claude/hooks.md +0 -250
  148. package/.claude/index.md +0 -279
  149. package/.claude/usage-patterns.md +0 -217
  150. package/.github/workflows/ci.yml +0 -16
  151. package/.github/workflows/publish.yml +0 -51
  152. package/improvements.md +0 -139
  153. package/project-structure.md +0 -343
  154. package/src/belongs-to.js +0 -63
  155. package/src/has-many.js +0 -61
  156. package/src/main.js +0 -148
  157. package/src/manage-record.js +0 -118
  158. package/src/model-property.js +0 -29
  159. package/src/model.js +0 -9
  160. package/src/mysql/migration-generator.js +0 -188
  161. package/src/mysql/mysql-db.js +0 -320
  162. package/src/mysql/schema-introspector.js +0 -158
  163. package/src/record.js +0 -127
  164. package/src/relationships.js +0 -43
  165. package/src/serializer.js +0 -138
  166. package/src/store.js +0 -211
  167. package/src/transforms.js +0 -20
  168. package/src/utils.js +0 -12
  169. package/test-events-setup.js +0 -41
  170. package/test-hooks-manual.js +0 -54
  171. package/test-hooks-with-logging.js +0 -52
@@ -1,217 +0,0 @@
1
- # Usage Patterns
2
-
3
- ## 1. Model Definition
4
-
5
- Models extend `Model` and use decorators for attributes and relationships:
6
-
7
- ```javascript
8
- // test/sample/models/animal.js
9
- import { Model, attr, belongsTo, hasMany } from '@stonyx/orm';
10
-
11
- export default class AnimalModel extends Model {
12
- // Attributes with type transforms
13
- type = attr('animal'); // Custom transform
14
- age = attr('number'); // Built-in transform
15
- size = attr('string');
16
-
17
- // Relationships
18
- owner = belongsTo('owner'); // Many-to-one
19
- traits = hasMany('trait'); // One-to-many
20
-
21
- // Computed properties
22
- get tag() {
23
- return `${this.owner.id}'s ${this.size} animal`;
24
- }
25
- }
26
- ```
27
-
28
- **Key Points:**
29
- - Use `attr(type)` for simple attributes
30
- - Use `belongsTo(modelName)` for many-to-one
31
- - Use `hasMany(modelName)` for one-to-many
32
- - Getters work as computed properties
33
- - Relationships auto-establish bidirectionally
34
-
35
- ## 2. Serializers (Data Transformation)
36
-
37
- Serializers map raw data paths to model properties:
38
-
39
- ```javascript
40
- // test/sample/serializers/animal.js
41
- import { Serializer } from '@stonyx/orm';
42
-
43
- export default class AnimalSerializer extends Serializer {
44
- map = {
45
- // Nested path mapping
46
- age: 'details.age',
47
- size: 'details.c',
48
- owner: 'details.location.owner',
49
-
50
- // Custom transformation function
51
- traits: ['details', ({ x:color }) => {
52
- const traits = [{ id: 1, type: 'habitat', value: 'farm' }];
53
- if (color) traits.push({ id: 2, type: 'color', value: color });
54
- return traits;
55
- }]
56
- }
57
- }
58
- ```
59
-
60
- **Key Points:**
61
- - `map` object defines field mappings
62
- - Supports nested paths (`'details.age'`)
63
- - Custom functions for complex transformations
64
- - Handlers receive raw data subset
65
-
66
- ## 3. Custom Transforms
67
-
68
- Transforms convert data types:
69
-
70
- ```javascript
71
- // test/sample/transforms/animal.js
72
- const codeEnumMap = { 'dog': 1, 'cat': 2, 'bird': 3 };
73
-
74
- export default function(value) {
75
- return codeEnumMap[value] || 0;
76
- }
77
- ```
78
-
79
- **Built-in Transforms:**
80
- - Type: `boolean`, `number`, `float`, `string`, `date`, `timestamp`
81
- - Math: `round`, `ceil`, `floor`
82
- - String: `trim`, `uppercase`
83
- - Utility: `passthrough`
84
-
85
- ## 4. CRUD Operations
86
-
87
- ```javascript
88
- import { createRecord, updateRecord, store } from '@stonyx/orm';
89
-
90
- // Create
91
- createRecord('owner', { id: 'bob', age: 30 });
92
-
93
- // Read
94
- const owner = store.get('owner', 'bob');
95
- const allOwners = store.get('owner');
96
-
97
- // Update
98
- updateRecord(owner, { age: 31 });
99
- // Or direct: owner.age = 31;
100
-
101
- // Delete
102
- store.remove('owner', 'bob');
103
- ```
104
-
105
- ## 5. Database Schema
106
-
107
- The DB schema is a Model defining top-level collections:
108
-
109
- ```javascript
110
- // test/sample/db-schema.js
111
- import { Model, hasMany } from '@stonyx/orm';
112
-
113
- export default class DBModel extends Model {
114
- owners = hasMany('owner');
115
- animals = hasMany('animal');
116
- traits = hasMany('trait');
117
- }
118
- ```
119
-
120
- ## 6. Persistence
121
-
122
- ```javascript
123
- import Orm from '@stonyx/orm';
124
-
125
- // Save to file
126
- await Orm.db.save();
127
-
128
- // Data auto-serializes to JSON file
129
- // Reload using createRecord with serialize:false, transform:false
130
- ```
131
-
132
- ## 7. Access Control
133
-
134
- ```javascript
135
- // test/sample/access/global-access.js
136
- export default class GlobalAccess {
137
- models = ['owner', 'animal']; // or '*' for all
138
-
139
- access(request) {
140
- // Deny specific access
141
- if (request.url.endsWith('/owner/angela')) return false;
142
-
143
- // Filter collections
144
- if (request.url.endsWith('/owner')) {
145
- return record => record.id !== 'angela';
146
- }
147
-
148
- // Grant CRUD permissions
149
- return ['read', 'create', 'update', 'delete'];
150
- }
151
- }
152
- ```
153
-
154
- ## 8. REST API (Auto-generated)
155
-
156
- ```javascript
157
- // Endpoints auto-generated for models:
158
- // GET /owners - List all
159
- // GET /owners/:id - Get one
160
- // POST /animals - Create
161
- // PATCH /animals/:id - Update (attributes and/or relationships)
162
- // DELETE /animals/:id - Delete
163
- ```
164
-
165
- **PATCH supports both attributes and relationships:**
166
- ```javascript
167
- // Update attributes only
168
- PATCH /animals/1
169
- { data: { type: 'animal', attributes: { age: 5 } } }
170
-
171
- // Update relationship only
172
- PATCH /animals/1
173
- { data: { type: 'animal', relationships: { owner: { data: { type: 'owner', id: 'gina' } } } } }
174
-
175
- // Update both
176
- PATCH /animals/1
177
- { data: { type: 'animal', attributes: { age: 5 }, relationships: { owner: { data: { type: 'owner', id: 'gina' } } } } }
178
- ```
179
-
180
- ## 9. Include Parameter (Sideloading)
181
-
182
- GET endpoints support sideloading related records with **nested relationship traversal**:
183
-
184
- ```javascript
185
- // Single-level includes
186
- GET /animals/1?include=owner,traits
187
-
188
- // Nested includes (NEW!)
189
- GET /animals/1?include=owner.pets,owner.company
190
-
191
- // Deep nesting (3+ levels)
192
- GET /scenes/e001-s001?include=slides.dialogue.character
193
-
194
- // Response structure (unchanged)
195
- {
196
- data: { type: 'animal', id: 1, attributes: {...}, relationships: {...} },
197
- included: [
198
- { type: 'owner', id: 'angela', ... },
199
- { type: 'animal', id: 7, ... }, // owner's other pets
200
- { type: 'animal', id: 11, ... }, // owner's other pets
201
- { type: 'company', id: 'acme', ... } // owner's company (if requested)
202
- ]
203
- }
204
- ```
205
-
206
- **How Nested Includes Work:**
207
- 1. Query param parsed into path segments: `owner.pets` -> `[['owner'], ['owner', 'pets'], ['traits']]`
208
- 2. `traverseIncludePath()` recursively traverses relationships depth-first
209
- 3. Deduplication still by type+id (no duplicates in included array)
210
- 4. Gracefully handles null/missing relationships at any depth
211
- 5. Each included record gets full `toJSON()` representation
212
-
213
- **Key Functions:**
214
- - `parseInclude()` - Splits comma-separated includes and parses nested paths
215
- - `traverseIncludePath()` - Recursively traverses relationship paths
216
- - `collectIncludedRecords()` - Orchestrates traversal and deduplication
217
- - All implemented in [src/orm-request.js](src/orm-request.js)
@@ -1,16 +0,0 @@
1
- name: CI
2
-
3
- on:
4
- pull_request:
5
- branches: [dev, main]
6
-
7
- concurrency:
8
- group: ci-${{ github.head_ref || github.ref }}
9
- cancel-in-progress: true
10
-
11
- permissions:
12
- contents: read
13
-
14
- jobs:
15
- test:
16
- uses: abofs/stonyx-workflows/.github/workflows/ci.yml@main
@@ -1,51 +0,0 @@
1
- name: Publish to NPM
2
-
3
- on:
4
- repository_dispatch:
5
- types: [cascade-publish]
6
- workflow_dispatch:
7
- inputs:
8
- version-type:
9
- description: 'Version type'
10
- required: true
11
- type: choice
12
- options:
13
- - patch
14
- - minor
15
- - major
16
- custom-version:
17
- description: 'Custom version (optional, overrides version-type)'
18
- required: false
19
- type: string
20
- pull_request:
21
- types: [opened, synchronize, reopened]
22
- branches: [main]
23
- push:
24
- branches: [main]
25
-
26
- concurrency:
27
- group: ${{ github.event_name == 'repository_dispatch' && 'cascade-update' || format('publish-{0}', github.ref) }}
28
- cancel-in-progress: false
29
-
30
- permissions:
31
- contents: write
32
- id-token: write
33
- pull-requests: write
34
-
35
- jobs:
36
- publish:
37
- if: "!contains(github.event.head_commit.message, '[skip ci]')"
38
- uses: abofs/stonyx-workflows/.github/workflows/npm-publish.yml@main
39
- with:
40
- version-type: ${{ github.event.inputs.version-type }}
41
- custom-version: ${{ github.event.inputs.custom-version }}
42
- cascade-source: ${{ github.event.client_payload.source_package || '' }}
43
- secrets: inherit
44
-
45
- cascade:
46
- needs: publish
47
- uses: abofs/stonyx-workflows/.github/workflows/cascade.yml@main
48
- with:
49
- package-name: ${{ needs.publish.outputs.package-name }}
50
- published-version: ${{ needs.publish.outputs.published-version }}
51
- secrets: inherit
package/improvements.md DELETED
@@ -1,139 +0,0 @@
1
- # Code Improvements: @stonyx/orm
2
-
3
- > Audited: 2026-02-09 | Auto-generated by project-docs-auditor
4
-
5
- ---
6
-
7
- ## Summary
8
-
9
- The codebase is well-structured with clear separation of concerns and consistent patterns. The main areas for improvement are: a debug `console.log` left in production config, duplicated utility functions across multiple files, and documentation that has drifted from the actual code. The MySQL driver is well-tested and cleanly DI'd, but the JSON persistence side lacks equivalent test coverage.
10
-
11
- **Findings by priority:**
12
- | Priority | Count |
13
- |----------|-------|
14
- | High | 2 |
15
- | Medium | 6 |
16
- | Low | 5 |
17
-
18
- ---
19
-
20
- ## High Priority
21
-
22
- ### [H1] Stray `console.log` in production config
23
- - **Category:** Debug Leak
24
- - **Files:** `config/environment.js`
25
- - **Lines:** L57
26
- - **Problem:** `console.log(MYSQL_HOST)` is left at the bottom of the environment config file. This will log the MySQL host (or `undefined`) on every application startup, leaking configuration details to stdout.
27
- - **Suggestion:** Remove the `console.log(MYSQL_HOST)` line entirely.
28
- - **Impact:** Eliminates unintended log noise and prevents leaking configuration values in production.
29
-
30
- ### [H2] Duplicated `getRelationshipInfo()` function
31
- - **Category:** WET Code
32
- - **Files:** `src/orm-request.js` (L18-28), `src/mysql/schema-introspector.js` (L6-14), `src/meta-request.js` (L33-34)
33
- - **Problem:** The pattern of inspecting a function's `toString()` for `getRelationships('belongsTo',` or `getRelationships('hasMany',` is repeated in three separate files with slight variations. Each independently detects relationship type from a property.
34
- - **Suggestion:** Extract a shared `getRelationshipInfo(property)` function into `src/relationships.js` (which already acts as the relationship utility module) and import it from all three consumers.
35
- - **Impact:** Single source of truth for relationship detection. Changes to the detection pattern only need to happen in one place.
36
-
37
- ---
38
-
39
- ## Medium Priority
40
-
41
- ### [M1] Duplicated `getOrSet` helper
42
- - **Category:** WET Code
43
- - **Files:** `src/has-many.js` (imports from `@stonyx/utils/object`), `src/belongs-to.js` (L4-7)
44
- - **Problem:** `belongs-to.js` defines its own local `getOrSet(map, key, defaultValue)` function identical to the one available from `@stonyx/utils/object` that `has-many.js` already imports.
45
- - **Suggestion:** Replace the local `getOrSet` in `belongs-to.js` with `import { getOrSet } from '@stonyx/utils/object'`.
46
- - **Impact:** Eliminates duplicated code and maintains consistency with `has-many.js`.
47
-
48
- ### [M2] Duplicated `getCollectionKeys()` and `getDirPath()`
49
- - **Category:** WET Code
50
- - **Files:** `src/db.js` (L42-61), `src/migrate.js` (L7-26)
51
- - **Problem:** Both files contain identical `getCollectionKeys()` and `getDirPath()` functions. The migration module duplicated these from the DB class as standalone functions.
52
- - **Suggestion:** Export these methods from `src/db.js` (or extract into a shared `src/db-utils.js`) and import them in `src/migrate.js`.
53
- - **Impact:** Eliminates duplication and ensures migration logic always matches DB logic.
54
-
55
- ### [M3] `TYPES` array missing `pendingBelongsTo`
56
- - **Category:** Bug Risk
57
- - **Files:** `src/relationships.js` (L43)
58
- - **Lines:** L43
59
- - **Problem:** `export const TYPES = ['global', 'hasMany', 'belongsTo', 'pending']` is missing `'pendingBelongsTo'`, which is a relationship type initialized in `src/main.js` (L48). The `TYPES` array is used by `store.unloadAllRecords()` (L75) for cleanup, meaning `pendingBelongsTo` entries won't be cleaned up when unloading all records for a model.
60
- - **Suggestion:** Add `'pendingBelongsTo'` to the `TYPES` array.
61
- - **Impact:** Prevents potential stale pending belongsTo references when unloading all records for a model.
62
-
63
- ### [M4] `introspectModels` called repeatedly on every persist operation
64
- - **Category:** Performance
65
- - **Files:** `src/mysql/mysql-db.js` (L147, L193, L231)
66
- - **Problem:** `_persistCreate`, `_persistUpdate`, and `_persistDelete` all call `this.deps.introspectModels()` on every single write operation. Schema introspection iterates all models, creates instances, and inspects properties. Since model schemas don't change at runtime, this is unnecessary repeated work.
67
- - **Suggestion:** Cache the introspected schemas in `MysqlDB.init()` (or lazily on first access) and reuse the cached result in persist methods.
68
- - **Impact:** Reduces CPU overhead on every write operation, especially significant with frequent CRUD activity.
69
-
70
- ### [M5] `startup()` also calls `introspectModels()` separately from `loadAllRecords()`
71
- - **Category:** Performance
72
- - **Files:** `src/mysql/mysql-db.js` (L69, L88)
73
- - **Problem:** `startup()` calls `introspectModels()` at L69 for drift detection, but `loadAllRecords()` (called at L62 inside the migration-apply branch) also calls `introspectModels()` at L88. When migrations are applied, `introspectModels()` runs three times: once in `loadAllRecords` (via init), once in reloaded `loadAllRecords`, and once for drift check.
74
- - **Suggestion:** Same as M4 — cache the result.
75
- - **Impact:** Reduces redundant schema introspection calls during startup.
76
-
77
- ### [M6] No test coverage for JSON DB `save()` and `getRecord()` flows
78
- - **Category:** Test Gap
79
- - **Files:** `src/db.js`
80
- - **Problem:** The JSON file persistence layer (`DB` class) lacks unit tests for its core `save()`, `getRecord()`, `getRecordFromDirectory()`, `getRecordFromFile()`, and `validateMode()` methods. The MySQL driver has thorough unit tests via dependency injection, but the JSON DB has no equivalent.
81
- - **Suggestion:** Add unit tests for `src/db.js`, potentially using the same DI pattern used by `MysqlDB` to mock file operations.
82
- - **Impact:** Increases confidence in the JSON persistence path, which is the default storage mode.
83
-
84
- ---
85
-
86
- ## Low Priority
87
-
88
- ### [L1] Documentation references non-existent files
89
- - **Category:** Stale Docs
90
- - **Files:** `.claude/index.md` (L38-39), `.claude/personal/outline.md` (L1107)
91
- - **Problem:** The `.claude/index.md` references `src/include-parser.js` and `src/include-collector.js` which don't exist — include parsing is inline in `src/orm-request.js`. The outline references `stonyx-bootstrap.cjs` which doesn't exist.
92
- - **Suggestion:** Remove the `include-parser.js` and `include-collector.js` references from `.claude/index.md` and the `stonyx-bootstrap.cjs` reference from the outline. Update the architecture section to point to `src/orm-request.js` for include logic.
93
- - **Impact:** Prevents confusion when navigating docs.
94
-
95
- ### [L2] Outdated version in outline doc
96
- - **Category:** Stale Docs
97
- - **Files:** `.claude/personal/outline.md` (L1076)
98
- - **Problem:** Lists version as `0.1.0` but `package.json` shows `0.2.1-beta.1`.
99
- - **Suggestion:** Update or remove the version reference. Since `package.json` is the source of truth, the docs shouldn't duplicate it.
100
- - **Impact:** Minor — prevents stale version confusion.
101
-
102
- ### [L3] Outline docs missing `./commands` and `./hooks` package exports
103
- - **Category:** Stale Docs
104
- - **Files:** `.claude/personal/outline.md` (L884-889)
105
- - **Problem:** The package.json `exports` section in the outline doc only shows `"."` and `"./db"`, but the actual `package.json` also exports `"./migrate"`, `"./commands"`, and `"./hooks"`.
106
- - **Suggestion:** Update the outline's package.json section to match the actual exports.
107
- - **Impact:** Minor — ensures docs reflect the full public API surface.
108
-
109
- ### [L4] Outline references old event-based system
110
- - **Category:** Stale Docs
111
- - **Files:** `.claude/index.md` (L204)
112
- - **Problem:** States `@stonyx/events - Pub/sub event system (optional, not used for hooks)`. However, `@stonyx/events` is imported and `setup(eventNames)` is called in `src/main.js` (L91). The events are set up but the hooks system uses its own registry. This is confusing — events are initialized but the hooks use a separate middleware pattern.
113
- - **Suggestion:** Clarify that `@stonyx/events` is still initialized for event names during ORM setup, but the actual hook dispatch uses the middleware-based system in `src/hooks.js`.
114
- - **Impact:** Reduces confusion about the relationship between `@stonyx/events` and the hooks system.
115
-
116
- ### [L5] Manual test scripts in project root
117
- - **Category:** Dead Code
118
- - **Files:** `test-hooks-with-logging.js`, `test-events-setup.js`, `test-hooks-manual.js`
119
- - **Problem:** Three manual test scripts remain in the project root from the hooks implementation. They were used to verify functionality when the test harness had linking issues, but are not part of the test suite and won't run via `npm test`.
120
- - **Suggestion:** Either move them to `test/manual/` or remove them if the hooks implementation is considered stable and the test harness issues are resolved.
121
- - **Impact:** Cleaner project root; reduces confusion about which test files are authoritative.
122
-
123
- ---
124
-
125
- ## Refactoring Roadmap
126
-
127
- **Quick wins (do first):**
128
- 1. **H1** — Delete one line (`console.log(MYSQL_HOST)`) in config
129
- 2. **M1** — Replace local `getOrSet` in `belongs-to.js` with import
130
- 3. **M3** — Add `'pendingBelongsTo'` to `TYPES` array
131
-
132
- **Medium effort:**
133
- 4. **H2** — Extract shared `getRelationshipInfo` into `relationships.js`
134
- 5. **M2** — Extract shared `getCollectionKeys`/`getDirPath` from `db.js`
135
-
136
- **Longer term:**
137
- 6. **M4/M5** — Cache introspected schemas in MysqlDB
138
- 7. **M6** — Add DB unit tests
139
- 8. **L1-L4** — Documentation cleanup pass