@dereekb/dbx-components-mcp 13.10.1 → 13.10.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.
|
@@ -0,0 +1,1991 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"code": "archetype-inconsistent",
|
|
4
|
+
"source": "dbx_model_fixture_validate_app",
|
|
5
|
+
"severity": "error",
|
|
6
|
+
"title": "Sub-collection wiring (8-generic factory + parent-aware",
|
|
7
|
+
"whatItFlags": "Sub-collection wiring (8-generic factory + parent-aware\n`getCollection`) without a parent-fixture field on the Params type\n— or vice versa.",
|
|
8
|
+
"whenItApplies": "Sub-collection archetypes (`sub-collection`, `sub-collection-traversal`).",
|
|
9
|
+
"whenItDoesNotApply": "Top-level archetypes (`top-level-simple`, `top-level-with-deps`) — they don't need a parent fixture field.",
|
|
10
|
+
"canonicalFix": "Add the parent fixture field to the Params type (named after the parent's `firestoreModelIdentity` short alias)."
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"code": "forwarder-divergent",
|
|
14
|
+
"source": "dbx_model_fixture_validate_app",
|
|
15
|
+
"severity": "warning",
|
|
16
|
+
"title": "A Fixture forwarder's signature drifts from the Instance method it",
|
|
17
|
+
"whatItFlags": "A Fixture forwarder's signature drifts from the Instance method it\nforwards to.",
|
|
18
|
+
"whenItApplies": "Forwarders whose parameter list, return type, or async-ness differs from the Instance source.",
|
|
19
|
+
"whenItDoesNotApply": "Forwarders that intentionally widen the Instance signature (rare — usually a refactor mismatch).",
|
|
20
|
+
"canonicalFix": "Re-run `dbx_model_fixture_forward` to regenerate the forwarder, or hand-edit the Fixture method to match."
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"code": "forwarder-missing",
|
|
24
|
+
"source": "dbx_model_fixture_validate_app",
|
|
25
|
+
"severity": "warning",
|
|
26
|
+
"title": "An Instance method has no Fixture forwarder",
|
|
27
|
+
"whatItFlags": "An Instance method has no Fixture forwarder.",
|
|
28
|
+
"whenItApplies": "Every public Instance method should have a same-name Fixture forwarder.",
|
|
29
|
+
"whenItDoesNotApply": "Static helpers, private/protected methods, and methods that intentionally exist only on Instance.",
|
|
30
|
+
"canonicalFix": "Run `dbx_model_fixture_forward apiDir=<apiDir> model=<Model>` to scaffold the missing forwarder.",
|
|
31
|
+
"seeAlso": [
|
|
32
|
+
{
|
|
33
|
+
"kind": "tool",
|
|
34
|
+
"target": "dbx_model_fixture_forward"
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"code": "forwarder-not-delegating",
|
|
40
|
+
"source": "dbx_model_fixture_validate_app",
|
|
41
|
+
"severity": "warning",
|
|
42
|
+
"title": "A Fixture forwarder exists but its body re-implements the Instance",
|
|
43
|
+
"whatItFlags": "A Fixture forwarder exists but its body re-implements the Instance\nlogic instead of delegating via `this.instance.<name>(...)`.",
|
|
44
|
+
"whenItApplies": "Forwarders whose body contains anything beyond a delegation call.",
|
|
45
|
+
"whenItDoesNotApply": "Forwarders intentionally adding pre/post hooks (rare; prefer encapsulating the hook in an Instance method).",
|
|
46
|
+
"canonicalFix": "Replace the forwarder body with `return this.instance.<name>(...args)`."
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"code": "generics-misaligned",
|
|
50
|
+
"source": "dbx_model_fixture_validate_app",
|
|
51
|
+
"severity": "error",
|
|
52
|
+
"title": "Model / Document generic args drift between the Fixture class, the",
|
|
53
|
+
"whatItFlags": "Model / Document generic args drift between the Fixture class, the\nInstance class, and the `modelTestContextFactory` call.",
|
|
54
|
+
"whenItApplies": "Every triplet's three generic-bearing positions (Fixture, Instance, factory).",
|
|
55
|
+
"whenItDoesNotApply": "Triplets that intentionally use a wider generic on Fixture (rare — almost always a typo or rename drift).",
|
|
56
|
+
"canonicalFix": "Align the generics on all three positions; the model and document type names should match exactly."
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"code": "model-not-in-registry",
|
|
60
|
+
"source": "dbx_model_fixture_validate_app",
|
|
61
|
+
"severity": "warning",
|
|
62
|
+
"title": "The fixture references a model not in the supplied model registry",
|
|
63
|
+
"whatItFlags": "The fixture references a model not in the supplied model registry.",
|
|
64
|
+
"whenItApplies": "When a model registry is supplied.",
|
|
65
|
+
"whenItDoesNotApply": "Downstream apps without a hooked-up registry — the rule is skipped entirely in that case.",
|
|
66
|
+
"canonicalFix": "Either register the model in the workspace's identity registry or remove the fixture if the model is no longer used."
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"code": "model-without-fixture",
|
|
70
|
+
"source": "dbx_model_fixture_validate_app",
|
|
71
|
+
"severity": "warning",
|
|
72
|
+
"title": "The model registry has the model but the fixture file doesn't",
|
|
73
|
+
"whatItFlags": "The model registry has the model but the fixture file doesn't\ndeclare a TestContext triplet for it.",
|
|
74
|
+
"whenItApplies": "When a model registry is supplied.",
|
|
75
|
+
"whenItDoesNotApply": "Models the app intentionally tests through some other harness (rare).",
|
|
76
|
+
"canonicalFix": "Run `dbx_model_fixture_scaffold apiDir=<apiDir> model=<Model>` to add the missing triplet.",
|
|
77
|
+
"seeAlso": [
|
|
78
|
+
{
|
|
79
|
+
"kind": "tool",
|
|
80
|
+
"target": "dbx_model_fixture_scaffold"
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"code": "params-field-naming",
|
|
86
|
+
"source": "dbx_model_fixture_validate_app",
|
|
87
|
+
"severity": "warning",
|
|
88
|
+
"title": "A parent fixture field's name doesn't match the parent's",
|
|
89
|
+
"whatItFlags": "A parent fixture field's name doesn't match the parent's\n`firestoreModelIdentity` short alias (e.g. `sg` for `SchoolGroup`).",
|
|
90
|
+
"whenItApplies": "When a model registry is supplied AND the field's parent fixture model is registered.",
|
|
91
|
+
"whenItDoesNotApply": "Fields whose parent fixture is intentionally aliased; or runs without a model registry.",
|
|
92
|
+
"canonicalFix": "Rename the field on the Params type to the parent's short alias from `firestoreModelIdentity`."
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"code": "triplet-incomplete",
|
|
96
|
+
"source": "dbx_model_fixture_validate_app",
|
|
97
|
+
"severity": "error",
|
|
98
|
+
"title": "A model is missing one of Fixture / Instance / Params / factory",
|
|
99
|
+
"whatItFlags": "A model is missing one of Fixture / Instance / Params / factory\ncall / singleton — the five-anchor triplet definition is incomplete.",
|
|
100
|
+
"whenItApplies": "Every model that has at least one of the anchors.",
|
|
101
|
+
"whenItDoesNotApply": "Models intentionally not yet wired (uncommon — usually a forgotten scaffold step).",
|
|
102
|
+
"canonicalFix": "Run `dbx_model_fixture_scaffold apiDir=<apiDir> model=<Model>` to generate the missing pieces.",
|
|
103
|
+
"seeAlso": [
|
|
104
|
+
{
|
|
105
|
+
"kind": "tool",
|
|
106
|
+
"target": "dbx_model_fixture_scaffold"
|
|
107
|
+
}
|
|
108
|
+
]
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"code": "FILE_GROUP_INTERFACE_AFTER_MODEL",
|
|
112
|
+
"source": "dbx_model_validate",
|
|
113
|
+
"severity": "error",
|
|
114
|
+
"title": "The `<Group>FirestoreCollections` interface is declared after the first model",
|
|
115
|
+
"whatItFlags": "The `<Group>FirestoreCollections` interface is declared after the first model.",
|
|
116
|
+
"whenItApplies": "Every model file with both an interface and at least one model declaration.",
|
|
117
|
+
"whenItDoesNotApply": "Files declaring no models (the interface ordering rule is moot there).",
|
|
118
|
+
"canonicalFix": "Move the `<Group>FirestoreCollections` interface above the first model declaration."
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"code": "FILE_GROUP_INTERFACE_MISSING_COLLECTION",
|
|
122
|
+
"source": "dbx_model_validate",
|
|
123
|
+
"severity": "error",
|
|
124
|
+
"title": "The `<Group>FirestoreCollections` interface is missing the collection entry for one of the file's models",
|
|
125
|
+
"whatItFlags": "The `<Group>FirestoreCollections` interface is missing the collection entry for one of the file's models.",
|
|
126
|
+
"whenItApplies": "Every model in the file must have its `<camelName>Collection` (root) or `<camelName>CollectionFactory` + `<camelName>CollectionGroup` (subcollection) entries on the interface.",
|
|
127
|
+
"whenItDoesNotApply": "Models intentionally excluded from the group container (rare).",
|
|
128
|
+
"canonicalFix": "Add the missing property to the interface declaration."
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"code": "FILE_GROUP_INTERFACE_NOT_EXPORTED",
|
|
132
|
+
"source": "dbx_model_validate",
|
|
133
|
+
"severity": "error",
|
|
134
|
+
"title": "The `<Group>FirestoreCollections` interface is declared but not exported",
|
|
135
|
+
"whatItFlags": "The `<Group>FirestoreCollections` interface is declared but not exported.",
|
|
136
|
+
"whenItApplies": "Every group-collections interface declaration.",
|
|
137
|
+
"whenItDoesNotApply": "When the interface is intentionally module-private (rare — the model wiring needs it cross-file).",
|
|
138
|
+
"canonicalFix": "Add the `export` keyword to the interface declaration."
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"code": "FILE_GROUP_TYPES_AFTER_MODEL",
|
|
142
|
+
"source": "dbx_model_validate",
|
|
143
|
+
"severity": "error",
|
|
144
|
+
"title": "The `<Group>Types` alias is declared after the first model",
|
|
145
|
+
"whatItFlags": "The `<Group>Types` alias is declared after the first model.",
|
|
146
|
+
"whenItApplies": "Every model file with both a types alias and at least one model.",
|
|
147
|
+
"whenItDoesNotApply": "Files declaring no models.",
|
|
148
|
+
"canonicalFix": "Move the `<Group>Types` alias above the first model."
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"code": "FILE_GROUP_TYPES_MISSING_IDENTITY",
|
|
152
|
+
"source": "dbx_model_validate",
|
|
153
|
+
"severity": "error",
|
|
154
|
+
"title": "The `<Group>Types` alias is missing a `typeof <identity>` ref for one of the file's models",
|
|
155
|
+
"whatItFlags": "The `<Group>Types` alias is missing a `typeof <identity>` ref for one of the file's models.",
|
|
156
|
+
"whenItApplies": "Every identity declared in the file must appear in the types union.",
|
|
157
|
+
"whenItDoesNotApply": "When the model is intentionally excluded (rare — the union is the canonical type discriminator).",
|
|
158
|
+
"canonicalFix": "Add `| typeof <identity>` to the union."
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"code": "FILE_GROUP_TYPES_NOT_EXPORTED",
|
|
162
|
+
"source": "dbx_model_validate",
|
|
163
|
+
"severity": "error",
|
|
164
|
+
"title": "The `<Group>Types` alias is declared but not exported",
|
|
165
|
+
"whatItFlags": "The `<Group>Types` alias is declared but not exported.",
|
|
166
|
+
"whenItApplies": "Every group-types alias.",
|
|
167
|
+
"whenItDoesNotApply": "When intentionally module-private (rare — downstream code consumes the union).",
|
|
168
|
+
"canonicalFix": "Add `export` to the type alias declaration."
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"code": "FILE_GROUP_TYPES_UNKNOWN_IDENTITY",
|
|
172
|
+
"source": "dbx_model_validate",
|
|
173
|
+
"severity": "error",
|
|
174
|
+
"title": "The `<Group>Types` alias references an identity that isn't declared in the file",
|
|
175
|
+
"whatItFlags": "The `<Group>Types` alias references an identity that isn't declared in the file.",
|
|
176
|
+
"whenItApplies": "Every identity ref in the union.",
|
|
177
|
+
"whenItDoesNotApply": "When the identity is imported from another file (rare — usually a typo).",
|
|
178
|
+
"canonicalFix": "Either declare the identity in the file or remove the orphaned ref."
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"code": "FILE_MISSING_GROUP_INTERFACE",
|
|
182
|
+
"source": "dbx_model_validate",
|
|
183
|
+
"severity": "error",
|
|
184
|
+
"title": "The file is missing its `<Group>FirestoreCollections` interface",
|
|
185
|
+
"whatItFlags": "The file is missing its `<Group>FirestoreCollections` interface.",
|
|
186
|
+
"whenItApplies": "Every model file (one declaring `firestoreModelIdentity(...)`) must anchor its `<Group>FirestoreCollections` interface above the first model.",
|
|
187
|
+
"whenItDoesNotApply": "Files in `@dereekb/firebase` itself — those are upstream sources owned by the package.",
|
|
188
|
+
"canonicalFix": "Declare `export interface <Group>FirestoreCollections { ... }` above the first `firestoreModelIdentity(...)` call.",
|
|
189
|
+
"seeAlso": [
|
|
190
|
+
{
|
|
191
|
+
"kind": "artifact",
|
|
192
|
+
"target": "firestore-model"
|
|
193
|
+
}
|
|
194
|
+
]
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"code": "FILE_MISSING_GROUP_TYPES",
|
|
198
|
+
"source": "dbx_model_validate",
|
|
199
|
+
"severity": "error",
|
|
200
|
+
"title": "The file is missing its `<Group>Types` union alias",
|
|
201
|
+
"whatItFlags": "The file is missing its `<Group>Types` union alias.",
|
|
202
|
+
"whenItApplies": "Every model file must declare a `<Group>Types` union of `typeof <identity>` covering every model in the file.",
|
|
203
|
+
"whenItDoesNotApply": "Files in `@dereekb/firebase` itself.",
|
|
204
|
+
"canonicalFix": "Add `export type <Group>Types = typeof <Identity1>FirestoreModelIdentity | typeof <Identity2>FirestoreModelIdentity ...`."
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"code": "MODEL_COLLECTION_FACTORY_TYPE_MISMATCH",
|
|
208
|
+
"source": "dbx_model_validate",
|
|
209
|
+
"severity": "error",
|
|
210
|
+
"title": "The collection-type alias kind disagrees with the factory body's `firestoreContext.*` call",
|
|
211
|
+
"whatItFlags": "The collection-type alias kind disagrees with the factory body's `firestoreContext.*` call.",
|
|
212
|
+
"whenItApplies": "When the type alias declares one shape and the factory implements another (e.g. type says `RootSingleItemFirestoreCollection` but body calls `firestoreCollection`).",
|
|
213
|
+
"whenItDoesNotApply": "When the validator can't locate the factory body (rare — emits no rule then).",
|
|
214
|
+
"canonicalFix": "Pick one shape and use it consistently — either change the type alias or change the factory body to match."
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
"code": "MODEL_COLLECTION_TYPE_WRONG_GENERIC",
|
|
218
|
+
"source": "dbx_model_validate",
|
|
219
|
+
"severity": "error",
|
|
220
|
+
"title": "The collection type alias uses the wrong generic shape for the model variant",
|
|
221
|
+
"whatItFlags": "The collection type alias uses the wrong generic shape for the model variant.",
|
|
222
|
+
"whenItApplies": "The 4-shape taxonomy: `FirestoreCollection<T, D>` for root, `RootSingleItemFirestoreCollection<T, D>` for root-singleton, `FirestoreCollectionWithParent<T, PT, D, PD>` for sub-collection, `SingleItemFirestoreCollection<T, PT, D, PD>` for singleton-sub.",
|
|
223
|
+
"whenItDoesNotApply": "Multi-document subcollections that should genuinely use `FirestoreCollectionWithParent` — confirm the factory body calls `firestoreContext.firestoreCollectionWithParent({...})`. If yes, this rule is a false-positive (the validator detected `singleItemFirestoreCollection` somewhere it shouldn't have).",
|
|
224
|
+
"canonicalFix": "Match the type alias's generics to the factory body's `firestoreContext.*` call. Run `dbx_explain_rule code=\"MODEL_COLLECTION_TYPE_WRONG_GENERIC\"` for the full taxonomy.",
|
|
225
|
+
"seeAlso": [
|
|
226
|
+
{
|
|
227
|
+
"kind": "artifact",
|
|
228
|
+
"target": "firestore-model"
|
|
229
|
+
}
|
|
230
|
+
]
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
"code": "MODEL_CONVERTER_NOT_EXPORTED",
|
|
234
|
+
"source": "dbx_model_validate",
|
|
235
|
+
"severity": "error",
|
|
236
|
+
"title": "The converter constant is declared but not exported",
|
|
237
|
+
"whatItFlags": "The converter constant is declared but not exported.",
|
|
238
|
+
"whenItApplies": "Every converter constant.",
|
|
239
|
+
"whenItDoesNotApply": "When intentionally module-private.",
|
|
240
|
+
"canonicalFix": "Add `export` to the converter declaration."
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
"code": "MODEL_DOCUMENT_BAD_TYPE_ARGS",
|
|
244
|
+
"source": "dbx_model_validate",
|
|
245
|
+
"severity": "error",
|
|
246
|
+
"title": "The document class's generic type args don't line up with the model identity / interface",
|
|
247
|
+
"whatItFlags": "The document class's generic type args don't line up with the model identity / interface.",
|
|
248
|
+
"whenItApplies": "Every document class.",
|
|
249
|
+
"whenItDoesNotApply": "When generics are intentionally widened (rare).",
|
|
250
|
+
"canonicalFix": "Pass `<PascalName>, <PascalName>Document>` (root) or include the parent generics for subcollections."
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
"code": "MODEL_DOCUMENT_CLASS_NOT_EXPORTED",
|
|
254
|
+
"source": "dbx_model_validate",
|
|
255
|
+
"severity": "error",
|
|
256
|
+
"title": "The document class is declared but not exported",
|
|
257
|
+
"whatItFlags": "The document class is declared but not exported.",
|
|
258
|
+
"whenItApplies": "Every document class.",
|
|
259
|
+
"whenItDoesNotApply": "When intentionally module-private.",
|
|
260
|
+
"canonicalFix": "Add `export` to the class declaration."
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
"code": "MODEL_DOCUMENT_MISSING_IDENTITY_GETTER",
|
|
264
|
+
"source": "dbx_model_validate",
|
|
265
|
+
"severity": "error",
|
|
266
|
+
"title": "The document class is missing the `get modelIdentity()` getter",
|
|
267
|
+
"whatItFlags": "The document class is missing the `get modelIdentity()` getter.",
|
|
268
|
+
"whenItApplies": "Every document class.",
|
|
269
|
+
"whenItDoesNotApply": "Document classes inheriting the getter from a custom abstract base (rare).",
|
|
270
|
+
"canonicalFix": "Add `get modelIdentity() { return <identity>; }` returning the matching identity constant."
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
"code": "MODEL_DOCUMENT_WRONG_BASE_CLASS",
|
|
274
|
+
"source": "dbx_model_validate",
|
|
275
|
+
"severity": "error",
|
|
276
|
+
"title": "The document class extends an unsupported base class",
|
|
277
|
+
"whatItFlags": "The document class extends an unsupported base class.",
|
|
278
|
+
"whenItApplies": "Every document class — must extend `AbstractFirestoreDocument` (root) or `AbstractFirestoreDocumentWithParent` (subcollection).",
|
|
279
|
+
"whenItDoesNotApply": "Custom document hierarchies (rare; usually a typo).",
|
|
280
|
+
"canonicalFix": "Change the `extends` clause to the canonical base class for the model variant."
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
"code": "MODEL_DOCUMENT_WRONG_IDENTITY_GETTER",
|
|
284
|
+
"source": "dbx_model_validate",
|
|
285
|
+
"severity": "error",
|
|
286
|
+
"title": "The document's `get modelIdentity()` returns the wrong identity constant",
|
|
287
|
+
"whatItFlags": "The document's `get modelIdentity()` returns the wrong identity constant.",
|
|
288
|
+
"whenItApplies": "Every document class.",
|
|
289
|
+
"whenItDoesNotApply": "When the rename was intentional (rare — usually a copy-paste).",
|
|
290
|
+
"canonicalFix": "Update the getter body to return the matching identity constant."
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
"code": "MODEL_FIELD_JSDOC_NO_FULL_NAME",
|
|
294
|
+
"source": "dbx_model_validate",
|
|
295
|
+
"severity": "warning",
|
|
296
|
+
"title": "A persisted field's JSDoc doesn't open with `<fullName> -- <description>`",
|
|
297
|
+
"whatItFlags": "A persisted field's JSDoc doesn't open with `<fullName> -- <description>`.",
|
|
298
|
+
"whenItApplies": "Every field with JSDoc — the first line should match the `<fullName> -- <description>` pattern so the long-name extractor and decoder agree on field semantics.",
|
|
299
|
+
"whenItDoesNotApply": "When the project deliberately uses a non-standard JSDoc convention (rare).",
|
|
300
|
+
"canonicalFix": "Reformat the JSDoc opener to `<longName> -- <one-line description>`."
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
"code": "MODEL_FIELD_MISSING_JSDOC",
|
|
304
|
+
"source": "dbx_model_validate",
|
|
305
|
+
"severity": "warning",
|
|
306
|
+
"title": "A persisted field has no JSDoc",
|
|
307
|
+
"whatItFlags": "A persisted field has no JSDoc.",
|
|
308
|
+
"whenItApplies": "Every persisted field — short field names need JSDoc to document what they mean.",
|
|
309
|
+
"whenItDoesNotApply": "Fields whose name is unambiguously self-describing (rare with 1-4 char abbreviations).",
|
|
310
|
+
"canonicalFix": "Add `/** <fullName> -- <description> *\\/` above the field declaration."
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
"code": "MODEL_FIELD_NAME_TOO_LONG",
|
|
314
|
+
"source": "dbx_model_validate",
|
|
315
|
+
"severity": "warning",
|
|
316
|
+
"title": "A persisted field's name exceeds the workspace's 4-character convention",
|
|
317
|
+
"whatItFlags": "A persisted field's name exceeds the workspace's 4-character convention.",
|
|
318
|
+
"whenItApplies": "Every persisted field on a model interface (or sub-object interface).",
|
|
319
|
+
"whenItDoesNotApply": "Fields that compose well-known multi-character abbreviations the project intentionally allows.",
|
|
320
|
+
"canonicalFix": "Rename the field to a 1–4 character abbreviation (e.g. `name` → `n`, `userId` → `uid`)."
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
"code": "MODEL_IDENTITY_BAD_ARGS",
|
|
324
|
+
"source": "dbx_model_validate",
|
|
325
|
+
"severity": "error",
|
|
326
|
+
"title": "`firestoreModelIdentity(...)` was called with non-string-literal args (or wrong arity)",
|
|
327
|
+
"whatItFlags": "`firestoreModelIdentity(...)` was called with non-string-literal args (or wrong arity).",
|
|
328
|
+
"whenItApplies": "Every identity call.",
|
|
329
|
+
"whenItDoesNotApply": "When the args come from a const (uncommon — the validator can't follow non-literal references).",
|
|
330
|
+
"canonicalFix": "Pass `(parentIdentity?, '<modelType>', '<prefix>')` as inline string literals."
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
"code": "MODEL_IDENTITY_NOT_EXPORTED",
|
|
334
|
+
"source": "dbx_model_validate",
|
|
335
|
+
"severity": "error",
|
|
336
|
+
"title": "The model's `firestoreModelIdentity(...)` const is not exported",
|
|
337
|
+
"whatItFlags": "The model's `firestoreModelIdentity(...)` const is not exported.",
|
|
338
|
+
"whenItApplies": "Every identity constant.",
|
|
339
|
+
"whenItDoesNotApply": "When intentionally module-private (rare).",
|
|
340
|
+
"canonicalFix": "Add `export` to the identity constant declaration."
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
"code": "MODEL_INTERFACE_NOT_EXPORTED",
|
|
344
|
+
"source": "dbx_model_validate",
|
|
345
|
+
"severity": "error",
|
|
346
|
+
"title": "The model's data interface is declared but not exported",
|
|
347
|
+
"whatItFlags": "The model's data interface is declared but not exported.",
|
|
348
|
+
"whenItApplies": "Every model interface declaration.",
|
|
349
|
+
"whenItDoesNotApply": "When intentionally module-private (rare).",
|
|
350
|
+
"canonicalFix": "Add `export` to the interface declaration."
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
"code": "MODEL_MISSING_COLLECTION_FN",
|
|
354
|
+
"source": "dbx_model_validate",
|
|
355
|
+
"severity": "error",
|
|
356
|
+
"title": "The model has no `<camelName>FirestoreCollection` (root) or `<camelName>FirestoreCollectionFactory` (subcollection) function",
|
|
357
|
+
"whatItFlags": "The model has no `<camelName>FirestoreCollection` (root) or `<camelName>FirestoreCollectionFactory` (subcollection) function.",
|
|
358
|
+
"whenItApplies": "Every model.",
|
|
359
|
+
"whenItDoesNotApply": "When the function is intentionally inlined (rare).",
|
|
360
|
+
"canonicalFix": "Declare the matching factory function."
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
"code": "MODEL_MISSING_COLLECTION_REFERENCE",
|
|
364
|
+
"source": "dbx_model_validate",
|
|
365
|
+
"severity": "error",
|
|
366
|
+
"title": "The model has no collection-reference function (`<camelName>CollectionReference` for root or `<camelName>CollectionReferenceFactory` for subcollection)",
|
|
367
|
+
"whatItFlags": "The model has no collection-reference function (`<camelName>CollectionReference` for root or `<camelName>CollectionReferenceFactory` for subcollection).",
|
|
368
|
+
"whenItApplies": "Every model.",
|
|
369
|
+
"whenItDoesNotApply": "Models that intentionally bypass the canonical reference shape.",
|
|
370
|
+
"canonicalFix": "Declare the matching reference function next to the converter."
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
"code": "MODEL_MISSING_COLLECTION_TYPE",
|
|
374
|
+
"source": "dbx_model_validate",
|
|
375
|
+
"severity": "error",
|
|
376
|
+
"title": "The model has no `<PascalName>FirestoreCollection` type alias",
|
|
377
|
+
"whatItFlags": "The model has no `<PascalName>FirestoreCollection` type alias.",
|
|
378
|
+
"whenItApplies": "Every model.",
|
|
379
|
+
"whenItDoesNotApply": "When intentionally re-using a parent type (rare).",
|
|
380
|
+
"canonicalFix": "Declare `export type <PascalName>FirestoreCollection = FirestoreCollection<<PascalName>, <PascalName>Document>;`."
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
"code": "MODEL_MISSING_CONVERTER",
|
|
384
|
+
"source": "dbx_model_validate",
|
|
385
|
+
"severity": "error",
|
|
386
|
+
"title": "The model has no `<camelName>Converter` constant",
|
|
387
|
+
"whatItFlags": "The model has no `<camelName>Converter` constant.",
|
|
388
|
+
"whenItApplies": "Every model in the file.",
|
|
389
|
+
"whenItDoesNotApply": "Models intentionally sharing a converter (rare).",
|
|
390
|
+
"canonicalFix": "Declare `export const <camelName>Converter = snapshotConverterFunctions<<PascalName>>({ fields: { ... } });`."
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
"code": "MODEL_MISSING_DOCUMENT_CLASS",
|
|
394
|
+
"source": "dbx_model_validate",
|
|
395
|
+
"severity": "error",
|
|
396
|
+
"title": "The model has no matching `<PascalName>Document` class",
|
|
397
|
+
"whatItFlags": "The model has no matching `<PascalName>Document` class.",
|
|
398
|
+
"whenItApplies": "Every model in the file.",
|
|
399
|
+
"whenItDoesNotApply": "Models intentionally extending a shared document class.",
|
|
400
|
+
"canonicalFix": "Declare `export class <PascalName>Document extends AbstractFirestoreDocument<...> { ... }`."
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
"code": "MODEL_MISSING_INTERFACE",
|
|
404
|
+
"source": "dbx_model_validate",
|
|
405
|
+
"severity": "error",
|
|
406
|
+
"title": "The model has no matching data interface (`<PascalName>`)",
|
|
407
|
+
"whatItFlags": "The model has no matching data interface (`<PascalName>`).",
|
|
408
|
+
"whenItApplies": "Every model in the file.",
|
|
409
|
+
"whenItDoesNotApply": "Models that intentionally reuse another file's interface (rare).",
|
|
410
|
+
"canonicalFix": "Declare `export interface <PascalName> extends FirestoreModelData { ... }`.",
|
|
411
|
+
"seeAlso": [
|
|
412
|
+
{
|
|
413
|
+
"kind": "artifact",
|
|
414
|
+
"target": "firestore-model"
|
|
415
|
+
}
|
|
416
|
+
]
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
"code": "MODEL_MISSING_ROLES",
|
|
420
|
+
"source": "dbx_model_validate",
|
|
421
|
+
"severity": "error",
|
|
422
|
+
"title": "The model has no matching `<PascalName>Roles` type alias",
|
|
423
|
+
"whatItFlags": "The model has no matching `<PascalName>Roles` type alias.",
|
|
424
|
+
"whenItApplies": "Every model in the file.",
|
|
425
|
+
"whenItDoesNotApply": "Models that intentionally reuse a parent's role union (rare).",
|
|
426
|
+
"canonicalFix": "Declare `export type <PascalName>Roles = 'role-a' | 'role-b' | ...`."
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
"code": "MODEL_OUT_OF_ORDER",
|
|
430
|
+
"source": "dbx_model_validate",
|
|
431
|
+
"severity": "error",
|
|
432
|
+
"title": "The model's declarations are out of canonical order",
|
|
433
|
+
"whatItFlags": "The model's declarations are out of canonical order.",
|
|
434
|
+
"whenItApplies": "Every model — declarations follow the order: identity, interface, rolesType, documentClass, converter, referenceFn, collectionType, collectionFn (root) or … collectionFactoryType, collectionFn, referenceGroupFn, collectionGroupType, collectionGroupFn (subcollection).",
|
|
435
|
+
"whenItDoesNotApply": "Files where multiple models intentionally interleave (rare; prefer one-model-per-file).",
|
|
436
|
+
"canonicalFix": "Re-order the declarations to match the canonical sequence."
|
|
437
|
+
},
|
|
438
|
+
{
|
|
439
|
+
"code": "MODEL_ROLES_NOT_EXPORTED",
|
|
440
|
+
"source": "dbx_model_validate",
|
|
441
|
+
"severity": "error",
|
|
442
|
+
"title": "The roles type is declared but not exported",
|
|
443
|
+
"whatItFlags": "The roles type is declared but not exported.",
|
|
444
|
+
"whenItApplies": "Every roles type alias.",
|
|
445
|
+
"whenItDoesNotApply": "When intentionally module-private.",
|
|
446
|
+
"canonicalFix": "Add `export` to the alias."
|
|
447
|
+
},
|
|
448
|
+
{
|
|
449
|
+
"code": "SUB_MISSING_COLLECTION_FACTORY_FN",
|
|
450
|
+
"source": "dbx_model_validate",
|
|
451
|
+
"severity": "error",
|
|
452
|
+
"title": "Subcollection model is missing its `<camelName>FirestoreCollectionFactory` function",
|
|
453
|
+
"whatItFlags": "Subcollection model is missing its `<camelName>FirestoreCollectionFactory` function.",
|
|
454
|
+
"whenItApplies": "Every subcollection model.",
|
|
455
|
+
"whenItDoesNotApply": "Root models.",
|
|
456
|
+
"canonicalFix": "Declare `export function <camelName>FirestoreCollectionFactory(...)`."
|
|
457
|
+
},
|
|
458
|
+
{
|
|
459
|
+
"code": "SUB_MISSING_COLLECTION_FACTORY_TYPE",
|
|
460
|
+
"source": "dbx_model_validate",
|
|
461
|
+
"severity": "error",
|
|
462
|
+
"title": "Subcollection model is missing its `<PascalName>FirestoreCollectionFactory` type alias",
|
|
463
|
+
"whatItFlags": "Subcollection model is missing its `<PascalName>FirestoreCollectionFactory` type alias.",
|
|
464
|
+
"whenItApplies": "Every subcollection model.",
|
|
465
|
+
"whenItDoesNotApply": "Root models.",
|
|
466
|
+
"canonicalFix": "Declare `export type <PascalName>FirestoreCollectionFactory = FirestoreCollectionWithParentFactory<...>;`."
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
"code": "SUB_MISSING_COLLECTION_GROUP_FN",
|
|
470
|
+
"source": "dbx_model_validate",
|
|
471
|
+
"severity": "error",
|
|
472
|
+
"title": "Subcollection model is missing its `<camelName>FirestoreCollectionGroup` function",
|
|
473
|
+
"whatItFlags": "Subcollection model is missing its `<camelName>FirestoreCollectionGroup` function.",
|
|
474
|
+
"whenItApplies": "Every subcollection model.",
|
|
475
|
+
"whenItDoesNotApply": "Root models.",
|
|
476
|
+
"canonicalFix": "Declare `export function <camelName>FirestoreCollectionGroup(firestoreContext)`."
|
|
477
|
+
},
|
|
478
|
+
{
|
|
479
|
+
"code": "SUB_MISSING_COLLECTION_GROUP_REFERENCE",
|
|
480
|
+
"source": "dbx_model_validate",
|
|
481
|
+
"severity": "error",
|
|
482
|
+
"title": "Subcollection model is missing its `<camelName>CollectionGroup` reference function",
|
|
483
|
+
"whatItFlags": "Subcollection model is missing its `<camelName>CollectionGroup` reference function.",
|
|
484
|
+
"whenItApplies": "Every subcollection model.",
|
|
485
|
+
"whenItDoesNotApply": "Root models — they don't have a collection-group concept.",
|
|
486
|
+
"canonicalFix": "Declare `export function <camelName>CollectionGroup(firestoreContext)`."
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
"code": "SUB_MISSING_COLLECTION_GROUP_TYPE",
|
|
490
|
+
"source": "dbx_model_validate",
|
|
491
|
+
"severity": "error",
|
|
492
|
+
"title": "Subcollection model is missing its `<PascalName>FirestoreCollectionGroup` type alias",
|
|
493
|
+
"whatItFlags": "Subcollection model is missing its `<PascalName>FirestoreCollectionGroup` type alias.",
|
|
494
|
+
"whenItApplies": "Every subcollection model.",
|
|
495
|
+
"whenItDoesNotApply": "Root models.",
|
|
496
|
+
"canonicalFix": "Declare `export type <PascalName>FirestoreCollectionGroup = FirestoreCollectionGroup<...>;`."
|
|
497
|
+
},
|
|
498
|
+
{
|
|
499
|
+
"code": "SUB_MISSING_COLLECTION_REFERENCE_FACTORY",
|
|
500
|
+
"source": "dbx_model_validate",
|
|
501
|
+
"severity": "error",
|
|
502
|
+
"title": "Subcollection model is missing its `<camelName>CollectionReferenceFactory` function",
|
|
503
|
+
"whatItFlags": "Subcollection model is missing its `<camelName>CollectionReferenceFactory` function.",
|
|
504
|
+
"whenItApplies": "Every subcollection model.",
|
|
505
|
+
"whenItDoesNotApply": "Root models — they declare `<camelName>CollectionReference` instead.",
|
|
506
|
+
"canonicalFix": "Declare `export function <camelName>CollectionReferenceFactory(...)`."
|
|
507
|
+
},
|
|
508
|
+
{
|
|
509
|
+
"code": "CRUD_CLASS_MISSING_KEY",
|
|
510
|
+
"source": "dbx_model_validate_api",
|
|
511
|
+
"severity": "warning",
|
|
512
|
+
"title": "A non-null CRUD key is missing the matching abstract member on `<Group>Functions`",
|
|
513
|
+
"whatItFlags": "A non-null CRUD key is missing the matching abstract member on `<Group>Functions`.",
|
|
514
|
+
"whenItApplies": "Every non-null key of `<Group>FunctionTypeCrudConfig` that doesn't appear as a member name on the abstract Functions class.",
|
|
515
|
+
"whenItDoesNotApply": "Keys covered by an inherited member from a base class (rare — CRUD members are declared per file by convention).",
|
|
516
|
+
"canonicalFix": "Add `abstract <key>: ModelFirebaseFunctionMapFunction<<Group>FunctionTypeMap, '<key>'>;` to the class."
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
"code": "CRUD_CONFIG_CONST_WRONG_GENERIC",
|
|
520
|
+
"source": "dbx_model_validate_api",
|
|
521
|
+
"severity": "error",
|
|
522
|
+
"title": "`<group>FunctionTypeCrudConfig` constant is annotated with the wrong generic argument",
|
|
523
|
+
"whatItFlags": "`<group>FunctionTypeCrudConfig` constant is annotated with the wrong generic argument.",
|
|
524
|
+
"whenItApplies": "When the type annotation on the const isn't the matching `<Group>FunctionTypeCrudConfig` type alias.",
|
|
525
|
+
"whenItDoesNotApply": "No known false-positive cases — the generic must point at the local type alias.",
|
|
526
|
+
"canonicalFix": "Set the annotation to `<Group>FunctionTypeCrudConfig` so the call map shape is inferred from the type map."
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
"code": "CRUD_CONFIG_MISSING_RESULT_TUPLE",
|
|
530
|
+
"source": "dbx_model_validate_api",
|
|
531
|
+
"severity": "warning",
|
|
532
|
+
"title": "A CRUD config leaf references the bare `*Params` interface without the `[Params, Result]` tuple form",
|
|
533
|
+
"whatItFlags": "A CRUD config leaf references the bare `*Params` interface without the `[Params, Result]` tuple form.",
|
|
534
|
+
"whenItApplies": "Every CRUD leaf that uses `<key>: <Foo>ParamsType` instead of `<key>: [<Foo>ParamsType, <Foo>Result]`.",
|
|
535
|
+
"whenItDoesNotApply": "CRUD entries whose result type is intentionally `void` (rare — convention is to declare `*Result` and use the tuple form).",
|
|
536
|
+
"canonicalFix": "Convert the leaf to the tuple form `[<Foo>ParamsType, <Foo>Result]` so the function signature carries the result type."
|
|
537
|
+
},
|
|
538
|
+
{
|
|
539
|
+
"code": "CRUD_CONST_MISSING_KEY",
|
|
540
|
+
"source": "dbx_model_validate_api",
|
|
541
|
+
"severity": "warning",
|
|
542
|
+
"title": "A non-null CRUD key is missing from the runtime `<group>FunctionTypeCrudConfig` const",
|
|
543
|
+
"whatItFlags": "A non-null CRUD key is missing from the runtime `<group>FunctionTypeCrudConfig` const.",
|
|
544
|
+
"whenItApplies": "Every non-null key declared on the `<Group>FunctionTypeCrudConfig` type that doesn't appear as a runtime key on the const.",
|
|
545
|
+
"whenItDoesNotApply": "Keys whose runtime entry is contributed by another file (rare — convention is to keep type + const in lockstep).",
|
|
546
|
+
"canonicalFix": "Add `<key>: [<Foo>ParamsType, <Foo>Result]` (or the bare `*Params` form) to the const."
|
|
547
|
+
},
|
|
548
|
+
{
|
|
549
|
+
"code": "DECL_AFTER_FUNCTIONS_BLOCK",
|
|
550
|
+
"source": "dbx_model_validate_api",
|
|
551
|
+
"severity": "warning",
|
|
552
|
+
"title": "A `*Params` / `*Result` declaration appears below the Functions block",
|
|
553
|
+
"whatItFlags": "A `*Params` / `*Result` declaration appears below the Functions block.",
|
|
554
|
+
"whenItApplies": "When a params or result declaration's line number falls after the first Functions-block declaration.",
|
|
555
|
+
"whenItDoesNotApply": "Files where the declaration order is intentionally inverted for project-specific reasons.",
|
|
556
|
+
"canonicalFix": "Move the params/result declaration above the Functions block so the file reads top-down: types → validators → Functions."
|
|
557
|
+
},
|
|
558
|
+
{
|
|
559
|
+
"code": "FILE_GROUP_NAME_INCONSISTENT",
|
|
560
|
+
"source": "dbx_model_validate_api",
|
|
561
|
+
"severity": "error",
|
|
562
|
+
"title": "The Functions block declarations don't all share the same `<group>` prefix",
|
|
563
|
+
"whatItFlags": "The Functions block declarations don't all share the same `<group>` prefix.",
|
|
564
|
+
"whenItApplies": "When the inferred group name on the type map, config map, CRUD type/const, function map, or class differs from the file's primary group.",
|
|
565
|
+
"whenItDoesNotApply": "Files where the prefix mismatch is intentional (rare — convention requires consistent naming).",
|
|
566
|
+
"canonicalFix": "Rename the divergent declaration so every Functions-block export shares the same `<group>` prefix."
|
|
567
|
+
},
|
|
568
|
+
{
|
|
569
|
+
"code": "FILE_MISSING_CRUD_CONFIG_CONST",
|
|
570
|
+
"source": "dbx_model_validate_api",
|
|
571
|
+
"severity": "error",
|
|
572
|
+
"title": "`<group>FunctionTypeCrudConfig` constant is missing from the file",
|
|
573
|
+
"whatItFlags": "`<group>FunctionTypeCrudConfig` constant is missing from the file.",
|
|
574
|
+
"whenItApplies": "Every `<model>.api.ts` file with a Functions block.",
|
|
575
|
+
"whenItDoesNotApply": "Non-CRUD api filenames listed in `NON_CRUD_API_BASENAMES`.",
|
|
576
|
+
"canonicalFix": "Add `export const <group>FunctionTypeCrudConfig: <Group>FunctionTypeCrudConfig = { ... };` mapping each CRUD key to its `[Params, Result]` tuple or `null`."
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
"code": "FILE_MISSING_CRUD_CONFIG_TYPE",
|
|
580
|
+
"source": "dbx_model_validate_api",
|
|
581
|
+
"severity": "error",
|
|
582
|
+
"title": "`<Group>FunctionTypeCrudConfig` type alias is missing from the file",
|
|
583
|
+
"whatItFlags": "`<Group>FunctionTypeCrudConfig` type alias is missing from the file.",
|
|
584
|
+
"whenItApplies": "Every `<model>.api.ts` file with a Functions block.",
|
|
585
|
+
"whenItDoesNotApply": "Non-CRUD api filenames listed in `NON_CRUD_API_BASENAMES`.",
|
|
586
|
+
"canonicalFix": "Add `export type <Group>FunctionTypeCrudConfig = ModelFirebaseCrudFunctionConfigMap<<Group>FunctionTypeMap>;` to bind the CRUD shape to the type map."
|
|
587
|
+
},
|
|
588
|
+
{
|
|
589
|
+
"code": "FILE_MISSING_FUNCTION_MAP",
|
|
590
|
+
"source": "dbx_model_validate_api",
|
|
591
|
+
"severity": "error",
|
|
592
|
+
"title": "`<group>FunctionMap` constant is missing from the file",
|
|
593
|
+
"whatItFlags": "`<group>FunctionMap` constant is missing from the file.",
|
|
594
|
+
"whenItApplies": "Every `<model>.api.ts` file with a Functions block.",
|
|
595
|
+
"whenItDoesNotApply": "Non-CRUD api filenames listed in `NON_CRUD_API_BASENAMES`.",
|
|
596
|
+
"canonicalFix": "Add `export const <group>FunctionMap = callModelFirebaseFunctionMapFactory(<group>FunctionTypeConfigMap, <group>FunctionTypeCrudConfig);` to wire the runtime call map."
|
|
597
|
+
},
|
|
598
|
+
{
|
|
599
|
+
"code": "FILE_MISSING_FUNCTION_TYPE_CONFIG_MAP",
|
|
600
|
+
"source": "dbx_model_validate_api",
|
|
601
|
+
"severity": "error",
|
|
602
|
+
"title": "`<group>FunctionTypeConfigMap` constant is missing from the file",
|
|
603
|
+
"whatItFlags": "`<group>FunctionTypeConfigMap` constant is missing from the file.",
|
|
604
|
+
"whenItApplies": "Every `<model>.api.ts` file with a Functions block.",
|
|
605
|
+
"whenItDoesNotApply": "Non-CRUD api filenames listed in `NON_CRUD_API_BASENAMES`.",
|
|
606
|
+
"canonicalFix": "Add `export const <group>FunctionTypeConfigMap: ModelFirebaseFunctionMapTypeConfigMap<<Group>FunctionTypeMap> = { ... };` aligned with the type-map keys.",
|
|
607
|
+
"seeAlso": [
|
|
608
|
+
{
|
|
609
|
+
"kind": "doc",
|
|
610
|
+
"target": "dbx__guide__call-model-api"
|
|
611
|
+
}
|
|
612
|
+
]
|
|
613
|
+
},
|
|
614
|
+
{
|
|
615
|
+
"code": "FILE_MISSING_FUNCTION_TYPE_MAP",
|
|
616
|
+
"source": "dbx_model_validate_api",
|
|
617
|
+
"severity": "error",
|
|
618
|
+
"title": "`<group>FunctionTypeMap` type alias is missing from the file",
|
|
619
|
+
"whatItFlags": "`<group>FunctionTypeMap` type alias is missing from the file.",
|
|
620
|
+
"whenItApplies": "Every `<model>.api.ts` file (other than the non-CRUD basenames listed in `NON_CRUD_API_BASENAMES`).",
|
|
621
|
+
"whenItDoesNotApply": "Files matching a `NON_CRUD_API_BASENAMES` entry (e.g. `development.api.ts`) — those short-circuit structural checks.",
|
|
622
|
+
"canonicalFix": "Add `export type <Group>FunctionTypeMap = { /* keys *\\/ };` at the top of the Functions block.",
|
|
623
|
+
"seeAlso": [
|
|
624
|
+
{
|
|
625
|
+
"kind": "doc",
|
|
626
|
+
"target": "dbx__guide__call-model-api"
|
|
627
|
+
}
|
|
628
|
+
]
|
|
629
|
+
},
|
|
630
|
+
{
|
|
631
|
+
"code": "FILE_MISSING_FUNCTIONS_CLASS",
|
|
632
|
+
"source": "dbx_model_validate_api",
|
|
633
|
+
"severity": "error",
|
|
634
|
+
"title": "`<Group>Functions` abstract class is missing from the file",
|
|
635
|
+
"whatItFlags": "`<Group>Functions` abstract class is missing from the file.",
|
|
636
|
+
"whenItApplies": "Every `<model>.api.ts` file with a Functions block.",
|
|
637
|
+
"whenItDoesNotApply": "Non-CRUD api filenames listed in `NON_CRUD_API_BASENAMES`.",
|
|
638
|
+
"canonicalFix": "Add `export abstract class <Group>Functions implements ModelFirebaseFunctionsConfigMap<<Group>FunctionTypeMap, <Group>FunctionTypeCrudConfig> { ... }` with one abstract member per non-null CRUD key."
|
|
639
|
+
},
|
|
640
|
+
{
|
|
641
|
+
"code": "FILE_MISSING_MARK_CONSTANTS",
|
|
642
|
+
"source": "dbx_model_validate_api",
|
|
643
|
+
"severity": "warning",
|
|
644
|
+
"title": "The file is missing the `// MARK: Constants` (or equivalent) section comment",
|
|
645
|
+
"whatItFlags": "The file is missing the `// MARK: Constants` (or equivalent) section comment.",
|
|
646
|
+
"whenItApplies": "Every CRUD api file expected to declare top-level constants alongside the params/results.",
|
|
647
|
+
"whenItDoesNotApply": "Files with no top-level constants — the marker is purely organizational.",
|
|
648
|
+
"canonicalFix": "Add a `// MARK: Constants` comment above the constants region so navigation and folding work consistently."
|
|
649
|
+
},
|
|
650
|
+
{
|
|
651
|
+
"code": "FILE_MISSING_MARK_FUNCTIONS",
|
|
652
|
+
"source": "dbx_model_validate_api",
|
|
653
|
+
"severity": "warning",
|
|
654
|
+
"title": "The file is missing the `// MARK: Functions` section comment above the Functions block",
|
|
655
|
+
"whatItFlags": "The file is missing the `// MARK: Functions` section comment above the Functions block.",
|
|
656
|
+
"whenItApplies": "Every CRUD api file with a Functions block.",
|
|
657
|
+
"whenItDoesNotApply": "Files matching `NON_CRUD_API_BASENAMES` (no Functions block expected).",
|
|
658
|
+
"canonicalFix": "Add a `// MARK: Functions` comment immediately above the Functions block so the file's top-down structure stays scannable."
|
|
659
|
+
},
|
|
660
|
+
{
|
|
661
|
+
"code": "FILE_MISSING_MARK_KEYS",
|
|
662
|
+
"source": "dbx_model_validate_api",
|
|
663
|
+
"severity": "warning",
|
|
664
|
+
"title": "The file is missing the `// MARK: Keys` section comment",
|
|
665
|
+
"whatItFlags": "The file is missing the `// MARK: Keys` section comment.",
|
|
666
|
+
"whenItApplies": "Every CRUD api file expected to declare key types alongside the params/results.",
|
|
667
|
+
"whenItDoesNotApply": "Files with no key declarations — the marker is purely organizational.",
|
|
668
|
+
"canonicalFix": "Add a `// MARK: Keys` comment above the keys region so navigation and folding work consistently."
|
|
669
|
+
},
|
|
670
|
+
{
|
|
671
|
+
"code": "FILE_NOT_EXPORTED",
|
|
672
|
+
"source": "dbx_model_validate_api",
|
|
673
|
+
"severity": "error",
|
|
674
|
+
"title": "A required Functions-block declaration exists but isn't `export`ed",
|
|
675
|
+
"whatItFlags": "A required Functions-block declaration exists but isn't `export`ed.",
|
|
676
|
+
"whenItApplies": "Any of the six Functions-block exports declared without the `export` keyword.",
|
|
677
|
+
"whenItDoesNotApply": "No known false-positive cases — the call map / class are consumed across packages and must be exported.",
|
|
678
|
+
"canonicalFix": "Add the `export` keyword to the declaration."
|
|
679
|
+
},
|
|
680
|
+
{
|
|
681
|
+
"code": "FUNCTION_MAP_BAD_FACTORY_ARGS",
|
|
682
|
+
"source": "dbx_model_validate_api",
|
|
683
|
+
"severity": "error",
|
|
684
|
+
"title": "`<group>FunctionMap = callModelFirebaseFunctionMapFactory(...)` was called with the wrong argument identifiers",
|
|
685
|
+
"whatItFlags": "`<group>FunctionMap = callModelFirebaseFunctionMapFactory(...)` was called with the wrong argument identifiers.",
|
|
686
|
+
"whenItApplies": "When the factory call's two argument identifiers don't match `<group>FunctionTypeConfigMap` and `<group>FunctionTypeCrudConfig` (in that order).",
|
|
687
|
+
"whenItDoesNotApply": "No known false-positive cases — the factory must be passed the file's own config + crud-config consts.",
|
|
688
|
+
"canonicalFix": "Pass `<group>FunctionTypeConfigMap` first and `<group>FunctionTypeCrudConfig` second, matching the local declarations."
|
|
689
|
+
},
|
|
690
|
+
{
|
|
691
|
+
"code": "FUNCTIONS_BLOCK_OUT_OF_ORDER",
|
|
692
|
+
"source": "dbx_model_validate_api",
|
|
693
|
+
"severity": "warning",
|
|
694
|
+
"title": "The Functions-block declarations aren't in canonical order",
|
|
695
|
+
"whatItFlags": "The Functions-block declarations aren't in canonical order.",
|
|
696
|
+
"whenItApplies": "When the actual on-disk order of `functionTypeMap` / `functionTypeConfigMap` / `crudConfigType` / `crudConfigConst` / `functionMap` / `functionsClass` doesn't match the canonical order in `FUNCTIONS_BLOCK_ORDER`.",
|
|
697
|
+
"whenItDoesNotApply": "Files where the order is intentionally different for project-specific reasons.",
|
|
698
|
+
"canonicalFix": "Reorder the Functions-block declarations to match `FUNCTIONS_BLOCK_ORDER`."
|
|
699
|
+
},
|
|
700
|
+
{
|
|
701
|
+
"code": "FUNCTIONS_CLASS_BAD_IMPLEMENTS",
|
|
702
|
+
"source": "dbx_model_validate_api",
|
|
703
|
+
"severity": "error",
|
|
704
|
+
"title": "`<Group>Functions` declares the wrong `implements` clause",
|
|
705
|
+
"whatItFlags": "`<Group>Functions` declares the wrong `implements` clause.",
|
|
706
|
+
"whenItApplies": "When the first `implements` clause text isn't `ModelFirebaseFunctionsConfigMap<<Group>FunctionTypeMap, <Group>FunctionTypeCrudConfig>` (with the local type/const names).",
|
|
707
|
+
"whenItDoesNotApply": "No known false-positive cases — the implements clause keeps the abstract members in sync with the CRUD config.",
|
|
708
|
+
"canonicalFix": "Replace the implements clause with `ModelFirebaseFunctionsConfigMap<<Group>FunctionTypeMap, <Group>FunctionTypeCrudConfig>`."
|
|
709
|
+
},
|
|
710
|
+
{
|
|
711
|
+
"code": "FUNCTIONS_CLASS_NOT_ABSTRACT",
|
|
712
|
+
"source": "dbx_model_validate_api",
|
|
713
|
+
"severity": "error",
|
|
714
|
+
"title": "`<Group>Functions` is declared as `class` rather than `abstract class`",
|
|
715
|
+
"whatItFlags": "`<Group>Functions` is declared as `class` rather than `abstract class`.",
|
|
716
|
+
"whenItApplies": "When the class declaration is missing the `abstract` modifier.",
|
|
717
|
+
"whenItDoesNotApply": "No known false-positive cases — the Functions class is implemented downstream by the API app.",
|
|
718
|
+
"canonicalFix": "Add the `abstract` modifier so concrete CRUD members are bound by the consuming `*ServerActions` class."
|
|
719
|
+
},
|
|
720
|
+
{
|
|
721
|
+
"code": "NON_CRUD_API_FILENAME",
|
|
722
|
+
"source": "dbx_model_validate_api",
|
|
723
|
+
"severity": "warning",
|
|
724
|
+
"title": "A `.api.ts` file follows the naming convention but is not a CRUD model api",
|
|
725
|
+
"whatItFlags": "A `.api.ts` file follows the naming convention but is not a CRUD model api.",
|
|
726
|
+
"whenItApplies": "Files whose basename appears in `NON_CRUD_API_BASENAMES` (e.g. `development.api.ts`).",
|
|
727
|
+
"whenItDoesNotApply": "CRUD-style api files — those run the full structural pass.",
|
|
728
|
+
"canonicalFix": "Either rename the file (drop `.api.ts`) or accept the warning — structural checks are intentionally short-circuited."
|
|
729
|
+
},
|
|
730
|
+
{
|
|
731
|
+
"code": "PARAMS_FIELD_NOT_READONLY",
|
|
732
|
+
"source": "dbx_model_validate_api",
|
|
733
|
+
"severity": "warning",
|
|
734
|
+
"title": "A field on a `*Params` interface is missing the `readonly` modifier",
|
|
735
|
+
"whatItFlags": "A field on a `*Params` interface is missing the `readonly` modifier.",
|
|
736
|
+
"whenItApplies": "Every property on a `*Params` interface (type aliases are skipped).",
|
|
737
|
+
"whenItDoesNotApply": "Fields whose type system needs mutability (rare — params are immutable by convention).",
|
|
738
|
+
"canonicalFix": "Add `readonly` to the property so the params shape stays immutable.",
|
|
739
|
+
"seeAlso": [
|
|
740
|
+
{
|
|
741
|
+
"kind": "doc",
|
|
742
|
+
"target": "dbx__note__typescript-programming"
|
|
743
|
+
}
|
|
744
|
+
]
|
|
745
|
+
},
|
|
746
|
+
{
|
|
747
|
+
"code": "PARAMS_MAYBE_WITHOUT_CLEARABLE",
|
|
748
|
+
"source": "dbx_model_validate_api",
|
|
749
|
+
"severity": "warning",
|
|
750
|
+
"title": "A `*ParamsType` validator declares a `Maybe<...>` field without `clearable(...)`",
|
|
751
|
+
"whatItFlags": "A `*ParamsType` validator declares a `Maybe<...>` field without `clearable(...)`.",
|
|
752
|
+
"whenItApplies": "When the params interface field is wrapped in `Maybe<T>` but the validator's matching property doesn't call `clearable(...)`.",
|
|
753
|
+
"whenItDoesNotApply": "Fields that intentionally accept `null` / `undefined` without the clearable wrapper (rare — convention is to use `clearable`).",
|
|
754
|
+
"canonicalFix": "Wrap the validator property's value with `clearable(...)` so optional / clearable fields decode correctly at runtime."
|
|
755
|
+
},
|
|
756
|
+
{
|
|
757
|
+
"code": "PARAMS_MISSING_VALIDATOR",
|
|
758
|
+
"source": "dbx_model_validate_api",
|
|
759
|
+
"severity": "error",
|
|
760
|
+
"title": "A `*Params` interface has no matching `*ParamsType` Arktype validator",
|
|
761
|
+
"whatItFlags": "A `*Params` interface has no matching `*ParamsType` Arktype validator.",
|
|
762
|
+
"whenItApplies": "Every `*Params` declaration referenced by the CRUD config.",
|
|
763
|
+
"whenItDoesNotApply": "Params that are intentionally unvalidated (rare — every public CRUD entry needs a runtime validator).",
|
|
764
|
+
"canonicalFix": "Add `export const <foo>ParamsType = type({ ... }) as unknown as RuntimeTypeValidator<<Foo>Params>;` adjacent to the interface.",
|
|
765
|
+
"seeAlso": [
|
|
766
|
+
{
|
|
767
|
+
"kind": "doc",
|
|
768
|
+
"target": "dbx__guide__call-model-api"
|
|
769
|
+
}
|
|
770
|
+
]
|
|
771
|
+
},
|
|
772
|
+
{
|
|
773
|
+
"code": "PARAMS_NOT_EXPORTED",
|
|
774
|
+
"source": "dbx_model_validate_api",
|
|
775
|
+
"severity": "error",
|
|
776
|
+
"title": "A `*Params` declaration exists but isn't `export`ed",
|
|
777
|
+
"whatItFlags": "A `*Params` declaration exists but isn't `export`ed.",
|
|
778
|
+
"whenItApplies": "Any `*Params` interface or type alias declared without the `export` keyword.",
|
|
779
|
+
"whenItDoesNotApply": "Internal helper params that aren't part of the CRUD config (rare — most params are referenced by the call map).",
|
|
780
|
+
"canonicalFix": "Add the `export` keyword so the params can be referenced by downstream packages and the validator's cast."
|
|
781
|
+
},
|
|
782
|
+
{
|
|
783
|
+
"code": "PARAMS_VALIDATOR_NOT_ADJACENT",
|
|
784
|
+
"source": "dbx_model_validate_api",
|
|
785
|
+
"severity": "warning",
|
|
786
|
+
"title": "A `*ParamsType` validator isn't declared adjacent to its `*Params` interface",
|
|
787
|
+
"whatItFlags": "A `*ParamsType` validator isn't declared adjacent to its `*Params` interface.",
|
|
788
|
+
"whenItApplies": "When the validator and its params interface are separated by another top-level declaration.",
|
|
789
|
+
"whenItDoesNotApply": "Files where the validator must live in a different region for project-specific reasons.",
|
|
790
|
+
"canonicalFix": "Move the validator immediately after its params interface so the pair stays grouped."
|
|
791
|
+
},
|
|
792
|
+
{
|
|
793
|
+
"code": "PARAMS_VALIDATOR_NOT_EXPORTED",
|
|
794
|
+
"source": "dbx_model_validate_api",
|
|
795
|
+
"severity": "error",
|
|
796
|
+
"title": "A `*ParamsType` validator declaration exists but isn't `export`ed",
|
|
797
|
+
"whatItFlags": "A `*ParamsType` validator declaration exists but isn't `export`ed.",
|
|
798
|
+
"whenItApplies": "Any `*ParamsType` constant declared without the `export` keyword.",
|
|
799
|
+
"whenItDoesNotApply": "No known false-positive cases — validators are consumed by the runtime CRUD wiring.",
|
|
800
|
+
"canonicalFix": "Add the `export` keyword so the validator can be referenced by the runtime wiring."
|
|
801
|
+
},
|
|
802
|
+
{
|
|
803
|
+
"code": "PARAMS_VALIDATOR_WRONG_CAST",
|
|
804
|
+
"source": "dbx_model_validate_api",
|
|
805
|
+
"severity": "error",
|
|
806
|
+
"title": "A `*ParamsType` validator is cast to the wrong target type",
|
|
807
|
+
"whatItFlags": "A `*ParamsType` validator is cast to the wrong target type.",
|
|
808
|
+
"whenItApplies": "When the validator's `as ... <Type>` cast doesn't reference the matching `*Params` interface.",
|
|
809
|
+
"whenItDoesNotApply": "No known false-positive cases — the cast is what links the validator to the params interface at the type level.",
|
|
810
|
+
"canonicalFix": "Cast the validator to `RuntimeTypeValidator<<Foo>Params>` (or `as unknown as RuntimeTypeValidator<<Foo>Params>`) so the CRUD config infers the right shape."
|
|
811
|
+
},
|
|
812
|
+
{
|
|
813
|
+
"code": "RESULT_FIELD_NOT_READONLY",
|
|
814
|
+
"source": "dbx_model_validate_api",
|
|
815
|
+
"severity": "warning",
|
|
816
|
+
"title": "A field on a `*Result` interface is missing the `readonly` modifier",
|
|
817
|
+
"whatItFlags": "A field on a `*Result` interface is missing the `readonly` modifier.",
|
|
818
|
+
"whenItApplies": "Every property on a `*Result` interface (type aliases are skipped).",
|
|
819
|
+
"whenItDoesNotApply": "Fields whose type system needs mutability (rare — results are immutable by convention).",
|
|
820
|
+
"canonicalFix": "Add `readonly` to the property so the result shape stays immutable.",
|
|
821
|
+
"seeAlso": [
|
|
822
|
+
{
|
|
823
|
+
"kind": "doc",
|
|
824
|
+
"target": "dbx__note__typescript-programming"
|
|
825
|
+
}
|
|
826
|
+
]
|
|
827
|
+
},
|
|
828
|
+
{
|
|
829
|
+
"code": "TYPE_CONFIG_MAP_WRONG_GENERIC",
|
|
830
|
+
"source": "dbx_model_validate_api",
|
|
831
|
+
"severity": "error",
|
|
832
|
+
"title": "`<group>FunctionTypeConfigMap` is annotated with the wrong generic argument",
|
|
833
|
+
"whatItFlags": "`<group>FunctionTypeConfigMap` is annotated with the wrong generic argument.",
|
|
834
|
+
"whenItApplies": "When the type annotation isn't `ModelFirebaseFunctionMapTypeConfigMap<<Group>FunctionTypeMap>`.",
|
|
835
|
+
"whenItDoesNotApply": "No known false-positive cases — the generic ties the config map to the type map by design.",
|
|
836
|
+
"canonicalFix": "Set the annotation to `ModelFirebaseFunctionMapTypeConfigMap<<Group>FunctionTypeMap>` matching the file's type-map name."
|
|
837
|
+
},
|
|
838
|
+
{
|
|
839
|
+
"code": "FOLDER_MISSING_ACTION",
|
|
840
|
+
"source": "dbx_model_validate_folder",
|
|
841
|
+
"severity": "error",
|
|
842
|
+
"title": "Required `<name>.action.ts` server-actions module is missing",
|
|
843
|
+
"whatItFlags": "Required `<name>.action.ts` server-actions module is missing.",
|
|
844
|
+
"whenItApplies": "Every canonical model folder.",
|
|
845
|
+
"whenItDoesNotApply": "Reserved folders that don't follow the 5-file convention.",
|
|
846
|
+
"canonicalFix": "Add `<name>.action.ts` declaring the abstract `<Model>ServerActions` class plus the action-context interface.",
|
|
847
|
+
"seeAlso": [
|
|
848
|
+
{
|
|
849
|
+
"kind": "artifact",
|
|
850
|
+
"target": "firestore-model"
|
|
851
|
+
}
|
|
852
|
+
]
|
|
853
|
+
},
|
|
854
|
+
{
|
|
855
|
+
"code": "FOLDER_MISSING_API",
|
|
856
|
+
"source": "dbx_model_validate_folder",
|
|
857
|
+
"severity": "error",
|
|
858
|
+
"title": "Required `<name>.api.ts` CRUD api module is missing",
|
|
859
|
+
"whatItFlags": "Required `<name>.api.ts` CRUD api module is missing.",
|
|
860
|
+
"whenItApplies": "Every canonical model folder.",
|
|
861
|
+
"whenItDoesNotApply": "Reserved folders that don't follow the 5-file convention.",
|
|
862
|
+
"canonicalFix": "Add `<name>.api.ts` declaring the params/result interfaces, validators, and Functions block.",
|
|
863
|
+
"seeAlso": [
|
|
864
|
+
{
|
|
865
|
+
"kind": "tool",
|
|
866
|
+
"target": "dbx_model_validate_api"
|
|
867
|
+
}
|
|
868
|
+
]
|
|
869
|
+
},
|
|
870
|
+
{
|
|
871
|
+
"code": "FOLDER_MISSING_ID",
|
|
872
|
+
"source": "dbx_model_validate_folder",
|
|
873
|
+
"severity": "error",
|
|
874
|
+
"title": "Required `<name>.id.ts` id-types module is missing",
|
|
875
|
+
"whatItFlags": "Required `<name>.id.ts` id-types module is missing.",
|
|
876
|
+
"whenItApplies": "Every canonical model folder.",
|
|
877
|
+
"whenItDoesNotApply": "Reserved folders that don't follow the 5-file convention.",
|
|
878
|
+
"canonicalFix": "Add `<name>.id.ts` exporting the model's id alias types and any composite-key helpers.",
|
|
879
|
+
"seeAlso": [
|
|
880
|
+
{
|
|
881
|
+
"kind": "artifact",
|
|
882
|
+
"target": "firestore-model"
|
|
883
|
+
}
|
|
884
|
+
]
|
|
885
|
+
},
|
|
886
|
+
{
|
|
887
|
+
"code": "FOLDER_MISSING_INDEX",
|
|
888
|
+
"source": "dbx_model_validate_folder",
|
|
889
|
+
"severity": "error",
|
|
890
|
+
"title": "Required `index.ts` barrel is missing",
|
|
891
|
+
"whatItFlags": "Required `index.ts` barrel is missing.",
|
|
892
|
+
"whenItApplies": "Every canonical model folder.",
|
|
893
|
+
"whenItDoesNotApply": "Reserved folders that don't follow the 5-file convention.",
|
|
894
|
+
"canonicalFix": "Add `index.ts` re-exporting every sibling `<name>.*.ts` module so the folder is consumed through one barrel."
|
|
895
|
+
},
|
|
896
|
+
{
|
|
897
|
+
"code": "FOLDER_MISSING_MAIN",
|
|
898
|
+
"source": "dbx_model_validate_folder",
|
|
899
|
+
"severity": "error",
|
|
900
|
+
"title": "Required `<name>.ts` main module is missing from the model folder",
|
|
901
|
+
"whatItFlags": "Required `<name>.ts` main module is missing from the model folder.",
|
|
902
|
+
"whenItApplies": "Every canonical model folder anchored on its folder basename.",
|
|
903
|
+
"whenItDoesNotApply": "Reserved folders (`system`, `notification`, `storagefile`) — they have a different layout and surface a separate `RESERVED_MODEL_FOLDER` warning instead.",
|
|
904
|
+
"canonicalFix": "Add `<name>.ts` containing the model's `firestoreModelIdentity`, interface, document class, converter, and collection wiring.",
|
|
905
|
+
"seeAlso": [
|
|
906
|
+
{
|
|
907
|
+
"kind": "artifact",
|
|
908
|
+
"target": "firestore-model"
|
|
909
|
+
}
|
|
910
|
+
]
|
|
911
|
+
},
|
|
912
|
+
{
|
|
913
|
+
"code": "FOLDER_MISSING_QUERY",
|
|
914
|
+
"source": "dbx_model_validate_folder",
|
|
915
|
+
"severity": "error",
|
|
916
|
+
"title": "Required `<name>.query.ts` query-helpers module is missing",
|
|
917
|
+
"whatItFlags": "Required `<name>.query.ts` query-helpers module is missing.",
|
|
918
|
+
"whenItApplies": "Every canonical model folder.",
|
|
919
|
+
"whenItDoesNotApply": "Reserved folders that don't follow the 5-file convention.",
|
|
920
|
+
"canonicalFix": "Add `<name>.query.ts` with the model's query-builder helpers.",
|
|
921
|
+
"seeAlso": [
|
|
922
|
+
{
|
|
923
|
+
"kind": "artifact",
|
|
924
|
+
"target": "firestore-model"
|
|
925
|
+
}
|
|
926
|
+
]
|
|
927
|
+
},
|
|
928
|
+
{
|
|
929
|
+
"code": "FOLDER_NOT_DIRECTORY",
|
|
930
|
+
"source": "dbx_model_validate_folder",
|
|
931
|
+
"severity": "error",
|
|
932
|
+
"title": "The path resolves to a file or other non-directory entry",
|
|
933
|
+
"whatItFlags": "The path resolves to a file or other non-directory entry.",
|
|
934
|
+
"whenItApplies": "Validating a path that exists but is not a directory.",
|
|
935
|
+
"whenItDoesNotApply": "File-level model validation — use `dbx_model_validate` for `.ts` source files.",
|
|
936
|
+
"canonicalFix": "Pass the model folder (e.g. `apps/.../src/lib/model/profile/`), not the `<name>.ts` file inside it."
|
|
937
|
+
},
|
|
938
|
+
{
|
|
939
|
+
"code": "FOLDER_NOT_FOUND",
|
|
940
|
+
"source": "dbx_model_validate_folder",
|
|
941
|
+
"severity": "error",
|
|
942
|
+
"title": "Folder does not exist on disk",
|
|
943
|
+
"whatItFlags": "Folder does not exist on disk.",
|
|
944
|
+
"whenItApplies": "Validating a folder path that doesn't resolve to a directory entry.",
|
|
945
|
+
"whenItDoesNotApply": "Glob patterns that intentionally match zero folders — pass at least one valid path.",
|
|
946
|
+
"canonicalFix": "Verify the path argument is a real folder under the workspace.",
|
|
947
|
+
"seeAlso": [
|
|
948
|
+
{
|
|
949
|
+
"kind": "tool",
|
|
950
|
+
"target": "dbx_model_validate_folder"
|
|
951
|
+
}
|
|
952
|
+
]
|
|
953
|
+
},
|
|
954
|
+
{
|
|
955
|
+
"code": "FOLDER_STRAY_FILE",
|
|
956
|
+
"source": "dbx_model_validate_folder",
|
|
957
|
+
"severity": "warning",
|
|
958
|
+
"title": "A `.ts` file in the folder doesn't start with the folder's `<name>.` prefix",
|
|
959
|
+
"whatItFlags": "A `.ts` file in the folder doesn't start with the folder's `<name>.` prefix.",
|
|
960
|
+
"whenItApplies": "Any `.ts` file that is not `index.ts` and is not prefixed with `<folder-name>.`.",
|
|
961
|
+
"whenItDoesNotApply": "Files outside the canonical layout that the project intentionally hosts here (rare — prefer moving them out).",
|
|
962
|
+
"canonicalFix": "Rename the file to `<folder-name>.<sub>.ts` so it stays grouped, or move it out of the model folder."
|
|
963
|
+
},
|
|
964
|
+
{
|
|
965
|
+
"code": "RESERVED_MODEL_FOLDER",
|
|
966
|
+
"source": "dbx_model_validate_folder",
|
|
967
|
+
"severity": "warning",
|
|
968
|
+
"title": "The folder name matches a reserved group (system / notification / storagefile)",
|
|
969
|
+
"whatItFlags": "The folder name matches a reserved group (system / notification / storagefile)\nthat follows a distinct layout. Validation skips it and points at the\ndedicated tool.",
|
|
970
|
+
"whenItApplies": "Folders named `system`, `notification`, or `storagefile`.",
|
|
971
|
+
"whenItDoesNotApply": "Custom downstream folders that happen to share a substring — match is exact.",
|
|
972
|
+
"canonicalFix": "Re-run validation with the recommended tool from the violation's message (e.g. `dbx_system_m_validate_folder`).",
|
|
973
|
+
"seeAlso": [
|
|
974
|
+
{
|
|
975
|
+
"kind": "tool",
|
|
976
|
+
"target": "dbx_system_m_validate_folder"
|
|
977
|
+
},
|
|
978
|
+
{
|
|
979
|
+
"kind": "tool",
|
|
980
|
+
"target": "dbx_notification_m_validate_folder"
|
|
981
|
+
},
|
|
982
|
+
{
|
|
983
|
+
"kind": "tool",
|
|
984
|
+
"target": "dbx_storagefile_m_validate_folder"
|
|
985
|
+
}
|
|
986
|
+
]
|
|
987
|
+
},
|
|
988
|
+
{
|
|
989
|
+
"code": "NOTIF_API_DIR_NOT_FOUND",
|
|
990
|
+
"source": "dbx_notification_m_validate_app",
|
|
991
|
+
"severity": "error",
|
|
992
|
+
"title": "The API app directory does not exist on disk",
|
|
993
|
+
"whatItFlags": "The API app directory does not exist on disk.",
|
|
994
|
+
"whenItApplies": "When the supplied `apiDir` does not resolve to a directory entry.",
|
|
995
|
+
"whenItDoesNotApply": "API apps intentionally not validated — pass `--skip notification_m` instead.",
|
|
996
|
+
"canonicalFix": "Verify the path argument resolves to an existing API app root.",
|
|
997
|
+
"seeAlso": [
|
|
998
|
+
{
|
|
999
|
+
"kind": "tool",
|
|
1000
|
+
"target": "dbx_notification_m_validate_folder"
|
|
1001
|
+
}
|
|
1002
|
+
]
|
|
1003
|
+
},
|
|
1004
|
+
{
|
|
1005
|
+
"code": "NOTIF_API_NOTIFICATION_FOLDER_MISSING",
|
|
1006
|
+
"source": "dbx_notification_m_validate_app",
|
|
1007
|
+
"severity": "error",
|
|
1008
|
+
"title": "The API root exists but `src/app/common/model/notification/` is missing",
|
|
1009
|
+
"whatItFlags": "The API root exists but `src/app/common/model/notification/` is missing.",
|
|
1010
|
+
"whenItApplies": "API apps expected to wire the notification module but with no notification folder.",
|
|
1011
|
+
"whenItDoesNotApply": "API apps that intentionally don't wire notifications — pass `--skip notification_m`.",
|
|
1012
|
+
"canonicalFix": "Add `src/app/common/model/notification/` with `notification.module.ts`, `notification.task.service.ts`, and `notification.send.service.ts`.",
|
|
1013
|
+
"seeAlso": [
|
|
1014
|
+
{
|
|
1015
|
+
"kind": "artifact",
|
|
1016
|
+
"target": "notification-template"
|
|
1017
|
+
}
|
|
1018
|
+
]
|
|
1019
|
+
},
|
|
1020
|
+
{
|
|
1021
|
+
"code": "NOTIF_COMPONENT_DIR_NOT_FOUND",
|
|
1022
|
+
"source": "dbx_notification_m_validate_app",
|
|
1023
|
+
"severity": "error",
|
|
1024
|
+
"title": "The component package directory does not exist on disk",
|
|
1025
|
+
"whatItFlags": "The component package directory does not exist on disk.",
|
|
1026
|
+
"whenItApplies": "When the supplied `componentDir` does not resolve to a directory entry.",
|
|
1027
|
+
"whenItDoesNotApply": "Components intentionally not part of this validation pass — pass `--skip notification_m` to `dbx_app_validate` instead.",
|
|
1028
|
+
"canonicalFix": "Verify the path argument resolves to an existing component package root.",
|
|
1029
|
+
"seeAlso": [
|
|
1030
|
+
{
|
|
1031
|
+
"kind": "tool",
|
|
1032
|
+
"target": "dbx_notification_m_validate_folder"
|
|
1033
|
+
}
|
|
1034
|
+
]
|
|
1035
|
+
},
|
|
1036
|
+
{
|
|
1037
|
+
"code": "NOTIF_COMPONENT_NOTIFICATION_FOLDER_MISSING",
|
|
1038
|
+
"source": "dbx_notification_m_validate_app",
|
|
1039
|
+
"severity": "error",
|
|
1040
|
+
"title": "The component root exists but `src/lib/model/notification/` is missing",
|
|
1041
|
+
"whatItFlags": "The component root exists but `src/lib/model/notification/` is missing.",
|
|
1042
|
+
"whenItApplies": "Components that should ship template / task constants but lack the notification model folder.",
|
|
1043
|
+
"whenItDoesNotApply": "Components that intentionally don't extend the notification group.",
|
|
1044
|
+
"canonicalFix": "Add `src/lib/model/notification/notification.ts` and the rest of the notification artefacts.",
|
|
1045
|
+
"seeAlso": [
|
|
1046
|
+
{
|
|
1047
|
+
"kind": "artifact",
|
|
1048
|
+
"target": "notification-template"
|
|
1049
|
+
},
|
|
1050
|
+
{
|
|
1051
|
+
"kind": "artifact",
|
|
1052
|
+
"target": "notification-task"
|
|
1053
|
+
}
|
|
1054
|
+
]
|
|
1055
|
+
},
|
|
1056
|
+
{
|
|
1057
|
+
"code": "NOTIF_TASK_HANDLER_NAME_MISMATCH",
|
|
1058
|
+
"source": "dbx_notification_m_validate_app",
|
|
1059
|
+
"severity": "error",
|
|
1060
|
+
"title": "A `NotificationTaskServiceTaskHandlerConfig`'s binding name doesn't match its handler-array reference",
|
|
1061
|
+
"whatItFlags": "A `NotificationTaskServiceTaskHandlerConfig`'s binding name doesn't match its handler-array reference.",
|
|
1062
|
+
"whenItApplies": "When the handler is bound to a typed const but the local-variable name diverges from the array element name in `notificationTaskService({ handlers })`.",
|
|
1063
|
+
"whenItDoesNotApply": "Inline / anonymous handler literals (no binding name to check against).",
|
|
1064
|
+
"canonicalFix": "Rename the binding to match the handler-array element, or update the array reference to match the binding."
|
|
1065
|
+
},
|
|
1066
|
+
{
|
|
1067
|
+
"code": "NOTIF_TASK_HANDLER_ORPHAN",
|
|
1068
|
+
"source": "dbx_notification_m_validate_app",
|
|
1069
|
+
"severity": "error",
|
|
1070
|
+
"title": "A `NotificationTaskServiceTaskHandlerConfig` references a `type:` identifier that is not a declared task-type constant",
|
|
1071
|
+
"whatItFlags": "A `NotificationTaskServiceTaskHandlerConfig` references a `type:` identifier that is not a declared task-type constant.",
|
|
1072
|
+
"whenItApplies": "When the handler's `type:` is an identifier outside the component's declared constants and the trust list.",
|
|
1073
|
+
"whenItDoesNotApply": "Handler configs whose `type:` is imported from a trust-listed module.",
|
|
1074
|
+
"canonicalFix": "Either declare the matching task-type constant or remove the orphaned handler config."
|
|
1075
|
+
},
|
|
1076
|
+
{
|
|
1077
|
+
"code": "NOTIF_TASK_HANDLER_SPREAD_UNRESOLVED",
|
|
1078
|
+
"source": "dbx_notification_m_validate_app",
|
|
1079
|
+
"severity": "warning",
|
|
1080
|
+
"title": "The `handlers:` array spreads an identifier that doesn't resolve to a declared array binding",
|
|
1081
|
+
"whatItFlags": "The `handlers:` array spreads an identifier that doesn't resolve to a declared array binding.",
|
|
1082
|
+
"whenItApplies": "When `notificationTaskService({ handlers: [...spread] })` spreads an identifier that isn't a typed `NotificationTaskServiceTaskHandlerConfig[]` binding or trusted external.",
|
|
1083
|
+
"whenItDoesNotApply": "Spreads from trust-listed `@dereekb/*` modules (e.g. `storageFileProcessingNotificationTaskHandler`).",
|
|
1084
|
+
"canonicalFix": "Declare the spread as `const <name>: NotificationTaskServiceTaskHandlerConfig<...>[] = [...]` or import it from a trusted module."
|
|
1085
|
+
},
|
|
1086
|
+
{
|
|
1087
|
+
"code": "NOTIF_TASK_IN_VALIDATE_WITHOUT_HANDLER",
|
|
1088
|
+
"source": "dbx_notification_m_validate_app",
|
|
1089
|
+
"severity": "warning",
|
|
1090
|
+
"title": "A task type appears in `validate:` but has no matching `handlers:` registration",
|
|
1091
|
+
"whatItFlags": "A task type appears in `validate:` but has no matching `handlers:` registration.",
|
|
1092
|
+
"whenItApplies": "When `notificationTaskService({ validate, handlers })` lists a task type in `validate:` that the `handlers:` traversal doesn't reach.",
|
|
1093
|
+
"whenItDoesNotApply": "Tasks whose handler is provided by an upstream module (covered by the trust list).",
|
|
1094
|
+
"canonicalFix": "Add the matching `NotificationTaskServiceTaskHandlerConfig` for the task and include it in `handlers:`."
|
|
1095
|
+
},
|
|
1096
|
+
{
|
|
1097
|
+
"code": "NOTIF_TASK_MULTIPLE_SERVICES",
|
|
1098
|
+
"source": "dbx_notification_m_validate_app",
|
|
1099
|
+
"severity": "warning",
|
|
1100
|
+
"title": "Multiple `notificationTaskService({ ... })` calls were found",
|
|
1101
|
+
"whatItFlags": "Multiple `notificationTaskService({ ... })` calls were found.",
|
|
1102
|
+
"whenItApplies": "When more than one task-service factory exists in the API.",
|
|
1103
|
+
"whenItDoesNotApply": "Apps that intentionally compose multiple task services (rare — only the first call's config takes effect at runtime).",
|
|
1104
|
+
"canonicalFix": "Consolidate the calls into one — the second call's handlers are unused at runtime."
|
|
1105
|
+
},
|
|
1106
|
+
{
|
|
1107
|
+
"code": "NOTIF_TASK_NOT_IN_ALL_ARRAY",
|
|
1108
|
+
"source": "dbx_notification_m_validate_app",
|
|
1109
|
+
"severity": "error",
|
|
1110
|
+
"title": "A declared `*_NOTIFICATION_TASK_TYPE` is not present in any `ALL_*_NOTIFICATION_TASK_TYPES` aggregate array",
|
|
1111
|
+
"whatItFlags": "A declared `*_NOTIFICATION_TASK_TYPE` is not present in any `ALL_*_NOTIFICATION_TASK_TYPES` aggregate array.",
|
|
1112
|
+
"whenItApplies": "Every declared task-type constant.",
|
|
1113
|
+
"whenItDoesNotApply": "Task-type constants intentionally held outside any aggregate (rare — most apps centralise the list).",
|
|
1114
|
+
"canonicalFix": "Add the constant to `ALL_<NAME>_NOTIFICATION_TASK_TYPES: NotificationTaskType[]` so the aggregate stays comprehensive."
|
|
1115
|
+
},
|
|
1116
|
+
{
|
|
1117
|
+
"code": "NOTIF_TASK_NOT_REGISTERED_IN_SERVICE",
|
|
1118
|
+
"source": "dbx_notification_m_validate_app",
|
|
1119
|
+
"severity": "error",
|
|
1120
|
+
"title": "A declared `*_NOTIFICATION_TASK_TYPE` is not reachable from any `notificationTaskService({ handlers })` call",
|
|
1121
|
+
"whatItFlags": "A declared `*_NOTIFICATION_TASK_TYPE` is not reachable from any `notificationTaskService({ handlers })` call.",
|
|
1122
|
+
"whenItApplies": "Every declared task-type constant.",
|
|
1123
|
+
"whenItDoesNotApply": "Task-type constants whose handler is provided by an upstream module (covered by the trust list).",
|
|
1124
|
+
"canonicalFix": "Add a `NotificationTaskServiceTaskHandlerConfig<...>` for the task and include its binding in `notificationTaskService({ handlers: [...] })`.",
|
|
1125
|
+
"seeAlso": [
|
|
1126
|
+
{
|
|
1127
|
+
"kind": "artifact",
|
|
1128
|
+
"target": "notification-task"
|
|
1129
|
+
},
|
|
1130
|
+
{
|
|
1131
|
+
"kind": "doc",
|
|
1132
|
+
"target": "dbx__guide__notification-task"
|
|
1133
|
+
}
|
|
1134
|
+
]
|
|
1135
|
+
},
|
|
1136
|
+
{
|
|
1137
|
+
"code": "NOTIF_TASK_SERVICE_FACTORY_MISSING",
|
|
1138
|
+
"source": "dbx_notification_m_validate_app",
|
|
1139
|
+
"severity": "error",
|
|
1140
|
+
"title": "No `notificationTaskService({ ... })` call was found in the API",
|
|
1141
|
+
"whatItFlags": "No `notificationTaskService({ ... })` call was found in the API.",
|
|
1142
|
+
"whenItApplies": "APIs that declare at least one `*_NOTIFICATION_TASK_TYPE`.",
|
|
1143
|
+
"whenItDoesNotApply": "APIs whose task service is provided by an upstream module (rare — extend the scanner's subpaths if so).",
|
|
1144
|
+
"canonicalFix": "Add `notificationTaskService({ validate: [...], handlers: [...] })` and bind it through the notification module."
|
|
1145
|
+
},
|
|
1146
|
+
{
|
|
1147
|
+
"code": "NOTIF_TASK_TYPE_CODE_DUPLICATE",
|
|
1148
|
+
"source": "dbx_notification_m_validate_app",
|
|
1149
|
+
"severity": "warning",
|
|
1150
|
+
"title": "Two `*_NOTIFICATION_TASK_TYPE` constants share the same string literal value",
|
|
1151
|
+
"whatItFlags": "Two `*_NOTIFICATION_TASK_TYPE` constants share the same string literal value.",
|
|
1152
|
+
"whenItApplies": "When more than one task-type constant resolves to the same `'<value>'` literal.",
|
|
1153
|
+
"whenItDoesNotApply": "Constants intentionally aliased — but this defeats runtime task discrimination, so almost always a copy-paste.",
|
|
1154
|
+
"canonicalFix": "Rename one of the literals so each task code is unique."
|
|
1155
|
+
},
|
|
1156
|
+
{
|
|
1157
|
+
"code": "NOTIF_TEMPLATE_FACTORY_ARRAY_MISSING",
|
|
1158
|
+
"source": "dbx_notification_m_validate_app",
|
|
1159
|
+
"severity": "error",
|
|
1160
|
+
"title": "No top-level `<app>NotificationTemplateServiceConfigsArrayFactory` was found",
|
|
1161
|
+
"whatItFlags": "No top-level `<app>NotificationTemplateServiceConfigsArrayFactory` was found.",
|
|
1162
|
+
"whenItApplies": "APIs that declare at least one `NotificationTemplateTypeInfo`.",
|
|
1163
|
+
"whenItDoesNotApply": "APIs whose configs-array factory is provided by an upstream module (rare — convention is one factory per app).",
|
|
1164
|
+
"canonicalFix": "Declare `export function <app>NotificationTemplateServiceConfigsArrayFactory(context): NotificationTemplateServiceTypeConfig[] { return [<foo>NotificationTemplateFactory(context), ...]; }`."
|
|
1165
|
+
},
|
|
1166
|
+
{
|
|
1167
|
+
"code": "NOTIF_TEMPLATE_FACTORY_MISSING",
|
|
1168
|
+
"source": "dbx_notification_m_validate_app",
|
|
1169
|
+
"severity": "error",
|
|
1170
|
+
"title": "A `*_NOTIFICATION_TEMPLATE_TYPE` constant has no matching `NotificationTemplateServiceTypeConfig` reachable from the configs-array factory",
|
|
1171
|
+
"whatItFlags": "A `*_NOTIFICATION_TEMPLATE_TYPE` constant has no matching `NotificationTemplateServiceTypeConfig` reachable from the configs-array factory.",
|
|
1172
|
+
"whenItApplies": "Every declared template-type constant.",
|
|
1173
|
+
"whenItDoesNotApply": "Template types whose handler config is provided by an upstream module (covered by the trust list).",
|
|
1174
|
+
"canonicalFix": "Declare a `<foo>NotificationTemplateFactory` returning the `NotificationTemplateServiceTypeConfig` and call it from the app's configs-array factory.",
|
|
1175
|
+
"seeAlso": [
|
|
1176
|
+
{
|
|
1177
|
+
"kind": "artifact",
|
|
1178
|
+
"target": "notification-template"
|
|
1179
|
+
}
|
|
1180
|
+
]
|
|
1181
|
+
},
|
|
1182
|
+
{
|
|
1183
|
+
"code": "NOTIF_TEMPLATE_FACTORY_NOT_WIRED",
|
|
1184
|
+
"source": "dbx_notification_m_validate_app",
|
|
1185
|
+
"severity": "error",
|
|
1186
|
+
"title": "The configs-array factory exists but no NestJS provider binds it via `NOTIFICATION_TEMPLATE_SERVICE_CONFIGS_ARRAY_TOKEN`",
|
|
1187
|
+
"whatItFlags": "The configs-array factory exists but no NestJS provider binds it via `NOTIFICATION_TEMPLATE_SERVICE_CONFIGS_ARRAY_TOKEN`.",
|
|
1188
|
+
"whenItApplies": "When `<app>NotificationTemplateServiceConfigsArrayFactory` exists but no `{ provide: NOTIFICATION_TEMPLATE_SERVICE_CONFIGS_ARRAY_TOKEN, useFactory }` provider exists.",
|
|
1189
|
+
"whenItDoesNotApply": "APIs that wire the factory indirectly through an imported app-module (rare — extend the scanner's subpaths if so).",
|
|
1190
|
+
"canonicalFix": "Add a NestJS provider with `provide: NOTIFICATION_TEMPLATE_SERVICE_CONFIGS_ARRAY_TOKEN, useFactory: <app>NotificationTemplateServiceConfigsArrayFactory`."
|
|
1191
|
+
},
|
|
1192
|
+
{
|
|
1193
|
+
"code": "NOTIF_TEMPLATE_FACTORY_ORPHAN",
|
|
1194
|
+
"source": "dbx_notification_m_validate_app",
|
|
1195
|
+
"severity": "error",
|
|
1196
|
+
"title": "A `NotificationTemplateServiceTypeConfig` references a `type:` identifier that is not a declared template-type constant",
|
|
1197
|
+
"whatItFlags": "A `NotificationTemplateServiceTypeConfig` references a `type:` identifier that is not a declared template-type constant.",
|
|
1198
|
+
"whenItApplies": "When the handler config's `type:` is an identifier outside the component's declared constants and the trust list.",
|
|
1199
|
+
"whenItDoesNotApply": "Handler configs whose `type:` is imported from a trust-listed module.",
|
|
1200
|
+
"canonicalFix": "Either declare the matching template-type constant or remove the orphaned config."
|
|
1201
|
+
},
|
|
1202
|
+
{
|
|
1203
|
+
"code": "NOTIF_TEMPLATE_FACTORY_SPREAD_UNRESOLVED",
|
|
1204
|
+
"source": "dbx_notification_m_validate_app",
|
|
1205
|
+
"severity": "warning",
|
|
1206
|
+
"title": "The configs-array factory spreads an identifier that doesn't resolve to a declared function",
|
|
1207
|
+
"whatItFlags": "The configs-array factory spreads an identifier that doesn't resolve to a declared function.",
|
|
1208
|
+
"whenItApplies": "When `<app>NotificationTemplateServiceConfigsArrayFactory` spreads (`...fooNotifications(context)`) a function that isn't declared locally or imported.",
|
|
1209
|
+
"whenItDoesNotApply": "Spreads from trust-listed `@dereekb/*` modules.",
|
|
1210
|
+
"canonicalFix": "Declare the missing function or import it from a trusted module."
|
|
1211
|
+
},
|
|
1212
|
+
{
|
|
1213
|
+
"code": "NOTIF_TEMPLATE_INFO_MISSING",
|
|
1214
|
+
"source": "dbx_notification_m_validate_app",
|
|
1215
|
+
"severity": "error",
|
|
1216
|
+
"title": "A `*_NOTIFICATION_TEMPLATE_TYPE` constant has no matching `NotificationTemplateTypeInfo` object",
|
|
1217
|
+
"whatItFlags": "A `*_NOTIFICATION_TEMPLATE_TYPE` constant has no matching `NotificationTemplateTypeInfo` object.",
|
|
1218
|
+
"whenItApplies": "Every declared template-type constant in the component.",
|
|
1219
|
+
"whenItDoesNotApply": "Template types declared in an upstream `@dereekb/*` module — those are detected via the trust list and skipped.",
|
|
1220
|
+
"canonicalFix": "Declare `export const <foo>NotificationTemplateTypeInfo: NotificationTemplateTypeInfo = { type: <CONSTANT>, name, description, ... }` adjacent to the constant.",
|
|
1221
|
+
"seeAlso": [
|
|
1222
|
+
{
|
|
1223
|
+
"kind": "artifact",
|
|
1224
|
+
"target": "notification-template"
|
|
1225
|
+
}
|
|
1226
|
+
]
|
|
1227
|
+
},
|
|
1228
|
+
{
|
|
1229
|
+
"code": "NOTIF_TEMPLATE_INFO_MISSING_NAME_OR_DESCRIPTION",
|
|
1230
|
+
"source": "dbx_notification_m_validate_app",
|
|
1231
|
+
"severity": "warning",
|
|
1232
|
+
"title": "A `NotificationTemplateTypeInfo` object is missing the `name` and/or `description` field",
|
|
1233
|
+
"whatItFlags": "A `NotificationTemplateTypeInfo` object is missing the `name` and/or `description` field.",
|
|
1234
|
+
"whenItApplies": "Every declared `NotificationTemplateTypeInfo` whose `name` or `description` is empty / missing.",
|
|
1235
|
+
"whenItDoesNotApply": "Infos whose human-readable fields are intentionally blank (rare — most consumers surface them in admin UI).",
|
|
1236
|
+
"canonicalFix": "Populate `name: '...'` and `description: '...'` on the info object so admin / tooling surfaces have something to render."
|
|
1237
|
+
},
|
|
1238
|
+
{
|
|
1239
|
+
"code": "NOTIF_TEMPLATE_INFO_NOT_IN_RECORD",
|
|
1240
|
+
"source": "dbx_notification_m_validate_app",
|
|
1241
|
+
"severity": "error",
|
|
1242
|
+
"title": "A declared `NotificationTemplateTypeInfo` is not reachable from the metadata aggregator record",
|
|
1243
|
+
"whatItFlags": "A declared `NotificationTemplateTypeInfo` is not reachable from the metadata aggregator record.",
|
|
1244
|
+
"whenItApplies": "Every info object whose symbol does not appear in the resolved set traced from `notificationTemplateTypeInfoRecord([...])`.",
|
|
1245
|
+
"whenItDoesNotApply": "Infos intentionally excluded from the runtime record (rare — usually a missed registration step).",
|
|
1246
|
+
"canonicalFix": "Add the info symbol (or its containing `ALL_*_NOTIFICATION_TEMPLATE_TYPE_INFOS` aggregate) to the record array."
|
|
1247
|
+
},
|
|
1248
|
+
{
|
|
1249
|
+
"code": "NOTIF_TEMPLATE_INFO_TYPE_MISMATCH",
|
|
1250
|
+
"source": "dbx_notification_m_validate_app",
|
|
1251
|
+
"severity": "error",
|
|
1252
|
+
"title": "A `NotificationTemplateTypeInfo` object's `type:` does not match a declared template-type constant",
|
|
1253
|
+
"whatItFlags": "A `NotificationTemplateTypeInfo` object's `type:` does not match a declared template-type constant.",
|
|
1254
|
+
"whenItApplies": "When the info's `type:` references a missing constant or an identifier outside the trust list.",
|
|
1255
|
+
"whenItDoesNotApply": "Info objects whose `type:` is provided by an imported `@dereekb/*` constant — covered by the trust list.",
|
|
1256
|
+
"canonicalFix": "Either declare the missing template-type constant or update the info's `type:` to a real constant in the component."
|
|
1257
|
+
},
|
|
1258
|
+
{
|
|
1259
|
+
"code": "NOTIF_TEMPLATE_INFO_UNUSED",
|
|
1260
|
+
"source": "dbx_notification_m_validate_app",
|
|
1261
|
+
"severity": "warning",
|
|
1262
|
+
"title": "A declared `NotificationTemplateTypeInfo` is unused — its symbol isn't reachable from the metadata aggregator",
|
|
1263
|
+
"whatItFlags": "A declared `NotificationTemplateTypeInfo` is unused — its symbol isn't reachable from the metadata aggregator.",
|
|
1264
|
+
"whenItApplies": "When the info's symbol does not appear in any aggregate array or the resolved record set.",
|
|
1265
|
+
"whenItDoesNotApply": "Infos kept around for documentation / future wiring (rare — usually rename drift).",
|
|
1266
|
+
"canonicalFix": "Either remove the orphan info or add it to the appropriate `ALL_*_NOTIFICATION_TEMPLATE_TYPE_INFOS` aggregate."
|
|
1267
|
+
},
|
|
1268
|
+
{
|
|
1269
|
+
"code": "NOTIF_TEMPLATE_RECORD_MISSING",
|
|
1270
|
+
"source": "dbx_notification_m_validate_app",
|
|
1271
|
+
"severity": "error",
|
|
1272
|
+
"title": "No top-level `notificationTemplateTypeInfoRecord([...])` call was found",
|
|
1273
|
+
"whatItFlags": "No top-level `notificationTemplateTypeInfoRecord([...])` call was found.",
|
|
1274
|
+
"whenItApplies": "Components that declare at least one `NotificationTemplateTypeInfo`.",
|
|
1275
|
+
"whenItDoesNotApply": "Components whose record is provided by an upstream `@dereekb/*` module (rare — convention is one record per app).",
|
|
1276
|
+
"canonicalFix": "Declare `export const <APP>_FIREBASE_NOTIFICATION_TEMPLATE_TYPE_INFO_RECORD = notificationTemplateTypeInfoRecord([...]);` covering every template info."
|
|
1277
|
+
},
|
|
1278
|
+
{
|
|
1279
|
+
"code": "NOTIF_TEMPLATE_RECORD_NOT_WIRED",
|
|
1280
|
+
"source": "dbx_notification_m_validate_app",
|
|
1281
|
+
"severity": "error",
|
|
1282
|
+
"title": "The metadata record exists but is not wired through `appNotificationTemplateTypeInfoRecordService(...)` in the API",
|
|
1283
|
+
"whatItFlags": "The metadata record exists but is not wired through `appNotificationTemplateTypeInfoRecordService(...)` in the API.",
|
|
1284
|
+
"whenItApplies": "When `appNotificationTemplateTypeInfoRecordService(...)` is missing or its argument doesn't resolve to the declared record.",
|
|
1285
|
+
"whenItDoesNotApply": "APIs that wire the record indirectly through an imported app-module (rare — extend the scanner's subpaths if so).",
|
|
1286
|
+
"canonicalFix": "Add `appNotificationTemplateTypeInfoRecordService(<APP>_FIREBASE_NOTIFICATION_TEMPLATE_TYPE_INFO_RECORD)` to the API's notification module."
|
|
1287
|
+
},
|
|
1288
|
+
{
|
|
1289
|
+
"code": "NOTIF_TEMPLATE_SPREAD_UNRESOLVED",
|
|
1290
|
+
"source": "dbx_notification_m_validate_app",
|
|
1291
|
+
"severity": "error",
|
|
1292
|
+
"title": "The metadata record's `[...]` array spreads an identifier that doesn't resolve to a declared aggregate",
|
|
1293
|
+
"whatItFlags": "The metadata record's `[...]` array spreads an identifier that doesn't resolve to a declared aggregate.",
|
|
1294
|
+
"whenItApplies": "When `notificationTemplateTypeInfoRecord([...])` spreads a name that isn't a `ALL_*_NOTIFICATION_TEMPLATE_TYPE_INFOS` aggregate or trusted external.",
|
|
1295
|
+
"whenItDoesNotApply": "Spreads from trust-listed `@dereekb/*` modules.",
|
|
1296
|
+
"canonicalFix": "Declare the aggregate as `export const ALL_<NAME>_NOTIFICATION_TEMPLATE_TYPE_INFOS: NotificationTemplateTypeInfo[] = [...]` or import it from a trusted module."
|
|
1297
|
+
},
|
|
1298
|
+
{
|
|
1299
|
+
"code": "NOTIF_TEMPLATE_TYPE_CODE_DUPLICATE",
|
|
1300
|
+
"source": "dbx_notification_m_validate_app",
|
|
1301
|
+
"severity": "warning",
|
|
1302
|
+
"title": "Two `*_NOTIFICATION_TEMPLATE_TYPE` constants share the same string literal value",
|
|
1303
|
+
"whatItFlags": "Two `*_NOTIFICATION_TEMPLATE_TYPE` constants share the same string literal value.",
|
|
1304
|
+
"whenItApplies": "When more than one template-type constant resolves to the same `'<value>'` literal.",
|
|
1305
|
+
"whenItDoesNotApply": "Constants intentionally aliased — but this defeats persisted-document discrimination, so almost always a copy-paste.",
|
|
1306
|
+
"canonicalFix": "Rename one of the literals so each template code is unique."
|
|
1307
|
+
},
|
|
1308
|
+
{
|
|
1309
|
+
"code": "NOTIF_FOLDER_API_DIR_NOT_FOUND",
|
|
1310
|
+
"source": "dbx_notification_m_validate_folder",
|
|
1311
|
+
"severity": "error",
|
|
1312
|
+
"title": "The API app directory does not exist on disk",
|
|
1313
|
+
"whatItFlags": "The API app directory does not exist on disk.",
|
|
1314
|
+
"whenItApplies": "When the supplied `apiDir` does not resolve to a directory entry.",
|
|
1315
|
+
"whenItDoesNotApply": "API apps intentionally not validated — pass `--skip notification_m` instead.",
|
|
1316
|
+
"canonicalFix": "Verify the path argument resolves to an existing API app root.",
|
|
1317
|
+
"seeAlso": [
|
|
1318
|
+
{
|
|
1319
|
+
"kind": "tool",
|
|
1320
|
+
"target": "dbx_notification_m_validate_folder"
|
|
1321
|
+
}
|
|
1322
|
+
]
|
|
1323
|
+
},
|
|
1324
|
+
{
|
|
1325
|
+
"code": "NOTIF_FOLDER_API_FOLDER_MISSING",
|
|
1326
|
+
"source": "dbx_notification_m_validate_folder",
|
|
1327
|
+
"severity": "error",
|
|
1328
|
+
"title": "The API root exists but `src/app/common/model/notification/` is missing",
|
|
1329
|
+
"whatItFlags": "The API root exists but `src/app/common/model/notification/` is missing.",
|
|
1330
|
+
"whenItApplies": "API apps expected to wire the notification module but with no notification folder.",
|
|
1331
|
+
"whenItDoesNotApply": "API apps that intentionally don't wire notifications — pass `--skip notification_m`.",
|
|
1332
|
+
"canonicalFix": "Add `src/app/common/model/notification/` with `notification.module.ts`, `notification.task.service.ts`, and `notification.send.service.ts`.",
|
|
1333
|
+
"seeAlso": [
|
|
1334
|
+
{
|
|
1335
|
+
"kind": "artifact",
|
|
1336
|
+
"target": "notification-template"
|
|
1337
|
+
}
|
|
1338
|
+
]
|
|
1339
|
+
},
|
|
1340
|
+
{
|
|
1341
|
+
"code": "NOTIF_FOLDER_BARREL_REEXPORT_MISSING",
|
|
1342
|
+
"source": "dbx_notification_m_validate_folder",
|
|
1343
|
+
"severity": "error",
|
|
1344
|
+
"title": "`index.ts` re-exports a path that does not resolve to a sibling file or subfolder",
|
|
1345
|
+
"whatItFlags": "`index.ts` re-exports a path that does not resolve to a sibling file or subfolder.",
|
|
1346
|
+
"whenItApplies": "When `export * from './X'` in `index.ts` has no matching `./X.ts` or `./X/` under the notification folder root.",
|
|
1347
|
+
"whenItDoesNotApply": "Re-exports that intentionally point outside the folder (use a relative path that climbs out, not `./X`).",
|
|
1348
|
+
"canonicalFix": "Add the missing `<name>.ts` / `<name>/` sibling, or remove the dangling re-export from `index.ts`."
|
|
1349
|
+
},
|
|
1350
|
+
{
|
|
1351
|
+
"code": "NOTIF_FOLDER_COMPONENT_DIR_NOT_FOUND",
|
|
1352
|
+
"source": "dbx_notification_m_validate_folder",
|
|
1353
|
+
"severity": "error",
|
|
1354
|
+
"title": "The component package directory does not exist on disk",
|
|
1355
|
+
"whatItFlags": "The component package directory does not exist on disk.",
|
|
1356
|
+
"whenItApplies": "When the supplied `componentDir` does not resolve to a directory entry.",
|
|
1357
|
+
"whenItDoesNotApply": "Components intentionally not part of this validation pass — pass `--skip notification_m` to `dbx_app_validate` instead.",
|
|
1358
|
+
"canonicalFix": "Verify the path argument resolves to an existing component package root.",
|
|
1359
|
+
"seeAlso": [
|
|
1360
|
+
{
|
|
1361
|
+
"kind": "tool",
|
|
1362
|
+
"target": "dbx_notification_m_validate_folder"
|
|
1363
|
+
}
|
|
1364
|
+
]
|
|
1365
|
+
},
|
|
1366
|
+
{
|
|
1367
|
+
"code": "NOTIF_FOLDER_COMPONENT_FOLDER_MISSING",
|
|
1368
|
+
"source": "dbx_notification_m_validate_folder",
|
|
1369
|
+
"severity": "error",
|
|
1370
|
+
"title": "The component root exists but `src/lib/model/notification/` is missing",
|
|
1371
|
+
"whatItFlags": "The component root exists but `src/lib/model/notification/` is missing.",
|
|
1372
|
+
"whenItApplies": "Components that should ship `NotificationTemplateType` / `NotificationTaskType` constants but lack the notification model folder.",
|
|
1373
|
+
"whenItDoesNotApply": "Components that intentionally don't extend the notification group (rare — most apps with notifications do).",
|
|
1374
|
+
"canonicalFix": "Add `src/lib/model/notification/notification.ts` and the rest of the notification artefacts.",
|
|
1375
|
+
"seeAlso": [
|
|
1376
|
+
{
|
|
1377
|
+
"kind": "artifact",
|
|
1378
|
+
"target": "notification-template"
|
|
1379
|
+
},
|
|
1380
|
+
{
|
|
1381
|
+
"kind": "artifact",
|
|
1382
|
+
"target": "notification-task"
|
|
1383
|
+
}
|
|
1384
|
+
]
|
|
1385
|
+
},
|
|
1386
|
+
{
|
|
1387
|
+
"code": "NOTIF_FOLDER_HANDLERS_SUBFOLDER_MIXED",
|
|
1388
|
+
"source": "dbx_notification_m_validate_folder",
|
|
1389
|
+
"severity": "warning",
|
|
1390
|
+
"title": "A non-canonical `.ts` file lives at the API notification root alongside a `handlers/` subfolder",
|
|
1391
|
+
"whatItFlags": "A non-canonical `.ts` file lives at the API notification root alongside a `handlers/` subfolder.",
|
|
1392
|
+
"whenItApplies": "API folders that mix root-level handler files with a sibling `handlers/` subfolder.",
|
|
1393
|
+
"whenItDoesNotApply": "Strictly canonical files (`notification.module.ts`, `notification.task.service.ts`, `notification.send.service.ts`, plus the convention extras tracked in `CANONICAL_API_ROOT_FILES`) — those are allowed at the root.",
|
|
1394
|
+
"canonicalFix": "Move the handler file into `handlers/` so the convention stays consistent across the project."
|
|
1395
|
+
},
|
|
1396
|
+
{
|
|
1397
|
+
"code": "NOTIF_FOLDER_MODULE_FILE_MISSING",
|
|
1398
|
+
"source": "dbx_notification_m_validate_folder",
|
|
1399
|
+
"severity": "error",
|
|
1400
|
+
"title": "The API notification folder is missing the required `notification.module.ts` file",
|
|
1401
|
+
"whatItFlags": "The API notification folder is missing the required `notification.module.ts` file.",
|
|
1402
|
+
"whenItApplies": "Every API notification folder that exists.",
|
|
1403
|
+
"whenItDoesNotApply": "The NestJS notification module is provided elsewhere in the app (rare — convention is one module per folder).",
|
|
1404
|
+
"canonicalFix": "Add `notification.module.ts` declaring the NestJS module that binds the notification task / send service providers."
|
|
1405
|
+
},
|
|
1406
|
+
{
|
|
1407
|
+
"code": "NOTIF_FOLDER_SEND_SERVICE_FILE_MISSING",
|
|
1408
|
+
"source": "dbx_notification_m_validate_folder",
|
|
1409
|
+
"severity": "error",
|
|
1410
|
+
"title": "The API notification folder is missing the required `notification.send.service.ts` file",
|
|
1411
|
+
"whatItFlags": "The API notification folder is missing the required `notification.send.service.ts` file.",
|
|
1412
|
+
"whenItApplies": "Every API notification folder that exists.",
|
|
1413
|
+
"whenItDoesNotApply": "Apps whose `NotificationSendService` factory lives elsewhere (rare — convention is one factory per folder).",
|
|
1414
|
+
"canonicalFix": "Add `notification.send.service.ts` exporting the `NotificationSendService` factory wired through the notification module."
|
|
1415
|
+
},
|
|
1416
|
+
{
|
|
1417
|
+
"code": "NOTIF_FOLDER_TASK_SERVICE_FILE_MISSING",
|
|
1418
|
+
"source": "dbx_notification_m_validate_folder",
|
|
1419
|
+
"severity": "error",
|
|
1420
|
+
"title": "The API notification folder is missing the required `notification.task.service.ts` file",
|
|
1421
|
+
"whatItFlags": "The API notification folder is missing the required `notification.task.service.ts` file.",
|
|
1422
|
+
"whenItApplies": "Every API notification folder that exists.",
|
|
1423
|
+
"whenItDoesNotApply": "Apps whose `NotificationTaskService` factory lives elsewhere (rare — convention is one factory per folder).",
|
|
1424
|
+
"canonicalFix": "Add `notification.task.service.ts` exporting the `notificationTaskService({ ... })` factory call.",
|
|
1425
|
+
"seeAlso": [
|
|
1426
|
+
{
|
|
1427
|
+
"kind": "artifact",
|
|
1428
|
+
"target": "notification-task"
|
|
1429
|
+
}
|
|
1430
|
+
]
|
|
1431
|
+
},
|
|
1432
|
+
{
|
|
1433
|
+
"code": "NOTIF_FOLDER_UNEXPECTED_FILE_NAME",
|
|
1434
|
+
"source": "dbx_notification_m_validate_folder",
|
|
1435
|
+
"severity": "warning",
|
|
1436
|
+
"title": "A `.ts` file in the notification folder doesn't start with the `notification.` prefix",
|
|
1437
|
+
"whatItFlags": "A `.ts` file in the notification folder doesn't start with the `notification.` prefix.",
|
|
1438
|
+
"whenItApplies": "Any `.ts` file other than `index.ts` whose basename doesn't start with `notification.`.",
|
|
1439
|
+
"whenItDoesNotApply": "Files outside the canonical layout that the project intentionally hosts here (rare — prefer moving them out).",
|
|
1440
|
+
"canonicalFix": "Rename the file to `notification.<sub>.ts`, or move it out of the notification folder."
|
|
1441
|
+
},
|
|
1442
|
+
{
|
|
1443
|
+
"code": "STORAGEFILE_API_DIR_NOT_FOUND",
|
|
1444
|
+
"source": "dbx_storagefile_m_validate_app",
|
|
1445
|
+
"severity": "error",
|
|
1446
|
+
"title": "The API app's `src/app/common/model/storagefile/` directory does not exist",
|
|
1447
|
+
"whatItFlags": "The API app's `src/app/common/model/storagefile/` directory does not exist.",
|
|
1448
|
+
"whenItApplies": "When `apiDir` resolves to a directory but the storagefile API folder is missing.",
|
|
1449
|
+
"whenItDoesNotApply": "API apps that intentionally don't wire storage-file purposes — pass `--skip storagefile_m` instead.",
|
|
1450
|
+
"canonicalFix": "Add `<apiDir>/src/app/common/model/storagefile/` with `storagefile.module.ts`, `storagefile.upload.service.ts`, and `storagefile.init.ts`.",
|
|
1451
|
+
"seeAlso": [
|
|
1452
|
+
{
|
|
1453
|
+
"kind": "tool",
|
|
1454
|
+
"target": "dbx_storagefile_m_validate_folder"
|
|
1455
|
+
}
|
|
1456
|
+
]
|
|
1457
|
+
},
|
|
1458
|
+
{
|
|
1459
|
+
"code": "STORAGEFILE_API_FOLDER_MISSING",
|
|
1460
|
+
"source": "dbx_storagefile_m_validate_app",
|
|
1461
|
+
"severity": "error",
|
|
1462
|
+
"title": "The API root exists but neither `src/app/common/model/storagefile/` nor",
|
|
1463
|
+
"whatItFlags": "The API root exists but neither `src/app/common/model/storagefile/` nor\n`src/app/common/model/notification/` is present (the storage-file\nprocessing handler may live in `notification/handlers/`).",
|
|
1464
|
+
"whenItApplies": "When the API package is present but has no storagefile or notification subfolders.",
|
|
1465
|
+
"whenItDoesNotApply": "API apps that don't wire storage-file or notification purposes.",
|
|
1466
|
+
"canonicalFix": "Add `src/app/common/model/storagefile/` and (if processing handlers are needed) `src/app/common/model/notification/handlers/`.",
|
|
1467
|
+
"seeAlso": [
|
|
1468
|
+
{
|
|
1469
|
+
"kind": "tool",
|
|
1470
|
+
"target": "dbx_storagefile_m_validate_folder"
|
|
1471
|
+
}
|
|
1472
|
+
]
|
|
1473
|
+
},
|
|
1474
|
+
{
|
|
1475
|
+
"code": "STORAGEFILE_COMPONENT_DIR_NOT_FOUND",
|
|
1476
|
+
"source": "dbx_storagefile_m_validate_app",
|
|
1477
|
+
"severity": "error",
|
|
1478
|
+
"title": "The component's `src/lib/model/storagefile/` directory does not exist",
|
|
1479
|
+
"whatItFlags": "The component's `src/lib/model/storagefile/` directory does not exist.",
|
|
1480
|
+
"whenItApplies": "When `componentDir` resolves to a directory but the storagefile model folder is missing.",
|
|
1481
|
+
"whenItDoesNotApply": "Components that intentionally don't ship storage-file purposes — pass `--skip storagefile_m` to `dbx_app_validate` instead.",
|
|
1482
|
+
"canonicalFix": "Add `<componentDir>/src/lib/model/storagefile/storagefile.ts` and the rest of the storagefile artefacts.",
|
|
1483
|
+
"seeAlso": [
|
|
1484
|
+
{
|
|
1485
|
+
"kind": "artifact",
|
|
1486
|
+
"target": "storagefile-purpose"
|
|
1487
|
+
},
|
|
1488
|
+
{
|
|
1489
|
+
"kind": "tool",
|
|
1490
|
+
"target": "dbx_storagefile_m_validate_folder"
|
|
1491
|
+
}
|
|
1492
|
+
]
|
|
1493
|
+
},
|
|
1494
|
+
{
|
|
1495
|
+
"code": "STORAGEFILE_COMPONENT_FOLDER_MISSING",
|
|
1496
|
+
"source": "dbx_storagefile_m_validate_app",
|
|
1497
|
+
"severity": "error",
|
|
1498
|
+
"title": "The component root exists but has no `src/lib/model/storagefile/` subfolder",
|
|
1499
|
+
"whatItFlags": "The component root exists but has no `src/lib/model/storagefile/` subfolder.",
|
|
1500
|
+
"whenItApplies": "When the component package is present but has no storagefile model folder.",
|
|
1501
|
+
"whenItDoesNotApply": "Components that don't extend the storagefile group.",
|
|
1502
|
+
"canonicalFix": "Run `dbx_artifact_scaffold artifact=\"storagefile-purpose\"` to scaffold the folder layout.",
|
|
1503
|
+
"seeAlso": [
|
|
1504
|
+
{
|
|
1505
|
+
"kind": "artifact",
|
|
1506
|
+
"target": "storagefile-purpose"
|
|
1507
|
+
}
|
|
1508
|
+
]
|
|
1509
|
+
},
|
|
1510
|
+
{
|
|
1511
|
+
"code": "STORAGEFILE_FILE_TYPE_IDENTIFIER_DUPLICATE",
|
|
1512
|
+
"source": "dbx_storagefile_m_validate_app",
|
|
1513
|
+
"severity": "warning",
|
|
1514
|
+
"title": "Two `UploadedFileTypeIdentifier` constants share the same string",
|
|
1515
|
+
"whatItFlags": "Two `UploadedFileTypeIdentifier` constants share the same string\nliteral value.",
|
|
1516
|
+
"whenItApplies": "When more than one file-type identifier constant resolves to the same `'<value>'`.",
|
|
1517
|
+
"whenItDoesNotApply": "File-type identifiers intentionally re-used across purposes (rare — almost always a bug).",
|
|
1518
|
+
"canonicalFix": "Rename one of the literals so each file-type code is unique."
|
|
1519
|
+
},
|
|
1520
|
+
{
|
|
1521
|
+
"code": "STORAGEFILE_GROUP_IDS_FUNCTION_MISSING",
|
|
1522
|
+
"source": "dbx_storagefile_m_validate_app",
|
|
1523
|
+
"severity": "warning",
|
|
1524
|
+
"title": "A `*_PURPOSE` constant has no `<purpose>FileGroupIds(...)` or",
|
|
1525
|
+
"whatItFlags": "A `*_PURPOSE` constant has no `<purpose>FileGroupIds(...)` or\n`<purpose>StorageFileGroupIds(...)` helper function in the same\ncomponent.",
|
|
1526
|
+
"whenItApplies": "Validating a downstream `-firebase` component that declares at least one `StorageFilePurpose` constant.",
|
|
1527
|
+
"whenItDoesNotApply": "Purposes that intentionally hold no group membership (rare — most purposes belong to a workspace's group convention).",
|
|
1528
|
+
"canonicalFix": "Declare `export function <purpose>FileGroupIds(input): StorageFileGroupIds` adjacent to the purpose constant.",
|
|
1529
|
+
"canonicalFixTemplate": "```ts\nexport function <purpose>FileGroupIds(input: { /* ids the group needs *\\/ }): StorageFileGroupIds {\nreturn [storageFileGroupId({ /* ... *\\/ })];\n}\n```",
|
|
1530
|
+
"seeAlso": [
|
|
1531
|
+
{
|
|
1532
|
+
"kind": "artifact",
|
|
1533
|
+
"target": "storagefile-purpose"
|
|
1534
|
+
}
|
|
1535
|
+
]
|
|
1536
|
+
},
|
|
1537
|
+
{
|
|
1538
|
+
"code": "STORAGEFILE_PROCESSING_CONFIG_MISSING",
|
|
1539
|
+
"source": "dbx_storagefile_m_validate_app",
|
|
1540
|
+
"severity": "error",
|
|
1541
|
+
"title": "A purpose with subtasks has no",
|
|
1542
|
+
"whatItFlags": "A purpose with subtasks has no\n`StorageFileProcessingPurposeSubtaskProcessorConfig` whose `target:`\nreferences it.",
|
|
1543
|
+
"whenItApplies": "Every purpose that declares a `*ProcessingSubtask` union.",
|
|
1544
|
+
"whenItDoesNotApply": "Purposes whose processing config is provided by an upstream module.",
|
|
1545
|
+
"canonicalFix": "Add a config with `target: <PURPOSE_CONST>, flow: [{ subtask: <SUBTASK_CONST>, ... }, ...]`.",
|
|
1546
|
+
"seeAlso": [
|
|
1547
|
+
{
|
|
1548
|
+
"kind": "artifact",
|
|
1549
|
+
"target": "storagefile-processor"
|
|
1550
|
+
}
|
|
1551
|
+
]
|
|
1552
|
+
},
|
|
1553
|
+
{
|
|
1554
|
+
"code": "STORAGEFILE_PROCESSING_CONFIG_ORPHAN",
|
|
1555
|
+
"source": "dbx_storagefile_m_validate_app",
|
|
1556
|
+
"severity": "error",
|
|
1557
|
+
"title": "A processing config references a `target:` identifier that is not",
|
|
1558
|
+
"whatItFlags": "A processing config references a `target:` identifier that is not\nany declared `StorageFilePurpose` constant.",
|
|
1559
|
+
"whenItApplies": "When the `target:` identifier is local but not declared.",
|
|
1560
|
+
"whenItDoesNotApply": "When the target is imported from a trust-listed module.",
|
|
1561
|
+
"canonicalFix": "Either declare the purpose or remove the orphaned config."
|
|
1562
|
+
},
|
|
1563
|
+
{
|
|
1564
|
+
"code": "STORAGEFILE_PROCESSING_HANDLER_MISSING",
|
|
1565
|
+
"source": "dbx_storagefile_m_validate_app",
|
|
1566
|
+
"severity": "error",
|
|
1567
|
+
"title": "The component declares purposes with subtasks but no",
|
|
1568
|
+
"whatItFlags": "The component declares purposes with subtasks but no\n`storageFileProcessingNotificationTaskHandler({ processors })` call\nis present in the API.",
|
|
1569
|
+
"whenItApplies": "When at least one purpose declares a `*ProcessingSubtask` union and `*_PROCESSING_SUBTASK` constants.",
|
|
1570
|
+
"whenItDoesNotApply": "Purposes that store a file but do not need processing.",
|
|
1571
|
+
"canonicalFix": "Add a `storageFileProcessingNotificationTaskHandler({ processors: [...] })` call and wire it into the notification-task service.",
|
|
1572
|
+
"seeAlso": [
|
|
1573
|
+
{
|
|
1574
|
+
"kind": "artifact",
|
|
1575
|
+
"target": "storagefile-processor"
|
|
1576
|
+
}
|
|
1577
|
+
]
|
|
1578
|
+
},
|
|
1579
|
+
{
|
|
1580
|
+
"code": "STORAGEFILE_PROCESSING_SUBTASK_NOT_HANDLED",
|
|
1581
|
+
"source": "dbx_storagefile_m_validate_app",
|
|
1582
|
+
"severity": "error",
|
|
1583
|
+
"title": "A `*_PROCESSING_SUBTASK` declared on a purpose's union is absent",
|
|
1584
|
+
"whatItFlags": "A `*_PROCESSING_SUBTASK` declared on a purpose's union is absent\nfrom the matching processor config's `flow:` array.",
|
|
1585
|
+
"whenItApplies": "Every purpose × subtask pairing.",
|
|
1586
|
+
"whenItDoesNotApply": "Subtasks whose processor lives in a separate, dedicated config (uncommon — usually a missed flow step).",
|
|
1587
|
+
"canonicalFix": "Add `{ subtask: <SUBTASK_CONST>, processor: ... }` to the config's `flow:` array.",
|
|
1588
|
+
"seeAlso": [
|
|
1589
|
+
{
|
|
1590
|
+
"kind": "artifact",
|
|
1591
|
+
"target": "storagefile-processor-subtask"
|
|
1592
|
+
}
|
|
1593
|
+
]
|
|
1594
|
+
},
|
|
1595
|
+
{
|
|
1596
|
+
"code": "STORAGEFILE_PURPOSE_DUPLICATE",
|
|
1597
|
+
"source": "dbx_storagefile_m_validate_app",
|
|
1598
|
+
"severity": "warning",
|
|
1599
|
+
"title": "Two `StorageFilePurpose` constants share the same string literal value",
|
|
1600
|
+
"whatItFlags": "Two `StorageFilePurpose` constants share the same string literal value.",
|
|
1601
|
+
"whenItApplies": "When more than one purpose constant resolves to the same `'<value>'` literal.",
|
|
1602
|
+
"whenItDoesNotApply": "Purposes intentionally aliased — but this defeats persisted-document discrimination, so almost always a copy-paste.",
|
|
1603
|
+
"canonicalFix": "Rename one of the literals so each purpose code is unique."
|
|
1604
|
+
},
|
|
1605
|
+
{
|
|
1606
|
+
"code": "STORAGEFILE_PURPOSE_MISSING_FILE_TYPE_IDENTIFIER",
|
|
1607
|
+
"source": "dbx_storagefile_m_validate_app",
|
|
1608
|
+
"severity": "error",
|
|
1609
|
+
"title": "A `*_PURPOSE: StorageFilePurpose` constant has no matching",
|
|
1610
|
+
"whatItFlags": "A `*_PURPOSE: StorageFilePurpose` constant has no matching\n`*_UPLOADED_FILE_TYPE_IDENTIFIER` constant alongside it.",
|
|
1611
|
+
"whenItApplies": "Every declared `StorageFilePurpose` constant.",
|
|
1612
|
+
"whenItDoesNotApply": "Purposes whose file-type identifier is intentionally imported from a trust-listed `@dereekb/firebase` module.",
|
|
1613
|
+
"canonicalFix": "Declare `<PREFIX>_UPLOADED_FILE_TYPE_IDENTIFIER: UploadedFileTypeIdentifier = '...'` next to the purpose.",
|
|
1614
|
+
"seeAlso": [
|
|
1615
|
+
{
|
|
1616
|
+
"kind": "artifact",
|
|
1617
|
+
"target": "storagefile-purpose"
|
|
1618
|
+
}
|
|
1619
|
+
]
|
|
1620
|
+
},
|
|
1621
|
+
{
|
|
1622
|
+
"code": "STORAGEFILE_PURPOSE_NOT_IN_UPLOAD_SERVICE",
|
|
1623
|
+
"source": "dbx_storagefile_m_validate_app",
|
|
1624
|
+
"severity": "error",
|
|
1625
|
+
"title": "A declared `UploadedFileTypeIdentifier` constant has no",
|
|
1626
|
+
"whatItFlags": "A declared `UploadedFileTypeIdentifier` constant has no\n`StorageFileInitializeFromUploadServiceInitializer` reachable from any\n`storageFileInitializeFromUploadService(...)` call.",
|
|
1627
|
+
"whenItApplies": "Every declared file-type identifier.",
|
|
1628
|
+
"whenItDoesNotApply": "File-type identifiers that are intentionally orphaned (rare — usually a typo in a binding name; see `STORAGEFILE_UPLOAD_INITIALIZER_NAME_MISMATCH`).",
|
|
1629
|
+
"canonicalFix": "Add an initializer with `type: <CONSTANT>` and include it in the upload-service `initializer` array.",
|
|
1630
|
+
"seeAlso": [
|
|
1631
|
+
{
|
|
1632
|
+
"kind": "artifact",
|
|
1633
|
+
"target": "storagefile-upload-handler"
|
|
1634
|
+
}
|
|
1635
|
+
]
|
|
1636
|
+
},
|
|
1637
|
+
{
|
|
1638
|
+
"code": "STORAGEFILE_UPLOAD_INITIALIZER_NAME_MISMATCH",
|
|
1639
|
+
"source": "dbx_storagefile_m_validate_app",
|
|
1640
|
+
"severity": "error",
|
|
1641
|
+
"title": "A `type:` constant is declared and referenced by an initializer, but",
|
|
1642
|
+
"whatItFlags": "A `type:` constant is declared and referenced by an initializer, but\nthe initializer's binding name doesn't match any element of the\n`initializer` array — usually a rename drift.",
|
|
1643
|
+
"whenItApplies": "When an initializer literal exists but the wrapping factory's local-variable name diverges from the call-site binding.",
|
|
1644
|
+
"whenItDoesNotApply": "Initializer factories that intentionally compose multiple bindings via `...spread` (the validator handles spreads via `STORAGEFILE_UPLOAD_SERVICE_SPREAD_UNRESOLVED`).",
|
|
1645
|
+
"canonicalFix": "Rename the local variable to match the binding name used in the `initializer` array element / spread, or update the array."
|
|
1646
|
+
},
|
|
1647
|
+
{
|
|
1648
|
+
"code": "STORAGEFILE_UPLOAD_INITIALIZER_ORPHAN",
|
|
1649
|
+
"source": "dbx_storagefile_m_validate_app",
|
|
1650
|
+
"severity": "error",
|
|
1651
|
+
"title": "An upload initializer references a `type:` identifier that is not a",
|
|
1652
|
+
"whatItFlags": "An upload initializer references a `type:` identifier that is not a\ndeclared `UploadedFileTypeIdentifier` constant in the component (or a\ntrust-listed external).",
|
|
1653
|
+
"whenItApplies": "Every initializer literal seen in the API.",
|
|
1654
|
+
"whenItDoesNotApply": "When the type identifier is imported from `@dereekb/firebase`/`@dereekb/firebase-server` — those are auto-trusted.",
|
|
1655
|
+
"canonicalFix": "Either declare the missing constant in the component or remove the initializer."
|
|
1656
|
+
},
|
|
1657
|
+
{
|
|
1658
|
+
"code": "STORAGEFILE_UPLOAD_SERVICE_FACTORY_MISSING",
|
|
1659
|
+
"source": "dbx_storagefile_m_validate_app",
|
|
1660
|
+
"severity": "error",
|
|
1661
|
+
"title": "No `storageFileInitializeFromUploadService(...)` call was found in",
|
|
1662
|
+
"whatItFlags": "No `storageFileInitializeFromUploadService(...)` call was found in\nthe API.",
|
|
1663
|
+
"whenItApplies": "APIs that declare at least one `UploadedFileTypeIdentifier` and therefore need to wire the upload service.",
|
|
1664
|
+
"whenItDoesNotApply": "APIs whose upload service is provided by an upstream module (and the call lives outside the scanned subpaths — extend the scanner if so).",
|
|
1665
|
+
"canonicalFix": "Add a factory whose return value is built from `storageFileInitializeFromUploadService({ initializer: [...] })` and bind it as a NestJS provider.",
|
|
1666
|
+
"seeAlso": [
|
|
1667
|
+
{
|
|
1668
|
+
"kind": "artifact",
|
|
1669
|
+
"target": "storagefile-upload-handler"
|
|
1670
|
+
}
|
|
1671
|
+
]
|
|
1672
|
+
},
|
|
1673
|
+
{
|
|
1674
|
+
"code": "STORAGEFILE_UPLOAD_SERVICE_MULTIPLE_FACTORIES",
|
|
1675
|
+
"source": "dbx_storagefile_m_validate_app",
|
|
1676
|
+
"severity": "warning",
|
|
1677
|
+
"title": "Multiple `storageFileInitializeFromUploadService(...)` calls were",
|
|
1678
|
+
"whatItFlags": "Multiple `storageFileInitializeFromUploadService(...)` calls were\nfound.",
|
|
1679
|
+
"whenItApplies": "When more than one upload-service factory exists in the API.",
|
|
1680
|
+
"whenItDoesNotApply": "Apps that intentionally compose multiple factories (rare — only the first one runs).",
|
|
1681
|
+
"canonicalFix": "Consolidate the factories into one — only the first call's config takes effect at runtime."
|
|
1682
|
+
},
|
|
1683
|
+
{
|
|
1684
|
+
"code": "STORAGEFILE_UPLOAD_SERVICE_NOT_WIRED",
|
|
1685
|
+
"source": "dbx_storagefile_m_validate_app",
|
|
1686
|
+
"severity": "error",
|
|
1687
|
+
"title": "The upload-service factory exists but no NestJS provider binds it via",
|
|
1688
|
+
"whatItFlags": "The upload-service factory exists but no NestJS provider binds it via\n`provide: StorageFileInitializeFromUploadService, useFactory: ...`.",
|
|
1689
|
+
"whenItApplies": "When the API has at least one upload-service factory.",
|
|
1690
|
+
"whenItDoesNotApply": "When the binding lives in a module imported transitively from a trust-listed `@dereekb` package.",
|
|
1691
|
+
"canonicalFix": "Add a NestJS provider with `provide: StorageFileInitializeFromUploadService, useFactory: <factory>` to a module imported by the app."
|
|
1692
|
+
},
|
|
1693
|
+
{
|
|
1694
|
+
"code": "STORAGEFILE_UPLOAD_SERVICE_SPREAD_UNRESOLVED",
|
|
1695
|
+
"source": "dbx_storagefile_m_validate_app",
|
|
1696
|
+
"severity": "warning",
|
|
1697
|
+
"title": "A `...spread` element inside the `initializer` array does not resolve",
|
|
1698
|
+
"whatItFlags": "A `...spread` element inside the `initializer` array does not resolve\nto a declared array binding or factory call.",
|
|
1699
|
+
"whenItApplies": "When the spread identifier is local but not declared anywhere reachable.",
|
|
1700
|
+
"whenItDoesNotApply": "Spread identifiers from trust-listed `@dereekb/*` modules.",
|
|
1701
|
+
"canonicalFix": "Declare the spread as `const <name>: StorageFileInitializeFromUploadServiceInitializer[] = [...]` or import it from a trusted module."
|
|
1702
|
+
},
|
|
1703
|
+
{
|
|
1704
|
+
"code": "STORAGEFILE_FOLDER_API_DIR_NOT_FOUND",
|
|
1705
|
+
"source": "dbx_storagefile_m_validate_folder",
|
|
1706
|
+
"severity": "error",
|
|
1707
|
+
"title": "The API app directory does not exist on disk",
|
|
1708
|
+
"whatItFlags": "The API app directory does not exist on disk.",
|
|
1709
|
+
"whenItApplies": "When the supplied `apiDir` does not resolve to a directory entry.",
|
|
1710
|
+
"whenItDoesNotApply": "API apps intentionally not validated — pass `--skip storagefile_m` instead.",
|
|
1711
|
+
"canonicalFix": "Verify the path argument resolves to an existing API app root.",
|
|
1712
|
+
"seeAlso": [
|
|
1713
|
+
{
|
|
1714
|
+
"kind": "tool",
|
|
1715
|
+
"target": "dbx_storagefile_m_validate_folder"
|
|
1716
|
+
}
|
|
1717
|
+
]
|
|
1718
|
+
},
|
|
1719
|
+
{
|
|
1720
|
+
"code": "STORAGEFILE_FOLDER_API_FOLDER_MISSING",
|
|
1721
|
+
"source": "dbx_storagefile_m_validate_folder",
|
|
1722
|
+
"severity": "error",
|
|
1723
|
+
"title": "The API root exists but `src/app/common/model/storagefile/` is missing",
|
|
1724
|
+
"whatItFlags": "The API root exists but `src/app/common/model/storagefile/` is missing.",
|
|
1725
|
+
"whenItApplies": "API apps expected to wire the storagefile module but with no storagefile folder.",
|
|
1726
|
+
"whenItDoesNotApply": "API apps that intentionally don't wire storage uploads — pass `--skip storagefile_m`.",
|
|
1727
|
+
"canonicalFix": "Add `src/app/common/model/storagefile/` with `storagefile.module.ts`, `storagefile.upload.service.ts`, and `storagefile.init.ts`.",
|
|
1728
|
+
"seeAlso": [
|
|
1729
|
+
{
|
|
1730
|
+
"kind": "artifact",
|
|
1731
|
+
"target": "storagefile-purpose"
|
|
1732
|
+
}
|
|
1733
|
+
]
|
|
1734
|
+
},
|
|
1735
|
+
{
|
|
1736
|
+
"code": "STORAGEFILE_FOLDER_BARREL_REEXPORT_MISSING",
|
|
1737
|
+
"source": "dbx_storagefile_m_validate_folder",
|
|
1738
|
+
"severity": "error",
|
|
1739
|
+
"title": "`index.ts` re-exports a path that does not resolve to a sibling file or subfolder",
|
|
1740
|
+
"whatItFlags": "`index.ts` re-exports a path that does not resolve to a sibling file or subfolder.",
|
|
1741
|
+
"whenItApplies": "When `export * from './X'` in `index.ts` has no matching `./X.ts` or `./X/` under the storagefile folder root.",
|
|
1742
|
+
"whenItDoesNotApply": "Re-exports that intentionally point outside the folder (use a relative path that climbs out, not `./X`).",
|
|
1743
|
+
"canonicalFix": "Add the missing `<name>.ts` / `<name>/` sibling, or remove the dangling re-export from `index.ts`."
|
|
1744
|
+
},
|
|
1745
|
+
{
|
|
1746
|
+
"code": "STORAGEFILE_FOLDER_COMPONENT_DIR_NOT_FOUND",
|
|
1747
|
+
"source": "dbx_storagefile_m_validate_folder",
|
|
1748
|
+
"severity": "error",
|
|
1749
|
+
"title": "The component package directory does not exist on disk",
|
|
1750
|
+
"whatItFlags": "The component package directory does not exist on disk.",
|
|
1751
|
+
"whenItApplies": "When the supplied `componentDir` does not resolve to a directory entry.",
|
|
1752
|
+
"whenItDoesNotApply": "Components intentionally not part of this validation pass — pass `--skip storagefile_m` to `dbx_app_validate` instead.",
|
|
1753
|
+
"canonicalFix": "Verify the path argument resolves to an existing component package root.",
|
|
1754
|
+
"seeAlso": [
|
|
1755
|
+
{
|
|
1756
|
+
"kind": "tool",
|
|
1757
|
+
"target": "dbx_storagefile_m_validate_folder"
|
|
1758
|
+
}
|
|
1759
|
+
]
|
|
1760
|
+
},
|
|
1761
|
+
{
|
|
1762
|
+
"code": "STORAGEFILE_FOLDER_COMPONENT_FOLDER_MISSING",
|
|
1763
|
+
"source": "dbx_storagefile_m_validate_folder",
|
|
1764
|
+
"severity": "error",
|
|
1765
|
+
"title": "The component root exists but `src/lib/model/storagefile/` is missing",
|
|
1766
|
+
"whatItFlags": "The component root exists but `src/lib/model/storagefile/` is missing.",
|
|
1767
|
+
"whenItApplies": "Components that should ship `StorageFilePurpose` constants but lack the storagefile model folder.",
|
|
1768
|
+
"whenItDoesNotApply": "Components that intentionally don't extend the storagefile group (rare — most apps with file uploads do).",
|
|
1769
|
+
"canonicalFix": "Run `dbx_artifact_scaffold artifact=\"storagefile-purpose\"` to scaffold the folder, or add `src/lib/model/storagefile/storagefile.ts` by hand.",
|
|
1770
|
+
"seeAlso": [
|
|
1771
|
+
{
|
|
1772
|
+
"kind": "artifact",
|
|
1773
|
+
"target": "storagefile-purpose"
|
|
1774
|
+
}
|
|
1775
|
+
]
|
|
1776
|
+
},
|
|
1777
|
+
{
|
|
1778
|
+
"code": "STORAGEFILE_FOLDER_HANDLERS_SUBFOLDER_MIXED",
|
|
1779
|
+
"source": "dbx_storagefile_m_validate_folder",
|
|
1780
|
+
"severity": "warning",
|
|
1781
|
+
"title": "A non-canonical `.ts` file lives at the API storagefile root alongside a `handlers/` subfolder",
|
|
1782
|
+
"whatItFlags": "A non-canonical `.ts` file lives at the API storagefile root alongside a `handlers/` subfolder.",
|
|
1783
|
+
"whenItApplies": "API folders that mix root-level handler files with a sibling `handlers/` subfolder.",
|
|
1784
|
+
"whenItDoesNotApply": "Strictly canonical files (`storagefile.module.ts`, `storagefile.upload.service.ts`, `storagefile.init.ts`) — those are allowed at the root.",
|
|
1785
|
+
"canonicalFix": "Move the handler file into `handlers/` so the convention stays consistent across the project."
|
|
1786
|
+
},
|
|
1787
|
+
{
|
|
1788
|
+
"code": "STORAGEFILE_FOLDER_INIT_FILE_MISSING",
|
|
1789
|
+
"source": "dbx_storagefile_m_validate_folder",
|
|
1790
|
+
"severity": "error",
|
|
1791
|
+
"title": "The API storagefile folder is missing the required `storagefile.init.ts` file",
|
|
1792
|
+
"whatItFlags": "The API storagefile folder is missing the required `storagefile.init.ts` file.",
|
|
1793
|
+
"whenItApplies": "Every API storagefile folder that exists.",
|
|
1794
|
+
"whenItDoesNotApply": "Apps that don't expose storagefile server-actions on the action context (rare — most do).",
|
|
1795
|
+
"canonicalFix": "Add `storagefile.init.ts` with the storage-file init server-actions config wired through the action context."
|
|
1796
|
+
},
|
|
1797
|
+
{
|
|
1798
|
+
"code": "STORAGEFILE_FOLDER_MODULE_FILE_MISSING",
|
|
1799
|
+
"source": "dbx_storagefile_m_validate_folder",
|
|
1800
|
+
"severity": "error",
|
|
1801
|
+
"title": "The API storagefile folder is missing the required `storagefile.module.ts` file",
|
|
1802
|
+
"whatItFlags": "The API storagefile folder is missing the required `storagefile.module.ts` file.",
|
|
1803
|
+
"whenItApplies": "Every API storagefile folder that exists.",
|
|
1804
|
+
"whenItDoesNotApply": "The NestJS storage-file module is provided elsewhere in the app (rare — convention is one module per folder).",
|
|
1805
|
+
"canonicalFix": "Add `storagefile.module.ts` declaring the NestJS module that binds the upload service provider."
|
|
1806
|
+
},
|
|
1807
|
+
{
|
|
1808
|
+
"code": "STORAGEFILE_FOLDER_UNEXPECTED_FILE_NAME",
|
|
1809
|
+
"source": "dbx_storagefile_m_validate_folder",
|
|
1810
|
+
"severity": "warning",
|
|
1811
|
+
"title": "A `.ts` file in the storagefile folder doesn't start with the `storagefile.` prefix",
|
|
1812
|
+
"whatItFlags": "A `.ts` file in the storagefile folder doesn't start with the `storagefile.` prefix.",
|
|
1813
|
+
"whenItApplies": "Any `.ts` file other than `index.ts` whose basename doesn't start with `storagefile.`.",
|
|
1814
|
+
"whenItDoesNotApply": "Files outside the canonical layout that the project intentionally hosts here (rare — prefer moving them out).",
|
|
1815
|
+
"canonicalFix": "Rename the file to `storagefile.<sub>.ts`, or move it out of the storagefile folder."
|
|
1816
|
+
},
|
|
1817
|
+
{
|
|
1818
|
+
"code": "STORAGEFILE_FOLDER_UPLOAD_SERVICE_FILE_MISSING",
|
|
1819
|
+
"source": "dbx_storagefile_m_validate_folder",
|
|
1820
|
+
"severity": "error",
|
|
1821
|
+
"title": "The API storagefile folder is missing the required `storagefile.upload.service.ts` file",
|
|
1822
|
+
"whatItFlags": "The API storagefile folder is missing the required `storagefile.upload.service.ts` file.",
|
|
1823
|
+
"whenItApplies": "Every API storagefile folder that exists.",
|
|
1824
|
+
"whenItDoesNotApply": "API apps whose upload service is provided by an upstream module imported transitively (rare — usually a missed scaffold step).",
|
|
1825
|
+
"canonicalFix": "Add `storagefile.upload.service.ts` exporting the `storageFileInitializeFromUploadService(...)` factory function.",
|
|
1826
|
+
"seeAlso": [
|
|
1827
|
+
{
|
|
1828
|
+
"kind": "artifact",
|
|
1829
|
+
"target": "storagefile-purpose"
|
|
1830
|
+
}
|
|
1831
|
+
]
|
|
1832
|
+
},
|
|
1833
|
+
{
|
|
1834
|
+
"code": "SYSTEM_CONVERTER_MAP_NOT_LAST",
|
|
1835
|
+
"source": "dbx_system_m_validate_folder",
|
|
1836
|
+
"severity": "warning",
|
|
1837
|
+
"title": "The aggregate `<app>SystemStateStoredDataConverterMap` is not the last top-level export in `system.ts`",
|
|
1838
|
+
"whatItFlags": "The aggregate `<app>SystemStateStoredDataConverterMap` is not the last top-level export in `system.ts`.",
|
|
1839
|
+
"whenItApplies": "When the converter-map declaration appears before another top-level export in `system.ts`.",
|
|
1840
|
+
"whenItDoesNotApply": "Files where the convention isn't followed for project-specific reasons — but it makes scanning the aggregator harder.",
|
|
1841
|
+
"canonicalFix": "Move the `<app>SystemStateStoredDataConverterMap` declaration to the end of `system.ts` so it always sits below the triples it aggregates."
|
|
1842
|
+
},
|
|
1843
|
+
{
|
|
1844
|
+
"code": "SYSTEM_FOLDER_DISALLOWED_FILE",
|
|
1845
|
+
"source": "dbx_system_m_validate_folder",
|
|
1846
|
+
"severity": "error",
|
|
1847
|
+
"title": "A file disallowed at the system folder root is present (`system.id.ts` or `system.query.ts`)",
|
|
1848
|
+
"whatItFlags": "A file disallowed at the system folder root is present (`system.id.ts` or `system.query.ts`).",
|
|
1849
|
+
"whenItApplies": "When the folder contains `system.id.ts` (SystemState identifiers are plain string keys) or `system.query.ts` (documents are fetched by key, not queried).",
|
|
1850
|
+
"whenItDoesNotApply": "No known false-positive cases — the listed files conflict with the SystemState convention.",
|
|
1851
|
+
"canonicalFix": "Delete the disallowed file. The reason is included in the violation message."
|
|
1852
|
+
},
|
|
1853
|
+
{
|
|
1854
|
+
"code": "SYSTEM_FOLDER_MISSING_INDEX",
|
|
1855
|
+
"source": "dbx_system_m_validate_folder",
|
|
1856
|
+
"severity": "error",
|
|
1857
|
+
"title": "Required `index.ts` barrel is missing from the system folder",
|
|
1858
|
+
"whatItFlags": "Required `index.ts` barrel is missing from the system folder.",
|
|
1859
|
+
"whenItApplies": "Every system folder that resolves to an existing directory.",
|
|
1860
|
+
"whenItDoesNotApply": "The base `@dereekb/firebase` system folder — covered above.",
|
|
1861
|
+
"canonicalFix": "Add `index.ts` re-exporting `system.ts` (and any optional siblings) so the folder is consumed through one barrel."
|
|
1862
|
+
},
|
|
1863
|
+
{
|
|
1864
|
+
"code": "SYSTEM_FOLDER_MISSING_MAIN",
|
|
1865
|
+
"source": "dbx_system_m_validate_folder",
|
|
1866
|
+
"severity": "error",
|
|
1867
|
+
"title": "Required `system.ts` main module is missing from the system folder",
|
|
1868
|
+
"whatItFlags": "Required `system.ts` main module is missing from the system folder.",
|
|
1869
|
+
"whenItApplies": "Every system folder that resolves to an existing directory.",
|
|
1870
|
+
"whenItDoesNotApply": "The base `@dereekb/firebase` system folder — that ships machinery (`systemStateIdentity` etc.) and should not be validated with this tool.",
|
|
1871
|
+
"canonicalFix": "Add `system.ts` declaring the downstream `<NAME>_SYSTEM_STATE_TYPE` constants, `<Foo>SystemData` interfaces, converters, and the aggregate `<app>SystemStateStoredDataConverterMap`.",
|
|
1872
|
+
"seeAlso": [
|
|
1873
|
+
{
|
|
1874
|
+
"kind": "doc",
|
|
1875
|
+
"target": "dbx__ref__system-state"
|
|
1876
|
+
}
|
|
1877
|
+
]
|
|
1878
|
+
},
|
|
1879
|
+
{
|
|
1880
|
+
"code": "SYSTEM_FOLDER_NOT_DIRECTORY",
|
|
1881
|
+
"source": "dbx_system_m_validate_folder",
|
|
1882
|
+
"severity": "error",
|
|
1883
|
+
"title": "The supplied path resolves to a file or other non-directory entry",
|
|
1884
|
+
"whatItFlags": "The supplied path resolves to a file or other non-directory entry.",
|
|
1885
|
+
"whenItApplies": "When the path exists but is not a directory.",
|
|
1886
|
+
"whenItDoesNotApply": "File-level system validation — pass the folder, not `system.ts`.",
|
|
1887
|
+
"canonicalFix": "Pass the system folder (e.g. `apps/.../src/lib/model/system/`), not the `system.ts` file inside it."
|
|
1888
|
+
},
|
|
1889
|
+
{
|
|
1890
|
+
"code": "SYSTEM_FOLDER_NOT_FOUND",
|
|
1891
|
+
"source": "dbx_system_m_validate_folder",
|
|
1892
|
+
"severity": "error",
|
|
1893
|
+
"title": "The supplied path does not exist on disk",
|
|
1894
|
+
"whatItFlags": "The supplied path does not exist on disk.",
|
|
1895
|
+
"whenItApplies": "When the folder path argument does not resolve to an entry.",
|
|
1896
|
+
"whenItDoesNotApply": "Glob patterns intentionally matching zero folders — pass at least one valid path.",
|
|
1897
|
+
"canonicalFix": "Verify the path resolves to an existing system model folder under the workspace."
|
|
1898
|
+
},
|
|
1899
|
+
{
|
|
1900
|
+
"code": "SYSTEM_FOLDER_STRAY_FILE",
|
|
1901
|
+
"source": "dbx_system_m_validate_folder",
|
|
1902
|
+
"severity": "warning",
|
|
1903
|
+
"title": "A `.ts` file in the system folder doesn't follow the `system.<sub>.ts` convention",
|
|
1904
|
+
"whatItFlags": "A `.ts` file in the system folder doesn't follow the `system.<sub>.ts` convention.",
|
|
1905
|
+
"whenItApplies": "Any `.ts` file other than `index.ts` whose basename doesn't start with `system.`.",
|
|
1906
|
+
"whenItDoesNotApply": "Files outside the canonical layout that the project intentionally hosts here (rare — prefer moving them out).",
|
|
1907
|
+
"canonicalFix": "Rename the file to `system.<sub>.ts`, or move it out of the system folder."
|
|
1908
|
+
},
|
|
1909
|
+
{
|
|
1910
|
+
"code": "SYSTEM_MISSING_CONVERTER",
|
|
1911
|
+
"source": "dbx_system_m_validate_folder",
|
|
1912
|
+
"severity": "error",
|
|
1913
|
+
"title": "A `<NAME>_SYSTEM_STATE_TYPE` / `<Foo>SystemData` pair has no matching `<foo>SystemDataConverter`",
|
|
1914
|
+
"whatItFlags": "A `<NAME>_SYSTEM_STATE_TYPE` / `<Foo>SystemData` pair has no matching `<foo>SystemDataConverter`.",
|
|
1915
|
+
"whenItApplies": "Every state-type constant whose name normalizes to a `<Foo>SystemData` interface but no `<foo>SystemDataConverter` constant exists.",
|
|
1916
|
+
"whenItDoesNotApply": "Converters provided by an upstream package and re-exported through `system.ts` (rare — usually a missed scaffold step).",
|
|
1917
|
+
"canonicalFix": "Add `export const <foo>SystemDataConverter: SystemStateStoredDataFieldConverterConfig<<Foo>SystemData> = { ... }` adjacent to the interface.",
|
|
1918
|
+
"seeAlso": [
|
|
1919
|
+
{
|
|
1920
|
+
"kind": "doc",
|
|
1921
|
+
"target": "dbx__ref__system-state"
|
|
1922
|
+
}
|
|
1923
|
+
]
|
|
1924
|
+
},
|
|
1925
|
+
{
|
|
1926
|
+
"code": "SYSTEM_MISSING_CONVERTER_MAP",
|
|
1927
|
+
"source": "dbx_system_m_validate_folder",
|
|
1928
|
+
"severity": "error",
|
|
1929
|
+
"title": "`system.ts` declares state-type triples but no aggregate `<app>SystemStateStoredDataConverterMap` is exported",
|
|
1930
|
+
"whatItFlags": "`system.ts` declares state-type triples but no aggregate `<app>SystemStateStoredDataConverterMap` is exported.",
|
|
1931
|
+
"whenItApplies": "When `system.ts` contains at least one `<NAME>_SYSTEM_STATE_TYPE` / `<Foo>SystemData` / `<foo>SystemDataConverter` triple.",
|
|
1932
|
+
"whenItDoesNotApply": "`system.ts` files that declare zero triples (an empty downstream system folder is still valid as long as `system.ts` exists).",
|
|
1933
|
+
"canonicalFix": "Add `export const <app>SystemStateStoredDataConverterMap: SystemStateStoredDataConverterMap = { ... }` mapping each `<NAME>_SYSTEM_STATE_TYPE` to its converter.",
|
|
1934
|
+
"seeAlso": [
|
|
1935
|
+
{
|
|
1936
|
+
"kind": "doc",
|
|
1937
|
+
"target": "dbx__ref__system-state"
|
|
1938
|
+
}
|
|
1939
|
+
]
|
|
1940
|
+
},
|
|
1941
|
+
{
|
|
1942
|
+
"code": "SYSTEM_MISSING_TYPE_CONSTANT",
|
|
1943
|
+
"source": "dbx_system_m_validate_folder",
|
|
1944
|
+
"severity": "error",
|
|
1945
|
+
"title": "A `<Foo>SystemData` interface has no matching `<NAME>_SYSTEM_STATE_TYPE` constant",
|
|
1946
|
+
"whatItFlags": "A `<Foo>SystemData` interface has no matching `<NAME>_SYSTEM_STATE_TYPE` constant.",
|
|
1947
|
+
"whenItApplies": "Every `<Foo>SystemData` interface declared in `system.ts`.",
|
|
1948
|
+
"whenItDoesNotApply": "Interfaces provided by an upstream package and re-exported here (rare — usually a missed scaffold step).",
|
|
1949
|
+
"canonicalFix": "Add `export const <NAME>_SYSTEM_STATE_TYPE: SystemStateType = '<value>'` adjacent to the interface."
|
|
1950
|
+
},
|
|
1951
|
+
{
|
|
1952
|
+
"code": "SYSTEM_ORPHAN_CONVERTER",
|
|
1953
|
+
"source": "dbx_system_m_validate_folder",
|
|
1954
|
+
"severity": "error",
|
|
1955
|
+
"title": "A `<foo>SystemDataConverter` exists with no matching `<Foo>SystemData` interface or `<NAME>_SYSTEM_STATE_TYPE` constant",
|
|
1956
|
+
"whatItFlags": "A `<foo>SystemDataConverter` exists with no matching `<Foo>SystemData` interface or `<NAME>_SYSTEM_STATE_TYPE` constant.",
|
|
1957
|
+
"whenItApplies": "When the converter's prefix has no sibling interface + constant.",
|
|
1958
|
+
"whenItDoesNotApply": "The converter is intentionally re-exported from another package (rare — usually a typo or rename drift).",
|
|
1959
|
+
"canonicalFix": "Either declare the matching interface + constant pair or rename the converter so it pairs with an existing triple."
|
|
1960
|
+
},
|
|
1961
|
+
{
|
|
1962
|
+
"code": "SYSTEM_ORPHAN_TYPE_CONSTANT",
|
|
1963
|
+
"source": "dbx_system_m_validate_folder",
|
|
1964
|
+
"severity": "error",
|
|
1965
|
+
"title": "A `<Foo>SystemData` interface exists but no matching `<NAME>_SYSTEM_STATE_TYPE` constant — pair is orphaned",
|
|
1966
|
+
"whatItFlags": "A `<Foo>SystemData` interface exists but no matching `<NAME>_SYSTEM_STATE_TYPE` constant — pair is orphaned.",
|
|
1967
|
+
"whenItApplies": "When `<Foo>SystemData` is declared without a same-prefix state-type constant.",
|
|
1968
|
+
"whenItDoesNotApply": "The interface is intentionally re-exported from another package (rare — usually a typo or rename drift).",
|
|
1969
|
+
"canonicalFix": "Either declare the matching `<NAME>_SYSTEM_STATE_TYPE` constant or rename the interface so it pairs with an existing constant."
|
|
1970
|
+
},
|
|
1971
|
+
{
|
|
1972
|
+
"code": "SYSTEM_TYPE_NOT_IN_MAP",
|
|
1973
|
+
"source": "dbx_system_m_validate_folder",
|
|
1974
|
+
"severity": "error",
|
|
1975
|
+
"title": "A declared `<NAME>_SYSTEM_STATE_TYPE` constant is not referenced by the aggregate converter map",
|
|
1976
|
+
"whatItFlags": "A declared `<NAME>_SYSTEM_STATE_TYPE` constant is not referenced by the aggregate converter map.",
|
|
1977
|
+
"whenItApplies": "Every state-type constant declared in `system.ts`.",
|
|
1978
|
+
"whenItDoesNotApply": "State types provided by upstream packages (the validator only reports locally declared constants).",
|
|
1979
|
+
"canonicalFix": "Add the constant as a key on `<app>SystemStateStoredDataConverterMap` so the runtime knows which converter to use."
|
|
1980
|
+
},
|
|
1981
|
+
{
|
|
1982
|
+
"code": "SYSTEM_UNKNOWN_MAP_KEY",
|
|
1983
|
+
"source": "dbx_system_m_validate_folder",
|
|
1984
|
+
"severity": "warning",
|
|
1985
|
+
"title": "The aggregate converter map references a key that is not a declared state-type constant in `system.ts`",
|
|
1986
|
+
"whatItFlags": "The aggregate converter map references a key that is not a declared state-type constant in `system.ts`.",
|
|
1987
|
+
"whenItApplies": "When a key on `<app>SystemStateStoredDataConverterMap` is neither a local `<NAME>_SYSTEM_STATE_TYPE` constant nor an imported identifier.",
|
|
1988
|
+
"whenItDoesNotApply": "Keys imported from upstream packages — those are detected via `importedIdentifiers` and skipped.",
|
|
1989
|
+
"canonicalFix": "Either declare the missing constant locally or import it from the upstream package that owns it."
|
|
1990
|
+
}
|
|
1991
|
+
]
|