@dereekb/dbx-components-mcp 13.13.0 → 13.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,2807 +0,0 @@
|
|
|
1
|
-
[
|
|
2
|
-
{
|
|
3
|
-
"code": "DBX_ASSET_AGGREGATOR_MISSING_MEMBER",
|
|
4
|
-
"source": "dbx_asset_validate_app",
|
|
5
|
-
"severity": "error",
|
|
6
|
-
"title": "The aggregator array references an identifier that is not a declared",
|
|
7
|
-
"whatItFlags": "The aggregator array references an identifier that is not a declared\n`AssetPathRef` constant in the file (and is not a trust-listed external).",
|
|
8
|
-
"whenItApplies": "Every aggregator member that does not match a local export.",
|
|
9
|
-
"whenItDoesNotApply": "Identifiers imported from a trust-listed `@dereekb/*` module.",
|
|
10
|
-
"canonicalFix": "Either declare the missing `export const <NAME> = ...` or remove the entry from the aggregator."
|
|
11
|
-
},
|
|
12
|
-
{
|
|
13
|
-
"code": "DBX_ASSET_APP_DIR_NOT_FOUND",
|
|
14
|
-
"source": "dbx_asset_validate_app",
|
|
15
|
-
"severity": "error",
|
|
16
|
-
"title": "The Angular app root does not exist or is not a directory",
|
|
17
|
-
"whatItFlags": "The Angular app root does not exist or is not a directory.",
|
|
18
|
-
"whenItApplies": "When `apiDir` does not resolve to an existing directory.",
|
|
19
|
-
"whenItDoesNotApply": "Backends that don't host an Angular front-end — the asset validator targets the Angular wiring.",
|
|
20
|
-
"canonicalFix": "Pass an `apiDir` that points at the Angular app (e.g. `apps/demo`), not the API app.",
|
|
21
|
-
"seeAlso": [
|
|
22
|
-
{
|
|
23
|
-
"kind": "tool",
|
|
24
|
-
"target": "dbx_asset_validate_folder"
|
|
25
|
-
}
|
|
26
|
-
]
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
"code": "DBX_ASSET_BARREL_MISSING",
|
|
30
|
-
"source": "dbx_asset_validate_app",
|
|
31
|
-
"severity": "warning",
|
|
32
|
-
"title": "The component's barrel `src/lib/index.ts` does not re-export `./assets`",
|
|
33
|
-
"whatItFlags": "The component's barrel `src/lib/index.ts` does not re-export `./assets`.",
|
|
34
|
-
"whenItApplies": "Components whose `src/lib/assets.ts` exists but is not re-exported through the package barrel.",
|
|
35
|
-
"whenItDoesNotApply": "Components that intentionally hide their asset refs from downstream consumers.",
|
|
36
|
-
"canonicalFix": "Add `export * from './assets';` to `<componentDir>/src/lib/index.ts`."
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
"code": "DBX_ASSET_BUILDER_UNKNOWN",
|
|
40
|
-
"source": "dbx_asset_validate_app",
|
|
41
|
-
"severity": "error",
|
|
42
|
-
"title": "An exported asset constant uses a builder callee that is not one of the",
|
|
43
|
-
"whatItFlags": "An exported asset constant uses a builder callee that is not one of the\nfour known `@dereekb/rxjs` builders.",
|
|
44
|
-
"whenItApplies": "Every `export const X = <callee>(...)` whose callee is not `localAsset` / `remoteAsset` / `assetFolder` / `remoteAssetBaseUrl` and not a trusted external.",
|
|
45
|
-
"whenItDoesNotApply": "Builders re-exported from a trust-listed `@dereekb/*` module — those go through the trust list.",
|
|
46
|
-
"canonicalFix": "Use one of `localAsset`, `remoteAsset`, `assetFolder('foo').asset('bar')`, or `remoteAssetBaseUrl('https://...').asset('x')` from `@dereekb/rxjs`."
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
"code": "DBX_ASSET_COMPONENT_DIR_NOT_FOUND",
|
|
50
|
-
"source": "dbx_asset_validate_app",
|
|
51
|
-
"severity": "error",
|
|
52
|
-
"title": "The component package root does not exist or is not a directory",
|
|
53
|
-
"whatItFlags": "The component package root does not exist or is not a directory.",
|
|
54
|
-
"whenItApplies": "When `componentDir` does not resolve to an existing directory.",
|
|
55
|
-
"whenItDoesNotApply": "Components that intentionally don't ship asset refs — pass `--skip asset` to `dbx_app_validate` instead.",
|
|
56
|
-
"canonicalFix": "Pass a `componentDir` that points at a real `-firebase` component package (e.g. `components/demo-firebase`).",
|
|
57
|
-
"seeAlso": [
|
|
58
|
-
{
|
|
59
|
-
"kind": "tool",
|
|
60
|
-
"target": "dbx_asset_validate_folder"
|
|
61
|
-
}
|
|
62
|
-
]
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
"code": "DBX_ASSET_DUPLICATE_PATH",
|
|
66
|
-
"source": "dbx_asset_validate_app",
|
|
67
|
-
"severity": "warning",
|
|
68
|
-
"title": "Two exported `AssetPathRef` constants resolve to the same path or URL",
|
|
69
|
-
"whatItFlags": "Two exported `AssetPathRef` constants resolve to the same path or URL.",
|
|
70
|
-
"whenItApplies": "When more than one constant produces the same `path` (local) or `url` (remote).",
|
|
71
|
-
"whenItDoesNotApply": "Constants intentionally aliased — but this defeats discriminating refs by symbol, so almost always a copy-paste.",
|
|
72
|
-
"canonicalFix": "Choose distinct paths/URLs or fold the duplicates into a single export."
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
"code": "DBX_ASSET_FILE_MISSING",
|
|
76
|
-
"source": "dbx_asset_validate_app",
|
|
77
|
-
"severity": "error",
|
|
78
|
-
"title": "The component does not contain a `src/lib/assets.ts` file",
|
|
79
|
-
"whatItFlags": "The component does not contain a `src/lib/assets.ts` file.",
|
|
80
|
-
"whenItApplies": "Every `-firebase` component package that should expose an `AssetPathRef` catalog.",
|
|
81
|
-
"whenItDoesNotApply": "Components that intentionally don't ship local asset refs.",
|
|
82
|
-
"canonicalFix": "Add `<componentDir>/src/lib/assets.ts` exporting `AssetPathRef` constants and an `AssetPathRef[]` aggregator."
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
"code": "DBX_ASSET_LOCAL_FILE_MISSING",
|
|
86
|
-
"source": "dbx_asset_validate_app",
|
|
87
|
-
"severity": "error",
|
|
88
|
-
"title": "A local asset constant resolves to a path that does not exist under",
|
|
89
|
-
"whatItFlags": "A local asset constant resolves to a path that does not exist under\n`<appDir>/src/assets/`.",
|
|
90
|
-
"whenItApplies": "Every `localAsset(path)` / `assetFolder('folder').asset('file')` reference whose joined path has no matching file under the Angular app's `src/assets/` directory.",
|
|
91
|
-
"whenItDoesNotApply": "Custom `localBaseUrl` configurations passed to `provideDbxAssetLoader` — only the default `/assets/` base is checked.",
|
|
92
|
-
"canonicalFix": "Place the file at `<appDir>/src/assets/<path>` so Angular CLI copies it to the build output."
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
"code": "DBX_ASSET_NO_AGGREGATOR",
|
|
96
|
-
"source": "dbx_asset_validate_app",
|
|
97
|
-
"severity": "warning",
|
|
98
|
-
"title": "`assets.ts` declares no exported `AssetPathRef[]` aggregator constant",
|
|
99
|
-
"whatItFlags": "`assets.ts` declares no exported `AssetPathRef[]` aggregator constant.",
|
|
100
|
-
"whenItApplies": "Components whose `assets.ts` file exists and parses but has no `: AssetPathRef[]`-annotated export.",
|
|
101
|
-
"whenItDoesNotApply": "Components that only need a single ref and intentionally omit the aggregator (rare — most apps want a discoverable list).",
|
|
102
|
-
"canonicalFix": "Add `export const <PROJECT>_ASSETS: AssetPathRef[] = [...];` listing every exported ref."
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
"code": "DBX_ASSET_PROVIDER_IMPORT_MISSING",
|
|
106
|
-
"source": "dbx_asset_validate_app",
|
|
107
|
-
"severity": "warning",
|
|
108
|
-
"title": "`provideDbxAssetLoader` is invoked but not imported from `@dereekb/dbx-core`",
|
|
109
|
-
"whatItFlags": "`provideDbxAssetLoader` is invoked but not imported from `@dereekb/dbx-core`.",
|
|
110
|
-
"whenItApplies": "When the call site exists but the import statement does not name `provideDbxAssetLoader` from `@dereekb/dbx-core`.",
|
|
111
|
-
"whenItDoesNotApply": "Re-exports from a workspace-local barrel that proxies `@dereekb/dbx-core` — but those defeat tree-shaking and are discouraged.",
|
|
112
|
-
"canonicalFix": "Import `provideDbxAssetLoader` directly from `@dereekb/dbx-core`."
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
"code": "DBX_ASSET_PROVIDER_MISSING",
|
|
116
|
-
"source": "dbx_asset_validate_app",
|
|
117
|
-
"severity": "error",
|
|
118
|
-
"title": "The Angular app config does not call `provideDbxAssetLoader(`",
|
|
119
|
-
"whatItFlags": "The Angular app config does not call `provideDbxAssetLoader(`.",
|
|
120
|
-
"whenItApplies": "Every Angular app whose `src/root.app.config.ts` should register the asset loader provider.",
|
|
121
|
-
"whenItDoesNotApply": "Apps that wire the loader from a non-standard config file — extend the scanner if so.",
|
|
122
|
-
"canonicalFix": "Add `provideDbxAssetLoader()` (from `@dereekb/dbx-core`) to the providers array in `<appDir>/src/root.app.config.ts`."
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
"code": "DBX_ASSET_REMOTE_INVALID_URL",
|
|
126
|
-
"source": "dbx_asset_validate_app",
|
|
127
|
-
"severity": "error",
|
|
128
|
-
"title": "A `remoteAsset(...)` or `remoteAssetBaseUrl(...)` argument is not an",
|
|
129
|
-
"whatItFlags": "A `remoteAsset(...)` or `remoteAssetBaseUrl(...)` argument is not an\nabsolute http/https URL.",
|
|
130
|
-
"whenItApplies": "Every remote-builder argument that is a string literal but lacks an `http://` or `https://` prefix.",
|
|
131
|
-
"whenItDoesNotApply": "Arguments built from variables, template strings, or environment values — those cannot be statically validated.",
|
|
132
|
-
"canonicalFix": "Use a literal absolute URL (e.g. `'https://cdn.example.com/data.json'`)."
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
"code": "DBX_ASSET_FOLDER_BARREL_MISSING",
|
|
136
|
-
"source": "dbx_asset_validate_folder",
|
|
137
|
-
"severity": "warning",
|
|
138
|
-
"title": "The component's barrel `src/lib/index.ts` does not re-export `./assets`",
|
|
139
|
-
"whatItFlags": "The component's barrel `src/lib/index.ts` does not re-export `./assets`.",
|
|
140
|
-
"whenItApplies": "Components whose `src/lib/assets.ts` exists but isn't re-exported through the package barrel.",
|
|
141
|
-
"whenItDoesNotApply": "Components that intentionally hide their asset refs from downstream consumers.",
|
|
142
|
-
"canonicalFix": "Add `export * from './assets';` to `<componentDir>/src/lib/index.ts`."
|
|
143
|
-
},
|
|
144
|
-
{
|
|
145
|
-
"code": "DBX_ASSET_FOLDER_COMPONENT_DIR_NOT_FOUND",
|
|
146
|
-
"source": "dbx_asset_validate_folder",
|
|
147
|
-
"severity": "error",
|
|
148
|
-
"title": "The component package root does not exist or is not a directory",
|
|
149
|
-
"whatItFlags": "The component package root does not exist or is not a directory.",
|
|
150
|
-
"whenItApplies": "When `componentDir` does not resolve to an existing directory.",
|
|
151
|
-
"whenItDoesNotApply": "Validating an app that doesn't ship its own component package.",
|
|
152
|
-
"canonicalFix": "Pass a `componentDir` that points at a real `-firebase` component package.",
|
|
153
|
-
"seeAlso": [
|
|
154
|
-
{
|
|
155
|
-
"kind": "tool",
|
|
156
|
-
"target": "dbx_asset_validate_app"
|
|
157
|
-
}
|
|
158
|
-
]
|
|
159
|
-
},
|
|
160
|
-
{
|
|
161
|
-
"code": "DBX_ASSET_FOLDER_FILE_MISSING",
|
|
162
|
-
"source": "dbx_asset_validate_folder",
|
|
163
|
-
"severity": "error",
|
|
164
|
-
"title": "The component does not contain a `src/lib/assets.ts` file",
|
|
165
|
-
"whatItFlags": "The component does not contain a `src/lib/assets.ts` file.",
|
|
166
|
-
"whenItApplies": "Every `-firebase` component package that should expose an `AssetPathRef` catalog.",
|
|
167
|
-
"whenItDoesNotApply": "Components that intentionally don't ship asset refs.",
|
|
168
|
-
"canonicalFix": "Add `<componentDir>/src/lib/assets.ts` exporting `AssetPathRef` constants."
|
|
169
|
-
},
|
|
170
|
-
{
|
|
171
|
-
"code": "DBX_ASSET_FOLDER_NO_EXPORTS",
|
|
172
|
-
"source": "dbx_asset_validate_folder",
|
|
173
|
-
"severity": "warning",
|
|
174
|
-
"title": "`assets.ts` exports neither an `AssetPathRef` constant nor an",
|
|
175
|
-
"whatItFlags": "`assets.ts` exports neither an `AssetPathRef` constant nor an\n`AssetPathRef[]` aggregator.",
|
|
176
|
-
"whenItApplies": "Components whose `assets.ts` parses but exports no asset refs.",
|
|
177
|
-
"whenItDoesNotApply": "Empty placeholders awaiting first-use scaffolding.",
|
|
178
|
-
"canonicalFix": "Use `dbx_asset_scaffold` to add a first ref and aggregator.",
|
|
179
|
-
"seeAlso": [
|
|
180
|
-
{
|
|
181
|
-
"kind": "tool",
|
|
182
|
-
"target": "dbx_asset_scaffold"
|
|
183
|
-
}
|
|
184
|
-
]
|
|
185
|
-
},
|
|
186
|
-
{
|
|
187
|
-
"code": "HANDLER_NAMING_MISMATCH",
|
|
188
|
-
"source": "dbx_model_api_validate_app",
|
|
189
|
-
"severity": "error",
|
|
190
|
-
"title": "A handler name does not follow the canonical",
|
|
191
|
-
"whatItFlags": "A handler name does not follow the canonical\n`<model><Verb>[<Specifier>]` form, so the verb-map cell and the\nhandler symbol drift apart.",
|
|
192
|
-
"whenItApplies": "Every wired handler whose identifier does not match either the full form (`guestbookEntryUpdateInsert`) or the verb-omitted shorthand (`guestbookEntryInsert`) for its cell.",
|
|
193
|
-
"whenItDoesNotApply": "Handlers intentionally aliased to satisfy backwards-compatibility on a public re-export — colocate the alias in the verb-map by name to keep the cell aligned.",
|
|
194
|
-
"canonicalFix": "Rename the handler (or its verb-map binding) to one of the accepted names so the model/verb/specifier triplet is recoverable from the identifier alone."
|
|
195
|
-
},
|
|
196
|
-
{
|
|
197
|
-
"code": "MISSING_HANDLER",
|
|
198
|
-
"source": "dbx_model_api_validate_app",
|
|
199
|
-
"severity": "error",
|
|
200
|
-
"title": "A CRUD entry is declared in the component's `<model>.api.ts` but the",
|
|
201
|
-
"whatItFlags": "A CRUD entry is declared in the component's `<model>.api.ts` but the\nAPI app's verb-map has no matching handler wired in.",
|
|
202
|
-
"whenItApplies": "Every declared `<model>.<verb>.<specifier>` cell that lacks a `<handlerName>:` entry under the corresponding verb in the app's `*FunctionMap`.",
|
|
203
|
-
"whenItDoesNotApply": "When the handler is intentionally not yet wired — declare the api entry inside a `// @ts-expect-error TODO` block, or remove the declaration until the handler lands.",
|
|
204
|
-
"canonicalFix": "Add a handler whose name follows `<model><Verb>[<Specifier>]` (e.g. `guestbookEntryUpdateInsert`) to the app's verb-map and assign it to the matching cell.",
|
|
205
|
-
"seeAlso": [
|
|
206
|
-
{
|
|
207
|
-
"kind": "tool",
|
|
208
|
-
"target": "dbx_model_api_list_app"
|
|
209
|
-
},
|
|
210
|
-
{
|
|
211
|
-
"kind": "tool",
|
|
212
|
-
"target": "dbx_model_api_lookup"
|
|
213
|
-
}
|
|
214
|
-
]
|
|
215
|
-
},
|
|
216
|
-
{
|
|
217
|
-
"code": "ORPHAN_HANDLER",
|
|
218
|
-
"source": "dbx_model_api_validate_app",
|
|
219
|
-
"severity": "error",
|
|
220
|
-
"title": "A handler is wired in the API app's verb-map but no",
|
|
221
|
-
"whatItFlags": "A handler is wired in the API app's verb-map but no\n`<model>.api.ts` in any component declares this CRUD entry.",
|
|
222
|
-
"whenItApplies": "Every cell of the app's verb-map that is not declared by an upstream `*ModelCrudFunctionsConfig`.",
|
|
223
|
-
"whenItDoesNotApply": "Handlers exposed by an upstream `@dereekb/*` package whose api file lives outside the scanned component dirs.",
|
|
224
|
-
"canonicalFix": "Either remove the orphan handler entry, or add the missing CRUD declaration to the matching `<model>.api.ts` so the surface is documented.",
|
|
225
|
-
"seeAlso": [
|
|
226
|
-
{
|
|
227
|
-
"kind": "tool",
|
|
228
|
-
"target": "dbx_model_api_list_app"
|
|
229
|
-
}
|
|
230
|
-
]
|
|
231
|
-
},
|
|
232
|
-
{
|
|
233
|
-
"code": "MODEL_FIREBASE_INDEX_BUILD_FAILED",
|
|
234
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
235
|
-
"severity": "warning",
|
|
236
|
-
"title": "The scan could not run — missing config, missing package.json, or an invalid manifest",
|
|
237
|
-
"whatItFlags": "The scan could not run — missing config, missing package.json, or an invalid manifest.",
|
|
238
|
-
"whenItApplies": "When `buildModelFirebaseIndexManifest` returns any outcome other than `success` (no-config, invalid-scan-config, no-package, invalid-package, invalid-manifest).",
|
|
239
|
-
"whenItDoesNotApply": "Components that successfully build a manifest — their downstream warnings get specific codes.",
|
|
240
|
-
"canonicalFix": "Read the embedded message; add or fix `dbx-mcp.scan.json`, ensure the component has a `package.json`, or correct the manifest shape so extraction can complete."
|
|
241
|
-
},
|
|
242
|
-
{
|
|
243
|
-
"code": "MODEL_FIREBASE_INDEX_COMPLEX_QUERY_BODY",
|
|
244
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
245
|
-
"severity": "error",
|
|
246
|
-
"title": "A tagged query body uses `if` / `switch` / ternary / loop — not branch-free",
|
|
247
|
-
"whatItFlags": "A tagged query body uses `if` / `switch` / ternary / loop — not branch-free.",
|
|
248
|
-
"whenItApplies": "Every `@dbxModelFirebaseIndex`-tagged factory whose body contains a branching construct, except those tagged `@dbxModelFirebaseIndexDispatcher`.",
|
|
249
|
-
"whenItDoesNotApply": "Bodies that only use `??` / `&&` / `||` for argument defaulting — those are still considered branch-free.",
|
|
250
|
-
"canonicalFix": "Split the function into one tagged factory per target index (each branch-free), or — if it only routes between other tagged queries — mark it `@dbxModelFirebaseIndexDispatcher` and return per-index results from each branch.",
|
|
251
|
-
"canonicalFixTemplate": "```ts\n/**\n*",
|
|
252
|
-
"seeAlso": [
|
|
253
|
-
{
|
|
254
|
-
"kind": "tool",
|
|
255
|
-
"target": "dbx_model_firebase_index_validate_app"
|
|
256
|
-
}
|
|
257
|
-
]
|
|
258
|
-
},
|
|
259
|
-
{
|
|
260
|
-
"code": "MODEL_FIREBASE_INDEX_COMPOSITE_ADDED",
|
|
261
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
262
|
-
"severity": "error",
|
|
263
|
-
"title": "A composite index required by tagged factories is missing from the committed `firestore.indexes.json`",
|
|
264
|
-
"whatItFlags": "A composite index required by tagged factories is missing from the committed `firestore.indexes.json`.",
|
|
265
|
-
"whenItApplies": "Every entry in the generated composite set that has no equal entry in the committed JSON.",
|
|
266
|
-
"whenItDoesNotApply": "Factories tagged `@dbxModelFirebaseIndexManual` — their shapes are author-managed and excluded from drift.",
|
|
267
|
-
"canonicalFix": "Run `dbx-cli-generate-firestore-indexes --component <dir>` (and the `scan-model-firebase-indexes` CLI if the manifest is also stale) and commit the regenerated `firestore.indexes.json`."
|
|
268
|
-
},
|
|
269
|
-
{
|
|
270
|
-
"code": "MODEL_FIREBASE_INDEX_COMPOSITE_REMOVED",
|
|
271
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
272
|
-
"severity": "warning",
|
|
273
|
-
"title": "A composite index in the committed `firestore.indexes.json` has no factory backing it",
|
|
274
|
-
"whatItFlags": "A composite index in the committed `firestore.indexes.json` has no factory backing it.",
|
|
275
|
-
"whenItApplies": "Every entry in the committed JSON that has no equal entry in the generated set.",
|
|
276
|
-
"whenItDoesNotApply": "Composites managed by hand — tag the corresponding factory with `@dbxModelFirebaseIndexManual` so the validator treats the deployed shape as expected.",
|
|
277
|
-
"canonicalFix": "Either delete the stale composite, or add a `@dbxModelFirebaseIndexManual` factory describing its shape so the validator treats it as expected."
|
|
278
|
-
},
|
|
279
|
-
{
|
|
280
|
-
"code": "MODEL_FIREBASE_INDEX_DUPLICATE_SLUG",
|
|
281
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
282
|
-
"severity": "warning",
|
|
283
|
-
"title": "Two tagged factories resolve to the same slug — the second is dropped from the manifest",
|
|
284
|
-
"whatItFlags": "Two tagged factories resolve to the same slug — the second is dropped from the manifest.",
|
|
285
|
-
"whenItApplies": "When two `@dbxModelFirebaseIndex` exports share the same `@dbxModelFirebaseIndexSlug` (or the same auto-derived slug from their names).",
|
|
286
|
-
"whenItDoesNotApply": "Intentional aliases — they should target the same composite, in which case keep one factory.",
|
|
287
|
-
"canonicalFix": "Pick distinct slugs (or distinct function names) so each factory is addressable."
|
|
288
|
-
},
|
|
289
|
-
{
|
|
290
|
-
"code": "MODEL_FIREBASE_INDEX_EXCLUDED",
|
|
291
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
292
|
-
"severity": "warning",
|
|
293
|
-
"title": "A tagged factory carries `@dbxModelFirebaseIndexExclude` — its constraints are parsed but the analyzer suppresses composite + fieldOverride emission",
|
|
294
|
-
"whatItFlags": "A tagged factory carries `@dbxModelFirebaseIndexExclude` — its constraints are parsed but the analyzer suppresses composite + fieldOverride emission.",
|
|
295
|
-
"whenItApplies": "Every `@dbxModelFirebaseIndex`-tagged factory that also declares `@dbxModelFirebaseIndexExclude`. The warning fires on every scan so the deliberate exclusion stays auditable in CI logs.",
|
|
296
|
-
"whenItDoesNotApply": "Factories using `@dbxModelFirebaseIndexSkip` (silent — no warning emitted) or `@dbxModelFirebaseIndexManual` (composites are author-managed, no audit signal needed).",
|
|
297
|
-
"canonicalFix": "If the exclusion is no longer required, delete the `@dbxModelFirebaseIndexExclude` tag and let the analyzer emit the implied composite. If the factory should be permanently silent, switch to `@dbxModelFirebaseIndexSkip` and document the rationale next to the tag.",
|
|
298
|
-
"seeAlso": [
|
|
299
|
-
{
|
|
300
|
-
"kind": "tool",
|
|
301
|
-
"target": "dbx_model_firebase_index_validate_app"
|
|
302
|
-
}
|
|
303
|
-
]
|
|
304
|
-
},
|
|
305
|
-
{
|
|
306
|
-
"code": "MODEL_FIREBASE_INDEX_FIELD_OVERRIDE_ADDED",
|
|
307
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
308
|
-
"severity": "error",
|
|
309
|
-
"title": "A `fieldOverrides` entry required by tagged factories is missing from the committed `firestore.indexes.json`",
|
|
310
|
-
"whatItFlags": "A `fieldOverrides` entry required by tagged factories is missing from the committed `firestore.indexes.json`.",
|
|
311
|
-
"whenItApplies": "Every fieldOverride required by an analyzed factory and absent from the committed JSON.",
|
|
312
|
-
"whenItDoesNotApply": "fieldOverrides covered by an `@dbxModelFirebaseIndexManual` factory.",
|
|
313
|
-
"canonicalFix": "Regenerate `firestore.indexes.json` via the scan + generate CLIs and commit."
|
|
314
|
-
},
|
|
315
|
-
{
|
|
316
|
-
"code": "MODEL_FIREBASE_INDEX_FIELD_OVERRIDE_REMOVED",
|
|
317
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
318
|
-
"severity": "warning",
|
|
319
|
-
"title": "A `fieldOverrides` entry exists in the committed JSON but no factory requires it",
|
|
320
|
-
"whatItFlags": "A `fieldOverrides` entry exists in the committed JSON but no factory requires it.",
|
|
321
|
-
"whenItApplies": "Every fieldOverride in the committed JSON without a matching generated entry.",
|
|
322
|
-
"whenItDoesNotApply": "fieldOverrides covered by a hand-managed `@dbxModelFirebaseIndexManual` factory.",
|
|
323
|
-
"canonicalFix": "Either delete the stale entry or add a `@dbxModelFirebaseIndexManual` factory so the validator treats it as expected."
|
|
324
|
-
},
|
|
325
|
-
{
|
|
326
|
-
"code": "MODEL_FIREBASE_INDEX_INDEXES_FILE_INVALID",
|
|
327
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
328
|
-
"severity": "warning",
|
|
329
|
-
"title": "The committed `firestore.indexes.json` exists but could not be parsed",
|
|
330
|
-
"whatItFlags": "The committed `firestore.indexes.json` exists but could not be parsed.",
|
|
331
|
-
"whenItApplies": "When `readFile` succeeds but `JSON.parse` fails, or the top-level value is not an object.",
|
|
332
|
-
"whenItDoesNotApply": "Components whose indexes file is absent — that path emits the missing-file note in the header instead.",
|
|
333
|
-
"canonicalFix": "Restore the file to valid JSON with a top-level `{ \"indexes\": [...], \"fieldOverrides\": [...] }` object — re-run `firebase init firestore` or restore from git history."
|
|
334
|
-
},
|
|
335
|
-
{
|
|
336
|
-
"code": "MODEL_FIREBASE_INDEX_MISSING_MODEL_TAG",
|
|
337
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
338
|
-
"severity": "warning",
|
|
339
|
-
"title": "A tagged factory is missing the required `@dbxModelFirebaseIndexModel <Type>` tag",
|
|
340
|
-
"whatItFlags": "A tagged factory is missing the required `@dbxModelFirebaseIndexModel <Type>` tag.",
|
|
341
|
-
"whenItApplies": "Every `@dbxModelFirebaseIndex`-tagged export.",
|
|
342
|
-
"whenItDoesNotApply": "Helpers that opt out of index emission via `@dbxModelFirebaseIndexSkip` and aren't tagged themselves.",
|
|
343
|
-
"canonicalFix": "Add `@dbxModelFirebaseIndexModel <TypeName>` referencing the Firestore model whose collection the query targets.",
|
|
344
|
-
"canonicalFixTemplate": "```ts\n/**\n*",
|
|
345
|
-
"seeAlso": [
|
|
346
|
-
{
|
|
347
|
-
"kind": "tool",
|
|
348
|
-
"target": "dbx_model_firebase_index_validate_app"
|
|
349
|
-
}
|
|
350
|
-
]
|
|
351
|
-
},
|
|
352
|
-
{
|
|
353
|
-
"code": "MODEL_FIREBASE_INDEX_MISSING_NAME",
|
|
354
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
355
|
-
"severity": "warning",
|
|
356
|
-
"title": "A `@dbxModelFirebaseIndex`-tagged export has no resolvable function name",
|
|
357
|
-
"whatItFlags": "A `@dbxModelFirebaseIndex`-tagged export has no resolvable function name.",
|
|
358
|
-
"whenItApplies": "When the JSDoc marker sits above a default export or an arrow assigned to a non-identifier binding.",
|
|
359
|
-
"whenItDoesNotApply": "Named `export function ...` declarations — the extractor reads the name directly.",
|
|
360
|
-
"canonicalFix": "Convert the export to `export function <name>(...) {}` so the slug + lookup table get a stable identifier.",
|
|
361
|
-
"seeAlso": [
|
|
362
|
-
{
|
|
363
|
-
"kind": "tool",
|
|
364
|
-
"target": "dbx_model_firebase_index_validate_app"
|
|
365
|
-
}
|
|
366
|
-
]
|
|
367
|
-
},
|
|
368
|
-
{
|
|
369
|
-
"code": "MODEL_FIREBASE_INDEX_MISSING_PATHS",
|
|
370
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
371
|
-
"severity": "warning",
|
|
372
|
-
"title": "A tagged body has conditional fields but no `@dbxModelFirebaseIndexPath` declarations",
|
|
373
|
-
"whatItFlags": "A tagged body has conditional fields but no `@dbxModelFirebaseIndexPath` declarations.",
|
|
374
|
-
"whenItApplies": "Legacy fallback when a tagged body somehow has conditional fields after the structural check skipped it. New code paths surface `MODEL_FIREBASE_INDEX_COMPLEX_QUERY_BODY` first.",
|
|
375
|
-
"whenItDoesNotApply": "Branch-free bodies — no path tag is necessary when every constraint executes unconditionally.",
|
|
376
|
-
"canonicalFix": "Add one `@dbxModelFirebaseIndexPath <fields>` tag per call pattern, or restructure into one branch-free factory per target index."
|
|
377
|
-
},
|
|
378
|
-
{
|
|
379
|
-
"code": "MODEL_FIREBASE_INDEX_MULTIPLE_RANGE_FIELDS",
|
|
380
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
381
|
-
"severity": "warning",
|
|
382
|
-
"title": "A constraint sequence has more than one range-filtered field",
|
|
383
|
-
"whatItFlags": "A constraint sequence has more than one range-filtered field.",
|
|
384
|
-
"whenItApplies": "Every analyzed sequence whose `where` calls put `<`, `<=`, `>`, `>=`, `!=`, or `not-in` on more than one field path.",
|
|
385
|
-
"whenItDoesNotApply": "Sequences that range-filter at most one field — Firestore's standard composite-index shape.",
|
|
386
|
-
"canonicalFix": "Restructure the query so only one field has a range filter; convert the others to equality filters or move them into a separate factory."
|
|
387
|
-
},
|
|
388
|
-
{
|
|
389
|
-
"code": "MODEL_FIREBASE_INDEX_NON_DELEGATING_DISPATCHER",
|
|
390
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
391
|
-
"severity": "error",
|
|
392
|
-
"title": "A `@dbxModelFirebaseIndexDispatcher` calls `where` / `orderBy` / a registered helper directly",
|
|
393
|
-
"whatItFlags": "A `@dbxModelFirebaseIndexDispatcher` calls `where` / `orderBy` / a registered helper directly.",
|
|
394
|
-
"whenItApplies": "Every dispatcher whose body emits its own constraints instead of delegating to other tagged query functions.",
|
|
395
|
-
"whenItDoesNotApply": "Dispatchers whose every branch is `return <perIndexQuery>(...)` — the canonical shape.",
|
|
396
|
-
"canonicalFix": "Move the constraint construction into a sibling `@dbxModelFirebaseIndex` factory and have the dispatcher `return` its result. If the function should not be a dispatcher, drop the `@dbxModelFirebaseIndexDispatcher` tag.",
|
|
397
|
-
"seeAlso": [
|
|
398
|
-
{
|
|
399
|
-
"kind": "tool",
|
|
400
|
-
"target": "dbx_model_firebase_index_validate_app"
|
|
401
|
-
}
|
|
402
|
-
]
|
|
403
|
-
},
|
|
404
|
-
{
|
|
405
|
-
"code": "MODEL_FIREBASE_INDEX_ORDERBY_CONFLICT",
|
|
406
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
407
|
-
"severity": "warning",
|
|
408
|
-
"title": "Two `orderBy` calls in the same constraint sequence disagree on direction for the same field",
|
|
409
|
-
"whatItFlags": "Two `orderBy` calls in the same constraint sequence disagree on direction for the same field.",
|
|
410
|
-
"whenItApplies": "When the same field path appears in multiple `orderBy` calls with both `asc` and `desc`.",
|
|
411
|
-
"whenItDoesNotApply": "Sequences with at most one direction per field.",
|
|
412
|
-
"canonicalFix": "Pick one direction per field, or split into two factories — Firestore can only deploy one direction at a time per composite."
|
|
413
|
-
},
|
|
414
|
-
{
|
|
415
|
-
"code": "MODEL_FIREBASE_INDEX_SPEC_FILES_ONLY_VIOLATION",
|
|
416
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
417
|
-
"severity": "error",
|
|
418
|
-
"title": "A factory tagged `@dbxModelFirebaseIndexSpecFilesOnly` is referenced from at least one non-spec file",
|
|
419
|
-
"whatItFlags": "A factory tagged `@dbxModelFirebaseIndexSpecFilesOnly` is referenced from at least one non-spec file.",
|
|
420
|
-
"whenItApplies": "Every `@dbxModelFirebaseIndexSpecFilesOnly` factory whose name appears in a `.ts` file under `apps/`, `components/`, or `packages/` that is NOT a `*.spec.ts` / `*.spec.tsx` file. The tag is a contract that the factory exists for tests only; a production caller breaks that contract and would leak a query shape the index generator deliberately skipped.",
|
|
421
|
-
"whenItDoesNotApply": "Spec-only factories whose references are confined to `*.spec.ts` / `*.spec.tsx` files (the intended state), or factories not tagged `@dbxModelFirebaseIndexSpecFilesOnly`.",
|
|
422
|
-
"canonicalFix": "Either move the production call-site into a tagged, non-spec-only factory (and update its callers), or remove the `@dbxModelFirebaseIndexSpecFilesOnly` tag and ensure the produced composite/fieldOverride is declared so the generator emits the required Firestore index.",
|
|
423
|
-
"seeAlso": [
|
|
424
|
-
{
|
|
425
|
-
"kind": "tool",
|
|
426
|
-
"target": "dbx_model_firebase_index_list_app"
|
|
427
|
-
}
|
|
428
|
-
]
|
|
429
|
-
},
|
|
430
|
-
{
|
|
431
|
-
"code": "MODEL_FIREBASE_INDEX_TRANSITIVE_CYCLE",
|
|
432
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
433
|
-
"severity": "warning",
|
|
434
|
-
"title": "Transitive constraint resolution hit a cycle (`A → B → A`)",
|
|
435
|
-
"whatItFlags": "Transitive constraint resolution hit a cycle (`A → B → A`).",
|
|
436
|
-
"whenItApplies": "When a tagged factory transitively calls itself through one or more other tagged factories.",
|
|
437
|
-
"whenItDoesNotApply": "Composition graphs without back-edges — those resolve cleanly.",
|
|
438
|
-
"canonicalFix": "Break the recursion in source — split the shared constraints into a leaf factory that neither caller re-enters."
|
|
439
|
-
},
|
|
440
|
-
{
|
|
441
|
-
"code": "MODEL_FIREBASE_INDEX_UNANNOTATED_QUERY_HELPER",
|
|
442
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
443
|
-
"severity": "warning",
|
|
444
|
-
"title": "A transitive callee returns `FirestoreQueryConstraint(s)` but is not `@dbxModelFirebaseIndex`-tagged",
|
|
445
|
-
"whatItFlags": "A transitive callee returns `FirestoreQueryConstraint(s)` but is not `@dbxModelFirebaseIndex`-tagged.",
|
|
446
|
-
"whenItApplies": "When a tagged factory inlines an untagged helper that returns query constraints — constraints still splice, but the helper escapes the catalog.",
|
|
447
|
-
"whenItDoesNotApply": "Helpers explicitly marked `@dbxModelFirebaseIndexSkip` — they opt out of emitting their own composite while still contributing to callers.",
|
|
448
|
-
"canonicalFix": "Tag the callee with `@dbxModelFirebaseIndex` (giving it its own composite) or mark it `@dbxModelFirebaseIndexSkip` (excluded but still spliced into callers)."
|
|
449
|
-
},
|
|
450
|
-
{
|
|
451
|
-
"code": "MODEL_FIREBASE_INDEX_UNKNOWN_HELPER",
|
|
452
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
453
|
-
"severity": "warning",
|
|
454
|
-
"title": "A constraint helper is called that the extractor does not recognise",
|
|
455
|
-
"whatItFlags": "A constraint helper is called that the extractor does not recognise.",
|
|
456
|
-
"whenItApplies": "When a tagged body invokes a function named like a helper but absent from `FIRESTORE_QUERY_HELPERS`.",
|
|
457
|
-
"whenItDoesNotApply": "Helpers that resolve via transitive resolution to another tagged factory — those go through `MODEL_FIREBASE_INDEX_UNANNOTATED_QUERY_HELPER` instead.",
|
|
458
|
-
"canonicalFix": "Either swap to a registered helper (e.g. `whereDateIsBeforeWithSort`) or extend `FIRESTORE_QUERY_HELPERS` in `dbx-components-mcp` with a descriptor."
|
|
459
|
-
},
|
|
460
|
-
{
|
|
461
|
-
"code": "MODEL_FIREBASE_INDEX_UNKNOWN_PATH_FIELD",
|
|
462
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
463
|
-
"severity": "warning",
|
|
464
|
-
"title": "`@dbxModelFirebaseIndexPath` references a field no `where` / `orderBy` / helper call in the body produces",
|
|
465
|
-
"whatItFlags": "`@dbxModelFirebaseIndexPath` references a field no `where` / `orderBy` / helper call in the body produces.",
|
|
466
|
-
"whenItApplies": "Every path tag whose field list contains an unknown identifier.",
|
|
467
|
-
"whenItDoesNotApply": "Path tags whose fields all map to body calls.",
|
|
468
|
-
"canonicalFix": "Either fix the field name in the path tag or extend the body to produce that constraint."
|
|
469
|
-
},
|
|
470
|
-
{
|
|
471
|
-
"code": "MODEL_FIREBASE_INDEX_UNRESOLVABLE_TRANSITIVE_CALLEE",
|
|
472
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
473
|
-
"severity": "warning",
|
|
474
|
-
"title": "A transitive callee returns constraints but its declaration is not reachable (likely a cross-package `.d.ts` import)",
|
|
475
|
-
"whatItFlags": "A transitive callee returns constraints but its declaration is not reachable (likely a cross-package `.d.ts` import).",
|
|
476
|
-
"whenItApplies": "When the resolved callee has no body (declaration-only) and so its constraints cannot be spliced.",
|
|
477
|
-
"whenItDoesNotApply": "Callees declared in the scanned source tree — those resolve normally.",
|
|
478
|
-
"canonicalFix": "Inline the constraint sequence locally, or extend `FIRESTORE_QUERY_HELPERS` in `dbx-components-mcp` with a descriptor for the helper."
|
|
479
|
-
},
|
|
480
|
-
{
|
|
481
|
-
"code": "MODEL_FIREBASE_INDEX_UNRESOLVED_FIELD",
|
|
482
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
483
|
-
"severity": "warning",
|
|
484
|
-
"title": "A `where` / `orderBy` / helper call's field-path argument is not a string literal",
|
|
485
|
-
"whatItFlags": "A `where` / `orderBy` / helper call's field-path argument is not a string literal.",
|
|
486
|
-
"whenItApplies": "When the extractor sees an identifier, template, or computed expression in the field-path slot.",
|
|
487
|
-
"whenItDoesNotApply": "Calls whose field path is a plain `'literal'` string — those parse cleanly.",
|
|
488
|
-
"canonicalFix": "Replace the dynamic expression with a string literal. If the path varies, split the factory and use `@dbxModelFirebaseIndexPath` tags."
|
|
489
|
-
},
|
|
490
|
-
{
|
|
491
|
-
"code": "MODEL_FIREBASE_INDEX_UNRESOLVED_MODEL",
|
|
492
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
493
|
-
"severity": "warning",
|
|
494
|
-
"title": "`@dbxModelFirebaseIndexModel` references a type the identity resolver does not know about",
|
|
495
|
-
"whatItFlags": "`@dbxModelFirebaseIndexModel` references a type the identity resolver does not know about.",
|
|
496
|
-
"whenItApplies": "When the model name on the tag does not resolve to a `firestoreModelIdentity(...)` declaration in the scanned project.",
|
|
497
|
-
"whenItDoesNotApply": "Models whose identity lives in an upstream package not included in the scan globs — extend the scan config instead.",
|
|
498
|
-
"canonicalFix": "Either fix the typo or add a `firestoreModelIdentity('<short>', '<plural>')` declaration in the component.",
|
|
499
|
-
"seeAlso": [
|
|
500
|
-
{
|
|
501
|
-
"kind": "doc",
|
|
502
|
-
"target": "dbx__guide__new-model"
|
|
503
|
-
}
|
|
504
|
-
]
|
|
505
|
-
},
|
|
506
|
-
{
|
|
507
|
-
"code": "MODEL_FIREBASE_INDEX_UNSUPPORTED_ARRAY_CONTAINS_ANY",
|
|
508
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
509
|
-
"severity": "warning",
|
|
510
|
-
"title": "A field uses the `array-contains-any` operator — index support is partial",
|
|
511
|
-
"whatItFlags": "A field uses the `array-contains-any` operator — index support is partial.",
|
|
512
|
-
"whenItApplies": "Every constraint sequence with at least one `array-contains-any` `where`.",
|
|
513
|
-
"whenItDoesNotApply": "Queries using `array-contains` (singular) — those have full composite support. Also suppressed when the factory is tagged `@dbxModelFirebaseIndexAllowArrayContainsAny`.",
|
|
514
|
-
"canonicalFix": "Confirm the deployed composite supports `array-contains-any` for the field set and add `@dbxModelFirebaseIndexAllowArrayContainsAny` to silence the advisory, or restructure to `array-contains` with a denormalised flag."
|
|
515
|
-
},
|
|
516
|
-
{
|
|
517
|
-
"code": "MODEL_FIREBASE_INDEX_UNSUPPORTED_SCOPE",
|
|
518
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
519
|
-
"severity": "warning",
|
|
520
|
-
"title": "`@dbxModelFirebaseIndexScope` was set to an unsupported value",
|
|
521
|
-
"whatItFlags": "`@dbxModelFirebaseIndexScope` was set to an unsupported value.",
|
|
522
|
-
"whenItApplies": "Every tagged factory that declares an explicit scope tag.",
|
|
523
|
-
"whenItDoesNotApply": "Factories that omit the tag — scope falls back to COLLECTION_GROUP for nested models, COLLECTION for root models.",
|
|
524
|
-
"canonicalFix": "Set the tag value to exactly `COLLECTION` or `COLLECTION_GROUP`."
|
|
525
|
-
},
|
|
526
|
-
{
|
|
527
|
-
"code": "MODEL_FIREBASE_INDEX_UNUSED_FACTORY",
|
|
528
|
-
"source": "dbx_model_firebase_index_validate_app",
|
|
529
|
-
"severity": "warning",
|
|
530
|
-
"title": "A tagged factory has zero callers anywhere in the workspace",
|
|
531
|
-
"whatItFlags": "A tagged factory has zero callers anywhere in the workspace.",
|
|
532
|
-
"whenItApplies": "Every `@dbxModelFirebaseIndex`-tagged factory whose exported name does not appear in any `.ts` file under `apps/`, `components/`, or `packages/` (excluding `*.d.ts`, `node_modules/`, and build outputs). For regular factories only non-spec callers count toward \"used\" — a factory whose only references are inside `*.spec.ts` files still triggers this warning unless it is opted in via `@dbxModelFirebaseIndexSpecFilesOnly`. The check uses word-boundary text scanning so renames + stale exports surface here.",
|
|
533
|
-
"whenItDoesNotApply": "Factories marked `@dbxModelFirebaseIndexSkip` (the author already opted out of emission), `@dbxModelFirebaseIndexManual` (author-managed index, not necessarily wired through normal call sites), or `@dbxModelFirebaseIndexSpecFilesOnly` that have at least one `*.spec.ts` caller (the intended state for test-only helpers).",
|
|
534
|
-
"canonicalFix": "Either delete the factory (and its `*.query.ts` file if empty), wire up a production caller, or — if the factory is intentionally a `*.spec.ts`-only helper — tag it `@dbxModelFirebaseIndexSpecFilesOnly`. `@dbxModelFirebaseIndexSkip` still works for \"retain pending a future caller\".",
|
|
535
|
-
"seeAlso": [
|
|
536
|
-
{
|
|
537
|
-
"kind": "tool",
|
|
538
|
-
"target": "dbx_model_firebase_index_list_app"
|
|
539
|
-
}
|
|
540
|
-
]
|
|
541
|
-
},
|
|
542
|
-
{
|
|
543
|
-
"code": "archetype-inconsistent",
|
|
544
|
-
"source": "dbx_model_fixture_validate_app",
|
|
545
|
-
"severity": "error",
|
|
546
|
-
"title": "Sub-collection wiring (8-generic factory + parent-aware",
|
|
547
|
-
"whatItFlags": "Sub-collection wiring (8-generic factory + parent-aware\n`getCollection`) without a parent-fixture field on the Params type\n— or vice versa.",
|
|
548
|
-
"whenItApplies": "Sub-collection archetypes (`sub-collection`, `sub-collection-traversal`).",
|
|
549
|
-
"whenItDoesNotApply": "Top-level archetypes (`top-level-simple`, `top-level-with-deps`) — they don't need a parent fixture field.",
|
|
550
|
-
"canonicalFix": "Add the parent fixture field to the Params type (named after the parent's `firestoreModelIdentity` short alias)."
|
|
551
|
-
},
|
|
552
|
-
{
|
|
553
|
-
"code": "forwarder-divergent",
|
|
554
|
-
"source": "dbx_model_fixture_validate_app",
|
|
555
|
-
"severity": "warning",
|
|
556
|
-
"title": "A Fixture forwarder's signature drifts from the Instance method it",
|
|
557
|
-
"whatItFlags": "A Fixture forwarder's signature drifts from the Instance method it\nforwards to.",
|
|
558
|
-
"whenItApplies": "Forwarders whose parameter list, return type, or async-ness differs from the Instance source.",
|
|
559
|
-
"whenItDoesNotApply": "Forwarders that intentionally widen the Instance signature (rare — usually a refactor mismatch).",
|
|
560
|
-
"canonicalFix": "Re-run `dbx_model_fixture_forward` to regenerate the forwarder, or hand-edit the Fixture method to match."
|
|
561
|
-
},
|
|
562
|
-
{
|
|
563
|
-
"code": "forwarder-missing",
|
|
564
|
-
"source": "dbx_model_fixture_validate_app",
|
|
565
|
-
"severity": "warning",
|
|
566
|
-
"title": "An Instance method has no Fixture forwarder",
|
|
567
|
-
"whatItFlags": "An Instance method has no Fixture forwarder.",
|
|
568
|
-
"whenItApplies": "Every public Instance method should have a same-name Fixture forwarder.",
|
|
569
|
-
"whenItDoesNotApply": "Static helpers, private/protected methods, and methods that intentionally exist only on Instance.",
|
|
570
|
-
"canonicalFix": "Run `dbx_model_fixture_forward apiDir=<apiDir> model=<Model>` to scaffold the missing forwarder.",
|
|
571
|
-
"seeAlso": [
|
|
572
|
-
{
|
|
573
|
-
"kind": "tool",
|
|
574
|
-
"target": "dbx_model_fixture_forward"
|
|
575
|
-
}
|
|
576
|
-
]
|
|
577
|
-
},
|
|
578
|
-
{
|
|
579
|
-
"code": "forwarder-not-delegating",
|
|
580
|
-
"source": "dbx_model_fixture_validate_app",
|
|
581
|
-
"severity": "warning",
|
|
582
|
-
"title": "A Fixture forwarder exists but its body re-implements the Instance",
|
|
583
|
-
"whatItFlags": "A Fixture forwarder exists but its body re-implements the Instance\nlogic instead of delegating via `this.instance.<name>(...)`.",
|
|
584
|
-
"whenItApplies": "Forwarders whose body contains anything beyond a delegation call.",
|
|
585
|
-
"whenItDoesNotApply": "Forwarders intentionally adding pre/post hooks (rare; prefer encapsulating the hook in an Instance method).",
|
|
586
|
-
"canonicalFix": "Replace the forwarder body with `return this.instance.<name>(...args)`."
|
|
587
|
-
},
|
|
588
|
-
{
|
|
589
|
-
"code": "generics-misaligned",
|
|
590
|
-
"source": "dbx_model_fixture_validate_app",
|
|
591
|
-
"severity": "error",
|
|
592
|
-
"title": "Model / Document generic args drift between the Fixture class, the",
|
|
593
|
-
"whatItFlags": "Model / Document generic args drift between the Fixture class, the\nInstance class, and the `modelTestContextFactory` call.",
|
|
594
|
-
"whenItApplies": "Every triplet's three generic-bearing positions (Fixture, Instance, factory).",
|
|
595
|
-
"whenItDoesNotApply": "Triplets that intentionally use a wider generic on Fixture (rare — almost always a typo or rename drift).",
|
|
596
|
-
"canonicalFix": "Align the generics on all three positions; the model and document type names should match exactly."
|
|
597
|
-
},
|
|
598
|
-
{
|
|
599
|
-
"code": "model-not-in-registry",
|
|
600
|
-
"source": "dbx_model_fixture_validate_app",
|
|
601
|
-
"severity": "warning",
|
|
602
|
-
"title": "The fixture references a model not in the supplied model registry",
|
|
603
|
-
"whatItFlags": "The fixture references a model not in the supplied model registry.",
|
|
604
|
-
"whenItApplies": "When a model registry is supplied.",
|
|
605
|
-
"whenItDoesNotApply": "Downstream apps without a hooked-up registry — the rule is skipped entirely in that case.",
|
|
606
|
-
"canonicalFix": "Either register the model in the workspace's identity registry or remove the fixture if the model is no longer used."
|
|
607
|
-
},
|
|
608
|
-
{
|
|
609
|
-
"code": "model-without-fixture",
|
|
610
|
-
"source": "dbx_model_fixture_validate_app",
|
|
611
|
-
"severity": "warning",
|
|
612
|
-
"title": "The model registry has the model but the fixture file doesn't",
|
|
613
|
-
"whatItFlags": "The model registry has the model but the fixture file doesn't\ndeclare a TestContext triplet for it.",
|
|
614
|
-
"whenItApplies": "When a model registry is supplied.",
|
|
615
|
-
"whenItDoesNotApply": "Models the app intentionally tests through some other harness (rare).",
|
|
616
|
-
"canonicalFix": "Run `dbx_model_fixture_scaffold apiDir=<apiDir> model=<Model>` to add the missing triplet.",
|
|
617
|
-
"seeAlso": [
|
|
618
|
-
{
|
|
619
|
-
"kind": "tool",
|
|
620
|
-
"target": "dbx_model_fixture_scaffold"
|
|
621
|
-
}
|
|
622
|
-
]
|
|
623
|
-
},
|
|
624
|
-
{
|
|
625
|
-
"code": "params-field-naming",
|
|
626
|
-
"source": "dbx_model_fixture_validate_app",
|
|
627
|
-
"severity": "warning",
|
|
628
|
-
"title": "A parent fixture field's name doesn't match the parent's",
|
|
629
|
-
"whatItFlags": "A parent fixture field's name doesn't match the parent's\n`firestoreModelIdentity` short alias (e.g. `sg` for `SchoolGroup`).",
|
|
630
|
-
"whenItApplies": "When a model registry is supplied AND the field's parent fixture model is registered.",
|
|
631
|
-
"whenItDoesNotApply": "Fields whose parent fixture is intentionally aliased; or runs without a model registry.",
|
|
632
|
-
"canonicalFix": "Rename the field on the Params type to the parent's short alias from `firestoreModelIdentity`."
|
|
633
|
-
},
|
|
634
|
-
{
|
|
635
|
-
"code": "triplet-incomplete",
|
|
636
|
-
"source": "dbx_model_fixture_validate_app",
|
|
637
|
-
"severity": "error",
|
|
638
|
-
"title": "A model is missing one of Fixture / Instance / Params / factory",
|
|
639
|
-
"whatItFlags": "A model is missing one of Fixture / Instance / Params / factory\ncall / singleton — the five-anchor triplet definition is incomplete.",
|
|
640
|
-
"whenItApplies": "Every Firestore-model fixture (`kind === 'firestore-model'`) that has at least one of the anchors.",
|
|
641
|
-
"whenItDoesNotApply": "Skipped for non-Firestore-model fixture pairs: AuthorizedUser-style fixtures (extending `AuthorizedUserTestContextFixture`/`Instance` or registered via `authorizedUserContextFactory`) and pairs tagged with `@dbxFixtureNotModel`.",
|
|
642
|
-
"canonicalFix": "Run `dbx_model_fixture_scaffold apiDir=<apiDir> model=<Model>` to generate the missing pieces; or, if the pair is intentionally not a Firestore model, ensure it extends a recognized framework base or carries `@dbxFixtureNotModel`.",
|
|
643
|
-
"seeAlso": [
|
|
644
|
-
{
|
|
645
|
-
"kind": "tool",
|
|
646
|
-
"target": "dbx_model_fixture_scaffold"
|
|
647
|
-
}
|
|
648
|
-
]
|
|
649
|
-
},
|
|
650
|
-
{
|
|
651
|
-
"code": "MODEL_GROUP_MISSING_CRUD_SPEC",
|
|
652
|
-
"source": "dbx_model_test_validate_app",
|
|
653
|
-
"severity": "warning",
|
|
654
|
-
"title": "A model group declared on the component side has no `<group>.crud.spec.ts`",
|
|
655
|
-
"whatItFlags": "A model group declared on the component side has no `<group>.crud.spec.ts`\nfile on the API side. Every model group is expected to have at least a\nbaseline CRUD spec exercising create / read / update / delete plus\npermission paths. Scenario specs are optional.",
|
|
656
|
-
"whenItApplies": "Every model group enumerated from the `-firebase` component (`<componentDir>/src/lib/model/<group>/`) that doesn't have a matching `<group>.crud.spec.ts` under `<apiDir>/src/app/function/<group>/`.",
|
|
657
|
-
"whenItDoesNotApply": "Reserved folders (`system`, `notification`, `storagefile`) — those follow distinct test layouts. Cross-group integration tests likewise don't satisfy this rule for their host group.",
|
|
658
|
-
"canonicalFix": "Add `<apiDir>/src/app/function/<group>/<group>.crud.spec.ts` covering the CRUD function map for the group. Use `dbx_model_test_convention` to fetch the canonical path.",
|
|
659
|
-
"seeAlso": [
|
|
660
|
-
{
|
|
661
|
-
"kind": "tool",
|
|
662
|
-
"target": "dbx_model_test_convention"
|
|
663
|
-
}
|
|
664
|
-
]
|
|
665
|
-
},
|
|
666
|
-
{
|
|
667
|
-
"code": "TEST_FILE_DRIFT_RENAME",
|
|
668
|
-
"source": "dbx_model_test_validate_app",
|
|
669
|
-
"severity": "warning",
|
|
670
|
-
"title": "Spec filename uses a `crud` / `scenario` segment that is not directly",
|
|
671
|
-
"whatItFlags": "Spec filename uses a `crud` / `scenario` segment that is not directly\nafter the group name (e.g. `worker.payroll.scenario.spec.ts` or\n`worker.pay.crud.spec.ts`). The canonical form places the bucket\nmarker immediately after the group: `<group>.scenario.<sub>.spec.ts`\nor `<group>.crud.<sub>.spec.ts`.",
|
|
672
|
-
"whenItApplies": "Any spec file under `<apiDir>/src/app/function/<group>/` where the `crud` / `scenario` segment is not the first non-group segment.",
|
|
673
|
-
"whenItDoesNotApply": "Canonical subgroup names like `job.crud.requirement.spec.ts` — there `crud` is already first.",
|
|
674
|
-
"canonicalFix": "Rename to the canonical `<group>.<bucket>.<sub>.spec.ts` form. The validator emits the recommended filename as part of the violation message.",
|
|
675
|
-
"seeAlso": [
|
|
676
|
-
{
|
|
677
|
-
"kind": "tool",
|
|
678
|
-
"target": "dbx_model_test_convention"
|
|
679
|
-
}
|
|
680
|
-
]
|
|
681
|
-
},
|
|
682
|
-
{
|
|
683
|
-
"code": "TEST_FILE_MISSING_BUCKET",
|
|
684
|
-
"source": "dbx_model_test_validate_app",
|
|
685
|
-
"severity": "warning",
|
|
686
|
-
"title": "Spec filename is missing a `crud` / `scenario` bucket segment entirely",
|
|
687
|
-
"whatItFlags": "Spec filename is missing a `crud` / `scenario` bucket segment entirely\n(e.g. `worker.system.spec.ts`). The validator can't tell whether the\nfile documents CRUD behavior or a workflow scenario — the author must\nchoose one.",
|
|
688
|
-
"whenItApplies": "Spec files where no segment after the group name is `crud` or `scenario`.",
|
|
689
|
-
"whenItDoesNotApply": "Files that already have a `crud` / `scenario` marker anywhere in the name (those surface `TEST_FILE_DRIFT_RENAME` instead when misplaced).",
|
|
690
|
-
"canonicalFix": "Decide whether the file's tests are CRUD-flavored or scenario-flavored, then rename to `<group>.crud.<sub>.spec.ts` or `<group>.scenario.<sub>.spec.ts`. Default to `scenario` when in doubt.",
|
|
691
|
-
"seeAlso": [
|
|
692
|
-
{
|
|
693
|
-
"kind": "tool",
|
|
694
|
-
"target": "dbx_model_test_convention"
|
|
695
|
-
}
|
|
696
|
-
]
|
|
697
|
-
},
|
|
698
|
-
{
|
|
699
|
-
"code": "TEST_FILE_NON_GROUP_PLACEMENT",
|
|
700
|
-
"source": "dbx_model_test_validate_app",
|
|
701
|
-
"severity": "warning",
|
|
702
|
-
"title": "Spec file's first filename segment doesn't match its parent folder",
|
|
703
|
-
"whatItFlags": "Spec file's first filename segment doesn't match its parent folder\n(e.g. `storagefile.scenario.jobrequirement.spec.ts` placed under the\n`job/` folder). Tests should live in the folder of the model group\nnamed by their filename prefix.",
|
|
704
|
-
"whenItApplies": "Any `.spec.ts` whose first dot-separated segment differs from the immediate parent folder name.",
|
|
705
|
-
"whenItDoesNotApply": "Spec files that intentionally test cross-model integration — move those to the primary group's folder and rename so the prefix matches, or keep them as scenario sub-buckets of one side.",
|
|
706
|
-
"canonicalFix": "Move the file into `<apiDir>/src/app/function/<first-segment>/` so the prefix matches the folder, or rename the file's first segment to match the current folder.",
|
|
707
|
-
"seeAlso": [
|
|
708
|
-
{
|
|
709
|
-
"kind": "tool",
|
|
710
|
-
"target": "dbx_model_test_convention"
|
|
711
|
-
}
|
|
712
|
-
]
|
|
713
|
-
},
|
|
714
|
-
{
|
|
715
|
-
"code": "FILE_GROUP_INTERFACE_AFTER_MODEL",
|
|
716
|
-
"source": "dbx_model_validate",
|
|
717
|
-
"severity": "error",
|
|
718
|
-
"title": "The `<Group>FirestoreCollections` interface is declared after the first model",
|
|
719
|
-
"whatItFlags": "The `<Group>FirestoreCollections` interface is declared after the first model.",
|
|
720
|
-
"whenItApplies": "Every model file with both an interface and at least one model declaration.",
|
|
721
|
-
"whenItDoesNotApply": "Files declaring no models (the interface ordering rule is moot there).",
|
|
722
|
-
"canonicalFix": "Move the `<Group>FirestoreCollections` interface above the first model declaration."
|
|
723
|
-
},
|
|
724
|
-
{
|
|
725
|
-
"code": "FILE_GROUP_INTERFACE_MISSING_COLLECTION",
|
|
726
|
-
"source": "dbx_model_validate",
|
|
727
|
-
"severity": "error",
|
|
728
|
-
"title": "The `<Group>FirestoreCollections` interface is missing the collection entry for one of the file's models",
|
|
729
|
-
"whatItFlags": "The `<Group>FirestoreCollections` interface is missing the collection entry for one of the file's models.",
|
|
730
|
-
"whenItApplies": "Every model in the file must have its `<camelName>Collection` (root) or `<camelName>CollectionFactory` + `<camelName>CollectionGroup` (subcollection) entries on the interface.",
|
|
731
|
-
"whenItDoesNotApply": "Models intentionally excluded from the group container (rare).",
|
|
732
|
-
"canonicalFix": "Add the missing property to the interface declaration."
|
|
733
|
-
},
|
|
734
|
-
{
|
|
735
|
-
"code": "FILE_GROUP_INTERFACE_NOT_EXPORTED",
|
|
736
|
-
"source": "dbx_model_validate",
|
|
737
|
-
"severity": "error",
|
|
738
|
-
"title": "The `<Group>FirestoreCollections` interface is declared but not exported",
|
|
739
|
-
"whatItFlags": "The `<Group>FirestoreCollections` interface is declared but not exported.",
|
|
740
|
-
"whenItApplies": "Every group-collections interface declaration.",
|
|
741
|
-
"whenItDoesNotApply": "When the interface is intentionally module-private (rare — the model wiring needs it cross-file).",
|
|
742
|
-
"canonicalFix": "Add the `export` keyword to the interface declaration."
|
|
743
|
-
},
|
|
744
|
-
{
|
|
745
|
-
"code": "FILE_GROUP_TYPES_AFTER_MODEL",
|
|
746
|
-
"source": "dbx_model_validate",
|
|
747
|
-
"severity": "error",
|
|
748
|
-
"title": "The `<Group>Types` alias is declared after the first model",
|
|
749
|
-
"whatItFlags": "The `<Group>Types` alias is declared after the first model.",
|
|
750
|
-
"whenItApplies": "Every model file with both a types alias and at least one model.",
|
|
751
|
-
"whenItDoesNotApply": "Files declaring no models.",
|
|
752
|
-
"canonicalFix": "Move the `<Group>Types` alias above the first model."
|
|
753
|
-
},
|
|
754
|
-
{
|
|
755
|
-
"code": "FILE_GROUP_TYPES_MISSING_IDENTITY",
|
|
756
|
-
"source": "dbx_model_validate",
|
|
757
|
-
"severity": "error",
|
|
758
|
-
"title": "The `<Group>Types` alias is missing a `typeof <identity>` ref for one of the file's models",
|
|
759
|
-
"whatItFlags": "The `<Group>Types` alias is missing a `typeof <identity>` ref for one of the file's models.",
|
|
760
|
-
"whenItApplies": "Every identity declared in the file must appear in the types union.",
|
|
761
|
-
"whenItDoesNotApply": "When the model is intentionally excluded (rare — the union is the canonical type discriminator).",
|
|
762
|
-
"canonicalFix": "Add `| typeof <identity>` to the union."
|
|
763
|
-
},
|
|
764
|
-
{
|
|
765
|
-
"code": "FILE_GROUP_TYPES_NOT_EXPORTED",
|
|
766
|
-
"source": "dbx_model_validate",
|
|
767
|
-
"severity": "error",
|
|
768
|
-
"title": "The `<Group>Types` alias is declared but not exported",
|
|
769
|
-
"whatItFlags": "The `<Group>Types` alias is declared but not exported.",
|
|
770
|
-
"whenItApplies": "Every group-types alias.",
|
|
771
|
-
"whenItDoesNotApply": "When intentionally module-private (rare — downstream code consumes the union).",
|
|
772
|
-
"canonicalFix": "Add `export` to the type alias declaration."
|
|
773
|
-
},
|
|
774
|
-
{
|
|
775
|
-
"code": "FILE_GROUP_TYPES_UNKNOWN_IDENTITY",
|
|
776
|
-
"source": "dbx_model_validate",
|
|
777
|
-
"severity": "error",
|
|
778
|
-
"title": "The `<Group>Types` alias references an identity that isn't declared in the file",
|
|
779
|
-
"whatItFlags": "The `<Group>Types` alias references an identity that isn't declared in the file.",
|
|
780
|
-
"whenItApplies": "Every identity ref in the union.",
|
|
781
|
-
"whenItDoesNotApply": "When the identity is imported from another file (rare — usually a typo).",
|
|
782
|
-
"canonicalFix": "Either declare the identity in the file or remove the orphaned ref."
|
|
783
|
-
},
|
|
784
|
-
{
|
|
785
|
-
"code": "FILE_MISSING_GROUP_INTERFACE",
|
|
786
|
-
"source": "dbx_model_validate",
|
|
787
|
-
"severity": "error",
|
|
788
|
-
"title": "The file is missing its `<Group>FirestoreCollections` interface",
|
|
789
|
-
"whatItFlags": "The file is missing its `<Group>FirestoreCollections` interface.",
|
|
790
|
-
"whenItApplies": "Every model file (one declaring `firestoreModelIdentity(...)`) must anchor its `<Group>FirestoreCollections` interface above the first model.",
|
|
791
|
-
"whenItDoesNotApply": "Files in `@dereekb/firebase` itself — those are upstream sources owned by the package.",
|
|
792
|
-
"canonicalFix": "Declare `export interface <Group>FirestoreCollections { ... }` above the first `firestoreModelIdentity(...)` call.",
|
|
793
|
-
"seeAlso": [
|
|
794
|
-
{
|
|
795
|
-
"kind": "artifact",
|
|
796
|
-
"target": "firestore-model"
|
|
797
|
-
}
|
|
798
|
-
]
|
|
799
|
-
},
|
|
800
|
-
{
|
|
801
|
-
"code": "FILE_MISSING_GROUP_TYPES",
|
|
802
|
-
"source": "dbx_model_validate",
|
|
803
|
-
"severity": "error",
|
|
804
|
-
"title": "The file is missing its `<Group>Types` union alias",
|
|
805
|
-
"whatItFlags": "The file is missing its `<Group>Types` union alias.",
|
|
806
|
-
"whenItApplies": "Every model file must declare a `<Group>Types` union of `typeof <identity>` covering every model in the file.",
|
|
807
|
-
"whenItDoesNotApply": "Files in `@dereekb/firebase` itself.",
|
|
808
|
-
"canonicalFix": "Add `export type <Group>Types = typeof <Identity1>FirestoreModelIdentity | typeof <Identity2>FirestoreModelIdentity ...`."
|
|
809
|
-
},
|
|
810
|
-
{
|
|
811
|
-
"code": "MODEL_COLLECTION_FACTORY_TYPE_MISMATCH",
|
|
812
|
-
"source": "dbx_model_validate",
|
|
813
|
-
"severity": "error",
|
|
814
|
-
"title": "The collection-type alias kind disagrees with the factory body's `firestoreContext.*` call",
|
|
815
|
-
"whatItFlags": "The collection-type alias kind disagrees with the factory body's `firestoreContext.*` call.",
|
|
816
|
-
"whenItApplies": "When the type alias declares one shape and the factory implements another (e.g. type says `RootSingleItemFirestoreCollection` but body calls `firestoreCollection`).",
|
|
817
|
-
"whenItDoesNotApply": "When the validator can't locate the factory body (rare — emits no rule then).",
|
|
818
|
-
"canonicalFix": "Pick one shape and use it consistently — either change the type alias or change the factory body to match."
|
|
819
|
-
},
|
|
820
|
-
{
|
|
821
|
-
"code": "MODEL_COLLECTION_TYPE_WRONG_GENERIC",
|
|
822
|
-
"source": "dbx_model_validate",
|
|
823
|
-
"severity": "error",
|
|
824
|
-
"title": "The collection type alias uses the wrong generic shape for the model variant",
|
|
825
|
-
"whatItFlags": "The collection type alias uses the wrong generic shape for the model variant.",
|
|
826
|
-
"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.",
|
|
827
|
-
"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).",
|
|
828
|
-
"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.",
|
|
829
|
-
"seeAlso": [
|
|
830
|
-
{
|
|
831
|
-
"kind": "artifact",
|
|
832
|
-
"target": "firestore-model"
|
|
833
|
-
}
|
|
834
|
-
]
|
|
835
|
-
},
|
|
836
|
-
{
|
|
837
|
-
"code": "MODEL_COMPOSITE_KEY_INVALID_ENCODING",
|
|
838
|
-
"source": "dbx_model_validate",
|
|
839
|
-
"severity": "error",
|
|
840
|
-
"title": "The `@dbxModelCompositeKey` tag has an invalid (or missing) `encoding=` argument. Allowed values are `two-way` (round-trips via `inferKeyFromTwoWayFlatFirestoreModelKey`) and `one-way` (slashes stripped, not recoverable)",
|
|
841
|
-
"whatItFlags": "The `@dbxModelCompositeKey` tag has an invalid (or missing) `encoding=` argument. Allowed values are `two-way` (round-trips via `inferKeyFromTwoWayFlatFirestoreModelKey`) and `one-way` (slashes stripped, not recoverable).",
|
|
842
|
-
"whenItApplies": "Every `@dbxModelCompositeKey` tag.",
|
|
843
|
-
"whenItDoesNotApply": "Models without the tag.",
|
|
844
|
-
"canonicalFix": "Set `encoding=two-way` when the source keys must be recoverable from the doc id (the common case). Use `encoding=one-way` only when the source keys are also stored as fields and the doc id only needs to be unique.",
|
|
845
|
-
"seeAlso": [
|
|
846
|
-
{
|
|
847
|
-
"kind": "artifact",
|
|
848
|
-
"target": "firestore-model"
|
|
849
|
-
}
|
|
850
|
-
]
|
|
851
|
-
},
|
|
852
|
-
{
|
|
853
|
-
"code": "MODEL_COMPOSITE_KEY_MISSING_FROM",
|
|
854
|
-
"source": "dbx_model_validate",
|
|
855
|
-
"severity": "error",
|
|
856
|
-
"title": "The `@dbxModelCompositeKey` tag is missing its `from=` argument. The tag must declare either a concrete list of source models (`from=ModelA,ModelB`) or the wildcard form (`from=*`) used by framework models that accept any source identity",
|
|
857
|
-
"whatItFlags": "The `@dbxModelCompositeKey` tag is missing its `from=` argument. The tag must declare either a concrete list of source models (`from=ModelA,ModelB`) or the wildcard form (`from=*`) used by framework models that accept any source identity.",
|
|
858
|
-
"whenItApplies": "Every `@dbxModelCompositeKey` tag.",
|
|
859
|
-
"whenItDoesNotApply": "Models without the tag.",
|
|
860
|
-
"canonicalFix": "Add `from=<ModelA>,<ModelB>` (concrete list) or `from=*` (wildcard for framework models like `NotificationBox`).",
|
|
861
|
-
"seeAlso": [
|
|
862
|
-
{
|
|
863
|
-
"kind": "artifact",
|
|
864
|
-
"target": "firestore-model"
|
|
865
|
-
}
|
|
866
|
-
]
|
|
867
|
-
},
|
|
868
|
-
{
|
|
869
|
-
"code": "MODEL_COMPOSITE_KEY_UNKNOWN_MODEL",
|
|
870
|
-
"source": "dbx_model_validate",
|
|
871
|
-
"severity": "error",
|
|
872
|
-
"title": "A `from=` entry on the `@dbxModelCompositeKey` tag does not resolve to any model in the merged manifest (`@dereekb/firebase` plus every discovered `*-firebase` component). Names are matched case-insensitively against interface name, identity const name (with `Identity` suffix dropped), and `modelType`",
|
|
873
|
-
"whatItFlags": "A `from=` entry on the `@dbxModelCompositeKey` tag does not resolve to any model in the merged manifest (`@dereekb/firebase` plus every discovered `*-firebase` component). Names are matched case-insensitively against interface name, identity const name (with `Identity` suffix dropped), and `modelType`.",
|
|
874
|
-
"whenItApplies": "Each concrete name in the `from=` list. Skipped entirely when the tag uses `from=*`.",
|
|
875
|
-
"whenItDoesNotApply": "Wildcard tags (`from=*`) since their source set is open by design.",
|
|
876
|
-
"canonicalFix": "Fix the typo, or add the missing model to a component the merged manifest scan picks up. The resolver matches interface name, identity const, and modelType.",
|
|
877
|
-
"seeAlso": [
|
|
878
|
-
{
|
|
879
|
-
"kind": "artifact",
|
|
880
|
-
"target": "firestore-model"
|
|
881
|
-
}
|
|
882
|
-
]
|
|
883
|
-
},
|
|
884
|
-
{
|
|
885
|
-
"code": "MODEL_COMPOSITE_KEY_WILDCARD_MIXED",
|
|
886
|
-
"source": "dbx_model_validate",
|
|
887
|
-
"severity": "error",
|
|
888
|
-
"title": "The `@dbxModelCompositeKey` tag mixes the `*` wildcard with concrete model names in its `from=` list (e.g. `from=*,Group`). The wildcard is exclusive — a tag is either fully open (`from=*`) or fully enumerated",
|
|
889
|
-
"whatItFlags": "The `@dbxModelCompositeKey` tag mixes the `*` wildcard with concrete model names in its `from=` list (e.g. `from=*,Group`). The wildcard is exclusive — a tag is either fully open (`from=*`) or fully enumerated.",
|
|
890
|
-
"whenItApplies": "Every `@dbxModelCompositeKey` tag whose `from=` list contains both `*` and at least one other entry.",
|
|
891
|
-
"whenItDoesNotApply": "Tags using only `from=*` or only concrete names.",
|
|
892
|
-
"canonicalFix": "Pick one: replace the list with `from=*` for framework-style models, or remove the `*` and enumerate every contributing model.",
|
|
893
|
-
"seeAlso": [
|
|
894
|
-
{
|
|
895
|
-
"kind": "artifact",
|
|
896
|
-
"target": "firestore-model"
|
|
897
|
-
}
|
|
898
|
-
]
|
|
899
|
-
},
|
|
900
|
-
{
|
|
901
|
-
"code": "MODEL_COMPOSITE_KEY_WITHOUT_ARCHETYPE",
|
|
902
|
-
"source": "dbx_model_validate",
|
|
903
|
-
"severity": "warning",
|
|
904
|
-
"title": "The model carries `@dbxModelCompositeKey` but no archetype tag that justifies the composite-flat-key shape — i.e. neither `@dbxModelArchetype composite-key-root` nor `@dbxModelArchetype denormalised-aggregate` (with `keying=composite-flat-key`) appears on the interface",
|
|
905
|
-
"whatItFlags": "The model carries `@dbxModelCompositeKey` but no archetype tag that justifies the composite-flat-key shape — i.e. neither `@dbxModelArchetype composite-key-root` nor `@dbxModelArchetype denormalised-aggregate` (with `keying=composite-flat-key`) appears on the interface.",
|
|
906
|
-
"whenItApplies": "Every `@dbxModelCompositeKey` tag on a model interface.",
|
|
907
|
-
"whenItDoesNotApply": "Interfaces tagged `composite-key-root` or `denormalised-aggregate keying=composite-flat-key`.",
|
|
908
|
-
"canonicalFix": "Either add the matching `@dbxModelArchetype` tag, or remove the composite-key tag if the model's doc id is not actually a composite-flat-key.",
|
|
909
|
-
"seeAlso": [
|
|
910
|
-
{
|
|
911
|
-
"kind": "artifact",
|
|
912
|
-
"target": "firestore-model"
|
|
913
|
-
}
|
|
914
|
-
]
|
|
915
|
-
},
|
|
916
|
-
{
|
|
917
|
-
"code": "MODEL_CONVERTER_NOT_EXPORTED",
|
|
918
|
-
"source": "dbx_model_validate",
|
|
919
|
-
"severity": "error",
|
|
920
|
-
"title": "The converter constant is declared but not exported",
|
|
921
|
-
"whatItFlags": "The converter constant is declared but not exported.",
|
|
922
|
-
"whenItApplies": "Every converter constant.",
|
|
923
|
-
"whenItDoesNotApply": "When intentionally module-private.",
|
|
924
|
-
"canonicalFix": "Add `export` to the converter declaration."
|
|
925
|
-
},
|
|
926
|
-
{
|
|
927
|
-
"code": "MODEL_DOCUMENT_BAD_TYPE_ARGS",
|
|
928
|
-
"source": "dbx_model_validate",
|
|
929
|
-
"severity": "error",
|
|
930
|
-
"title": "The document class's generic type args don't line up with the model identity / interface",
|
|
931
|
-
"whatItFlags": "The document class's generic type args don't line up with the model identity / interface.",
|
|
932
|
-
"whenItApplies": "Every document class.",
|
|
933
|
-
"whenItDoesNotApply": "When generics are intentionally widened (rare).",
|
|
934
|
-
"canonicalFix": "Pass `<PascalName>, <PascalName>Document>` (root) or include the parent generics for subcollections."
|
|
935
|
-
},
|
|
936
|
-
{
|
|
937
|
-
"code": "MODEL_DOCUMENT_CLASS_NOT_EXPORTED",
|
|
938
|
-
"source": "dbx_model_validate",
|
|
939
|
-
"severity": "error",
|
|
940
|
-
"title": "The document class is declared but not exported",
|
|
941
|
-
"whatItFlags": "The document class is declared but not exported.",
|
|
942
|
-
"whenItApplies": "Every document class.",
|
|
943
|
-
"whenItDoesNotApply": "When intentionally module-private.",
|
|
944
|
-
"canonicalFix": "Add `export` to the class declaration."
|
|
945
|
-
},
|
|
946
|
-
{
|
|
947
|
-
"code": "MODEL_DOCUMENT_MISSING_IDENTITY_GETTER",
|
|
948
|
-
"source": "dbx_model_validate",
|
|
949
|
-
"severity": "error",
|
|
950
|
-
"title": "The document class is missing the `get modelIdentity()` getter",
|
|
951
|
-
"whatItFlags": "The document class is missing the `get modelIdentity()` getter.",
|
|
952
|
-
"whenItApplies": "Every document class.",
|
|
953
|
-
"whenItDoesNotApply": "Document classes inheriting the getter from a custom abstract base (rare).",
|
|
954
|
-
"canonicalFix": "Add `get modelIdentity() { return <identity>; }` returning the matching identity constant."
|
|
955
|
-
},
|
|
956
|
-
{
|
|
957
|
-
"code": "MODEL_DOCUMENT_WRONG_BASE_CLASS",
|
|
958
|
-
"source": "dbx_model_validate",
|
|
959
|
-
"severity": "error",
|
|
960
|
-
"title": "The document class extends an unsupported base class",
|
|
961
|
-
"whatItFlags": "The document class extends an unsupported base class.",
|
|
962
|
-
"whenItApplies": "Every document class — must extend `AbstractFirestoreDocument` (root) or `AbstractFirestoreDocumentWithParent` (subcollection).",
|
|
963
|
-
"whenItDoesNotApply": "Custom document hierarchies (rare; usually a typo).",
|
|
964
|
-
"canonicalFix": "Change the `extends` clause to the canonical base class for the model variant."
|
|
965
|
-
},
|
|
966
|
-
{
|
|
967
|
-
"code": "MODEL_DOCUMENT_WRONG_IDENTITY_GETTER",
|
|
968
|
-
"source": "dbx_model_validate",
|
|
969
|
-
"severity": "error",
|
|
970
|
-
"title": "The document's `get modelIdentity()` returns the wrong identity constant",
|
|
971
|
-
"whatItFlags": "The document's `get modelIdentity()` returns the wrong identity constant.",
|
|
972
|
-
"whenItApplies": "Every document class.",
|
|
973
|
-
"whenItDoesNotApply": "When the rename was intentional (rare — usually a copy-paste).",
|
|
974
|
-
"canonicalFix": "Update the getter body to return the matching identity constant."
|
|
975
|
-
},
|
|
976
|
-
{
|
|
977
|
-
"code": "MODEL_FIELD_LONG_NAME_EQUALS_NAME",
|
|
978
|
-
"source": "dbx_model_validate",
|
|
979
|
-
"severity": "warning",
|
|
980
|
-
"title": "A persisted field's `@dbxModelVariable <longName>` tag value matches the field's short name verbatim, defeating the tag's purpose (the long name should be the field's unabbreviated camelCase variable name)",
|
|
981
|
-
"whatItFlags": "A persisted field's `@dbxModelVariable <longName>` tag value matches the field's short name verbatim, defeating the tag's purpose (the long name should be the field's unabbreviated camelCase variable name).",
|
|
982
|
-
"whenItApplies": "Every field on a `@dbxModel` interface or on a `@dbxModelSubObject`-tagged embedded sub-object interface where `@dbxModelVariable` is present and its value equals the field's name (e.g. field `h` tagged `@dbxModelVariable h`, field `ub` tagged `@dbxModelVariable ub`). The tag must always carry the unabbreviated form so the catalog and decoder surface a meaningful long name.",
|
|
983
|
-
"whenItDoesNotApply": "Fields whose name is already the unabbreviated camelCase form (e.g. `name`, `email`, `id`, `at`) — add those to `dbx-mcp.config.json` `modelValidate.ignoredFieldNames` to silence the warning workspace-wide.",
|
|
984
|
-
"canonicalFix": "Replace the tag value with the field's unabbreviated camelCase variable name (e.g. `@dbxModelVariable h` → `@dbxModelVariable hours`, `@dbxModelVariable ub` → `@dbxModelVariable usedBudget`). To exempt fields whose long name legitimately equals the short name, add them to `modelValidate.ignoredFieldNames`."
|
|
985
|
-
},
|
|
986
|
-
{
|
|
987
|
-
"code": "MODEL_FIELD_MISSING_JSDOC",
|
|
988
|
-
"source": "dbx_model_validate",
|
|
989
|
-
"severity": "warning",
|
|
990
|
-
"title": "A persisted field has no JSDoc description",
|
|
991
|
-
"whatItFlags": "A persisted field has no JSDoc description.",
|
|
992
|
-
"whenItApplies": "Every persisted field — short field names need a JSDoc description so a reader knows what the field is actually for. The long-name itself is carried by the `@dbxModelVariable` tag, so the JSDoc body just needs a one-line description.",
|
|
993
|
-
"whenItDoesNotApply": "Fields whose name is unambiguously self-describing (rare with 1-4 char abbreviations).",
|
|
994
|
-
"canonicalFix": "Add `/** <one-line description> *\\/` above the field declaration (and append `@dbxModelVariable <longName>` for the canonical long name)."
|
|
995
|
-
},
|
|
996
|
-
{
|
|
997
|
-
"code": "MODEL_FIELD_MISSING_VARIABLE_TAG",
|
|
998
|
-
"source": "dbx_model_validate",
|
|
999
|
-
"severity": "warning",
|
|
1000
|
-
"title": "A persisted field is missing its `@dbxModelVariable <name>` JSDoc tag",
|
|
1001
|
-
"whatItFlags": "A persisted field is missing its `@dbxModelVariable <name>` JSDoc tag.",
|
|
1002
|
-
"whenItApplies": "Every field on a `@dbxModel` interface or on a `@dbxModelSubObject`-tagged embedded sub-object interface — the tag carries the human-readable long name the catalog and decoder use when surfacing the field to operators. The long name is the variable name the field would have unabbreviated, written in camelCase (e.g. `uid` → `userUid`, `n` → `name`, `crAt` → `createdAt`).",
|
|
1003
|
-
"whenItDoesNotApply": "Fields on embedded sub-object interfaces that are not tagged with `@dbxModelSubObject` (the tag is opt-in) and fields the project deliberately leaves untagged (rare).",
|
|
1004
|
-
"canonicalFix": "Append `@dbxModelVariable <longName>` to the field's JSDoc block, where `<longName>` is the field's unabbreviated camelCase variable name."
|
|
1005
|
-
},
|
|
1006
|
-
{
|
|
1007
|
-
"code": "MODEL_FIELD_NAME_TOO_LONG",
|
|
1008
|
-
"source": "dbx_model_validate",
|
|
1009
|
-
"severity": "warning",
|
|
1010
|
-
"title": "A persisted field's name exceeds the workspace's 5-character convention",
|
|
1011
|
-
"whatItFlags": "A persisted field's name exceeds the workspace's 5-character convention.",
|
|
1012
|
-
"whenItApplies": "Every persisted field on a model interface (or sub-object interface). The default limit is 5; override via `dbx-mcp.config.json` `modelValidate.maxFieldNameLength`.",
|
|
1013
|
-
"whenItDoesNotApply": "Fields whose name is listed in `dbx-mcp.config.json` `modelValidate.ignoredFieldNames`, or fields that compose well-known multi-character abbreviations the project intentionally allows.",
|
|
1014
|
-
"canonicalFix": "Rename the field to a 1–5 character abbreviation (e.g. `name` → `n`, `userId` → `uid`). To exempt specific names workspace-wide, add them to `modelValidate.ignoredFieldNames` in `dbx-mcp.config.json`."
|
|
1015
|
-
},
|
|
1016
|
-
{
|
|
1017
|
-
"code": "MODEL_GROUP_INTERFACE_MISSING_TAG",
|
|
1018
|
-
"source": "dbx_model_validate",
|
|
1019
|
-
"severity": "error",
|
|
1020
|
-
"title": "The `<Group>FirestoreCollections` interface is missing its `@dbxModelGroup` JSDoc tag",
|
|
1021
|
-
"whatItFlags": "The `<Group>FirestoreCollections` interface is missing its `@dbxModelGroup` JSDoc tag.",
|
|
1022
|
-
"whenItApplies": "Every group container — the rich catalog extractor (`scan/extract-models`) requires the tag to register the group, and downstream traversal/referencing depends on that registration.",
|
|
1023
|
-
"whenItDoesNotApply": "Files in `@dereekb/firebase` itself (upstream-owned sources).",
|
|
1024
|
-
"canonicalFix": "Add `@dbxModelGroup <Group>` to the JSDoc above the `<Group>FirestoreCollections` declaration.",
|
|
1025
|
-
"seeAlso": [
|
|
1026
|
-
{
|
|
1027
|
-
"kind": "artifact",
|
|
1028
|
-
"target": "firestore-model"
|
|
1029
|
-
}
|
|
1030
|
-
]
|
|
1031
|
-
},
|
|
1032
|
-
{
|
|
1033
|
-
"code": "MODEL_IDENTITY_BAD_ARGS",
|
|
1034
|
-
"source": "dbx_model_validate",
|
|
1035
|
-
"severity": "error",
|
|
1036
|
-
"title": "`firestoreModelIdentity(...)` was called with non-string-literal args (or wrong arity)",
|
|
1037
|
-
"whatItFlags": "`firestoreModelIdentity(...)` was called with non-string-literal args (or wrong arity).",
|
|
1038
|
-
"whenItApplies": "Every identity call.",
|
|
1039
|
-
"whenItDoesNotApply": "When the args come from a const (uncommon — the validator can't follow non-literal references).",
|
|
1040
|
-
"canonicalFix": "Pass `(parentIdentity?, '<modelType>', '<prefix>')` as inline string literals."
|
|
1041
|
-
},
|
|
1042
|
-
{
|
|
1043
|
-
"code": "MODEL_IDENTITY_COLLECTION_NAME_DUPLICATE",
|
|
1044
|
-
"source": "dbx_model_validate",
|
|
1045
|
-
"severity": "error",
|
|
1046
|
-
"title": "Two `firestoreModelIdentity(...)` declarations share the same `collectionName` (the lowercase Firestore collection segment passed as the `collectionName` arg, surfaced in the manifest as `collectionPrefix`). Collection names must be globally unique across the merged model manifest — `@dereekb/firebase` upstream plus every discovered `*-firebase` component — because Firestore collection-group queries match by collection name regardless of where the collection sits in the document hierarchy, so two collections sharing a name silently bleed into each other's results",
|
|
1047
|
-
"whatItFlags": "Two `firestoreModelIdentity(...)` declarations share the same `collectionName` (the lowercase Firestore collection segment passed as the `collectionName` arg, surfaced in the manifest as `collectionPrefix`). Collection names must be globally unique across the merged model manifest — `@dereekb/firebase` upstream plus every discovered `*-firebase` component — because Firestore collection-group queries match by collection name regardless of where the collection sits in the document hierarchy, so two collections sharing a name silently bleed into each other's results.",
|
|
1048
|
-
"whenItApplies": "Every `firestoreModelIdentity(...)` declaration discovered by the manifest scan. Anchored at each duplicate occurrence after the first (the first-seen identity is treated as the incumbent). Applies regardless of root vs. subcollection variant — two subcollections under different parents that share a `collectionName` still collide because CollectionGroup queries do not respect parent paths.",
|
|
1049
|
-
"whenItDoesNotApply": "Identities declared outside the merged manifest scan (e.g. packages the discovery layer does not pick up).",
|
|
1050
|
-
"canonicalFix": "Rename one of the conflicting identities so the `collectionName` arg of `firestoreModelIdentity(modelName, collectionName)` is globally unique. Update every Firestore document path / collection-group query that referenced the renamed segment.",
|
|
1051
|
-
"seeAlso": [
|
|
1052
|
-
{
|
|
1053
|
-
"kind": "artifact",
|
|
1054
|
-
"target": "firestore-model"
|
|
1055
|
-
}
|
|
1056
|
-
]
|
|
1057
|
-
},
|
|
1058
|
-
{
|
|
1059
|
-
"code": "MODEL_IDENTITY_MODEL_TYPE_DUPLICATE",
|
|
1060
|
-
"source": "dbx_model_validate",
|
|
1061
|
-
"severity": "error",
|
|
1062
|
-
"title": "Two `firestoreModelIdentity(...)` declarations share the same `modelType` (the camelCase model identifier passed as the first string arg). Model types must be globally unique across the merged model manifest — `@dereekb/firebase` upstream plus every discovered `*-firebase` component — because the model registry, fixture lookup, and key-to-identity decoding all resolve by `modelType`, so a duplicate silently masks one of the two models",
|
|
1063
|
-
"whatItFlags": "Two `firestoreModelIdentity(...)` declarations share the same `modelType` (the camelCase model identifier passed as the first string arg). Model types must be globally unique across the merged model manifest — `@dereekb/firebase` upstream plus every discovered `*-firebase` component — because the model registry, fixture lookup, and key-to-identity decoding all resolve by `modelType`, so a duplicate silently masks one of the two models.",
|
|
1064
|
-
"whenItApplies": "Every `firestoreModelIdentity(...)` declaration discovered by the manifest scan. Anchored at each duplicate occurrence after the first (the first-seen identity is treated as the incumbent). Applies regardless of root vs. subcollection variant.",
|
|
1065
|
-
"whenItDoesNotApply": "Identities declared outside the merged manifest scan.",
|
|
1066
|
-
"canonicalFix": "Rename one of the conflicting identities so the `modelName` arg of `firestoreModelIdentity(modelName, collectionName)` is globally unique. Update every downstream reference to the renamed `modelType`.",
|
|
1067
|
-
"seeAlso": [
|
|
1068
|
-
{
|
|
1069
|
-
"kind": "artifact",
|
|
1070
|
-
"target": "firestore-model"
|
|
1071
|
-
}
|
|
1072
|
-
]
|
|
1073
|
-
},
|
|
1074
|
-
{
|
|
1075
|
-
"code": "MODEL_IDENTITY_NOT_EXPORTED",
|
|
1076
|
-
"source": "dbx_model_validate",
|
|
1077
|
-
"severity": "error",
|
|
1078
|
-
"title": "The model's `firestoreModelIdentity(...)` const is not exported",
|
|
1079
|
-
"whatItFlags": "The model's `firestoreModelIdentity(...)` const is not exported.",
|
|
1080
|
-
"whenItApplies": "Every identity constant.",
|
|
1081
|
-
"whenItDoesNotApply": "When intentionally module-private (rare).",
|
|
1082
|
-
"canonicalFix": "Add `export` to the identity constant declaration."
|
|
1083
|
-
},
|
|
1084
|
-
{
|
|
1085
|
-
"code": "MODEL_IDENTITY_NOT_TAGGED",
|
|
1086
|
-
"source": "dbx_model_validate",
|
|
1087
|
-
"severity": "error",
|
|
1088
|
-
"title": "`firestoreModelIdentity(...)` was found but its corresponding model interface lacks the `@dbxModel` JSDoc tag, leaving the model invisible to the catalog and to downstream traversal/referencing code",
|
|
1089
|
-
"whatItFlags": "`firestoreModelIdentity(...)` was found but its corresponding model interface lacks the `@dbxModel` JSDoc tag, leaving the model invisible to the catalog and to downstream traversal/referencing code.",
|
|
1090
|
-
"whenItApplies": "Every `firestoreModelIdentity(...)` call whose `<PascalName>` interface is missing `@dbxModel`. Anchored at the identity line so the fix points at both the interface and the identity.",
|
|
1091
|
-
"whenItDoesNotApply": "Files in `@dereekb/firebase` itself.",
|
|
1092
|
-
"canonicalFix": "Add `@dbxModel` to the JSDoc on the `<PascalName>` interface so the catalog and decoder recognise it as a model.",
|
|
1093
|
-
"seeAlso": [
|
|
1094
|
-
{
|
|
1095
|
-
"kind": "artifact",
|
|
1096
|
-
"target": "firestore-model"
|
|
1097
|
-
}
|
|
1098
|
-
]
|
|
1099
|
-
},
|
|
1100
|
-
{
|
|
1101
|
-
"code": "MODEL_INTERFACE_MISSING_TAG",
|
|
1102
|
-
"source": "dbx_model_validate",
|
|
1103
|
-
"severity": "error",
|
|
1104
|
-
"title": "The model's data interface is missing its `@dbxModel` JSDoc tag",
|
|
1105
|
-
"whatItFlags": "The model's data interface is missing its `@dbxModel` JSDoc tag.",
|
|
1106
|
-
"whenItApplies": "Every `<PascalName>` interface that anchors a `firestoreModelIdentity(...)` model — the rich catalog extractor (`scan/extract-models`) requires the tag to register the model.",
|
|
1107
|
-
"whenItDoesNotApply": "Embedded sub-object interfaces (no matching identity) and files in `@dereekb/firebase` itself.",
|
|
1108
|
-
"canonicalFix": "Add `@dbxModel` to the JSDoc above the `<PascalName>` interface declaration.",
|
|
1109
|
-
"seeAlso": [
|
|
1110
|
-
{
|
|
1111
|
-
"kind": "artifact",
|
|
1112
|
-
"target": "firestore-model"
|
|
1113
|
-
}
|
|
1114
|
-
]
|
|
1115
|
-
},
|
|
1116
|
-
{
|
|
1117
|
-
"code": "MODEL_INTERFACE_NOT_EXPORTED",
|
|
1118
|
-
"source": "dbx_model_validate",
|
|
1119
|
-
"severity": "error",
|
|
1120
|
-
"title": "The model's data interface is declared but not exported",
|
|
1121
|
-
"whatItFlags": "The model's data interface is declared but not exported.",
|
|
1122
|
-
"whenItApplies": "Every model interface declaration.",
|
|
1123
|
-
"whenItDoesNotApply": "When intentionally module-private (rare).",
|
|
1124
|
-
"canonicalFix": "Add `export` to the interface declaration."
|
|
1125
|
-
},
|
|
1126
|
-
{
|
|
1127
|
-
"code": "MODEL_MISSING_COLLECTION_FN",
|
|
1128
|
-
"source": "dbx_model_validate",
|
|
1129
|
-
"severity": "error",
|
|
1130
|
-
"title": "The model has no `<camelName>FirestoreCollection` (root) or `<camelName>FirestoreCollectionFactory` (subcollection) function",
|
|
1131
|
-
"whatItFlags": "The model has no `<camelName>FirestoreCollection` (root) or `<camelName>FirestoreCollectionFactory` (subcollection) function.",
|
|
1132
|
-
"whenItApplies": "Every model.",
|
|
1133
|
-
"whenItDoesNotApply": "When the function is intentionally inlined (rare).",
|
|
1134
|
-
"canonicalFix": "Declare the matching factory function."
|
|
1135
|
-
},
|
|
1136
|
-
{
|
|
1137
|
-
"code": "MODEL_MISSING_COLLECTION_REFERENCE",
|
|
1138
|
-
"source": "dbx_model_validate",
|
|
1139
|
-
"severity": "error",
|
|
1140
|
-
"title": "The model has no collection-reference function (`<camelName>CollectionReference` for root or `<camelName>CollectionReferenceFactory` for subcollection)",
|
|
1141
|
-
"whatItFlags": "The model has no collection-reference function (`<camelName>CollectionReference` for root or `<camelName>CollectionReferenceFactory` for subcollection).",
|
|
1142
|
-
"whenItApplies": "Every model.",
|
|
1143
|
-
"whenItDoesNotApply": "Models that intentionally bypass the canonical reference shape.",
|
|
1144
|
-
"canonicalFix": "Declare the matching reference function next to the converter."
|
|
1145
|
-
},
|
|
1146
|
-
{
|
|
1147
|
-
"code": "MODEL_MISSING_COLLECTION_TYPE",
|
|
1148
|
-
"source": "dbx_model_validate",
|
|
1149
|
-
"severity": "error",
|
|
1150
|
-
"title": "The model has no `<PascalName>FirestoreCollection` type alias",
|
|
1151
|
-
"whatItFlags": "The model has no `<PascalName>FirestoreCollection` type alias.",
|
|
1152
|
-
"whenItApplies": "Every model.",
|
|
1153
|
-
"whenItDoesNotApply": "When intentionally re-using a parent type (rare).",
|
|
1154
|
-
"canonicalFix": "Declare `export type <PascalName>FirestoreCollection = FirestoreCollection<<PascalName>, <PascalName>Document>;`."
|
|
1155
|
-
},
|
|
1156
|
-
{
|
|
1157
|
-
"code": "MODEL_MISSING_CONVERTER",
|
|
1158
|
-
"source": "dbx_model_validate",
|
|
1159
|
-
"severity": "error",
|
|
1160
|
-
"title": "The model has no `<camelName>Converter` constant",
|
|
1161
|
-
"whatItFlags": "The model has no `<camelName>Converter` constant.",
|
|
1162
|
-
"whenItApplies": "Every model in the file.",
|
|
1163
|
-
"whenItDoesNotApply": "Models intentionally sharing a converter (rare).",
|
|
1164
|
-
"canonicalFix": "Declare `export const <camelName>Converter = snapshotConverterFunctions<<PascalName>>({ fields: { ... } });`."
|
|
1165
|
-
},
|
|
1166
|
-
{
|
|
1167
|
-
"code": "MODEL_MISSING_DOCUMENT_CLASS",
|
|
1168
|
-
"source": "dbx_model_validate",
|
|
1169
|
-
"severity": "error",
|
|
1170
|
-
"title": "The model has no matching `<PascalName>Document` class",
|
|
1171
|
-
"whatItFlags": "The model has no matching `<PascalName>Document` class.",
|
|
1172
|
-
"whenItApplies": "Every model in the file.",
|
|
1173
|
-
"whenItDoesNotApply": "Models intentionally extending a shared document class.",
|
|
1174
|
-
"canonicalFix": "Declare `export class <PascalName>Document extends AbstractFirestoreDocument<...> { ... }`."
|
|
1175
|
-
},
|
|
1176
|
-
{
|
|
1177
|
-
"code": "MODEL_MISSING_INTERFACE",
|
|
1178
|
-
"source": "dbx_model_validate",
|
|
1179
|
-
"severity": "error",
|
|
1180
|
-
"title": "The model has no matching data interface (`<PascalName>`)",
|
|
1181
|
-
"whatItFlags": "The model has no matching data interface (`<PascalName>`).",
|
|
1182
|
-
"whenItApplies": "Every model in the file.",
|
|
1183
|
-
"whenItDoesNotApply": "Models that intentionally reuse another file's interface (rare).",
|
|
1184
|
-
"canonicalFix": "Declare `export interface <PascalName> extends FirestoreModelData { ... }`.",
|
|
1185
|
-
"seeAlso": [
|
|
1186
|
-
{
|
|
1187
|
-
"kind": "artifact",
|
|
1188
|
-
"target": "firestore-model"
|
|
1189
|
-
}
|
|
1190
|
-
]
|
|
1191
|
-
},
|
|
1192
|
-
{
|
|
1193
|
-
"code": "MODEL_MISSING_ROLES",
|
|
1194
|
-
"source": "dbx_model_validate",
|
|
1195
|
-
"severity": "error",
|
|
1196
|
-
"title": "The model has no matching `<PascalName>Roles` type alias",
|
|
1197
|
-
"whatItFlags": "The model has no matching `<PascalName>Roles` type alias.",
|
|
1198
|
-
"whenItApplies": "Every model in the file.",
|
|
1199
|
-
"whenItDoesNotApply": "Models that intentionally reuse a parent's role union (rare).",
|
|
1200
|
-
"canonicalFix": "Declare `export type <PascalName>Roles = 'role-a' | 'role-b' | ...`."
|
|
1201
|
-
},
|
|
1202
|
-
{
|
|
1203
|
-
"code": "MODEL_OUT_OF_ORDER",
|
|
1204
|
-
"source": "dbx_model_validate",
|
|
1205
|
-
"severity": "error",
|
|
1206
|
-
"title": "The model's declarations are out of canonical order",
|
|
1207
|
-
"whatItFlags": "The model's declarations are out of canonical order.",
|
|
1208
|
-
"whenItApplies": "Every model — declarations follow the order: identity, interface, rolesType, documentClass, converter, referenceFn, collectionType, collectionFn (root) or … collectionFactoryType, collectionFn, referenceGroupFn, collectionGroupType, collectionGroupFn (subcollection).",
|
|
1209
|
-
"whenItDoesNotApply": "Files where multiple models intentionally interleave (rare; prefer one-model-per-file).",
|
|
1210
|
-
"canonicalFix": "Re-order the declarations to match the canonical sequence."
|
|
1211
|
-
},
|
|
1212
|
-
{
|
|
1213
|
-
"code": "MODEL_ROLES_NOT_EXPORTED",
|
|
1214
|
-
"source": "dbx_model_validate",
|
|
1215
|
-
"severity": "error",
|
|
1216
|
-
"title": "The roles type is declared but not exported",
|
|
1217
|
-
"whatItFlags": "The roles type is declared but not exported.",
|
|
1218
|
-
"whenItApplies": "Every roles type alias.",
|
|
1219
|
-
"whenItDoesNotApply": "When intentionally module-private.",
|
|
1220
|
-
"canonicalFix": "Add `export` to the alias."
|
|
1221
|
-
},
|
|
1222
|
-
{
|
|
1223
|
-
"code": "MODEL_SUBOBJECT_NOT_TAGGED",
|
|
1224
|
-
"source": "dbx_model_validate",
|
|
1225
|
-
"severity": "warning",
|
|
1226
|
-
"title": "An interface is referenced as the first generic type-argument of a sub-object factory call (`firestoreSubObject<T>(...)`, `firestoreObjectArray<T>(...)`, or `firestoreMap<T>(...)`) but its declaration carries neither `@dbxModel` nor `@dbxModelSubObject`. The interface therefore opts out of the workspace's `@dbxModelVariable` long-name conventions even though its fields are persisted to Firestore",
|
|
1227
|
-
"whatItFlags": "An interface is referenced as the first generic type-argument of a sub-object factory call (`firestoreSubObject<T>(...)`, `firestoreObjectArray<T>(...)`, or `firestoreMap<T>(...)`) but its declaration carries neither `@dbxModel` nor `@dbxModelSubObject`. The interface therefore opts out of the workspace's `@dbxModelVariable` long-name conventions even though its fields are persisted to Firestore.",
|
|
1228
|
-
"whenItApplies": "Any interface declared in the validated source set that is the type-arg of at least one sub-object factory call and lacks both `@dbxModel` and `@dbxModelSubObject`. The warning is emitted once per interface (de-duplicated across all call sites) and anchored at the interface declaration line. Unresolved type-args — interfaces declared outside the validated source set, generic parameters, inline types — are silently skipped to avoid false positives.",
|
|
1229
|
-
"whenItDoesNotApply": "Interfaces already tagged with `@dbxModel` (top-level models) or `@dbxModelSubObject` (embedded sub-objects), and interfaces referenced only from outside the supplied source set (different package, etc.).",
|
|
1230
|
-
"canonicalFix": "Add `@dbxModelSubObject` to the interface's JSDoc block so its fields are subject to `@dbxModelVariable` long-name checks. If the interface is actually a top-level Firestore model, declare a matching `firestoreModelIdentity` and tag it `@dbxModel` instead.",
|
|
1231
|
-
"seeAlso": [
|
|
1232
|
-
{
|
|
1233
|
-
"kind": "artifact",
|
|
1234
|
-
"target": "firestore-model"
|
|
1235
|
-
}
|
|
1236
|
-
]
|
|
1237
|
-
},
|
|
1238
|
-
{
|
|
1239
|
-
"code": "MODEL_SUBOBJECT_PARENT_NOT_TAGGED",
|
|
1240
|
-
"source": "dbx_model_validate",
|
|
1241
|
-
"severity": "warning",
|
|
1242
|
-
"title": "A `@dbxModelSubObject` interface extends a parent interface that is not itself tagged with `@dbxModel` or `@dbxModelSubObject`. The parent's persisted fields flow through the sub-object's converter but never reach the workspace's `@dbxModelVariable` long-name checks. Whether the agent acts depends on whether the parent is owned by this package, but the validator surfaces both classifications so the consuming agent (or developer) can make an informed call",
|
|
1243
|
-
"whatItFlags": "A `@dbxModelSubObject` interface extends a parent interface that is not itself tagged with `@dbxModel` or `@dbxModelSubObject`. The parent's persisted fields flow through the sub-object's converter but never reach the workspace's `@dbxModelVariable` long-name checks. Whether the agent acts depends on whether the parent is owned by this package, but the validator surfaces both classifications so the consuming agent (or developer) can make an informed call.",
|
|
1244
|
-
"whenItApplies": "Every `@dbxModelSubObject` interface whose `extends` heritage names an untagged parent. The parent is classified `in-package` when its declaration is found in the validated source set, otherwise `external`. Anchored at the sub-object interface line so the caller sees both the child and the parent in one place.",
|
|
1245
|
-
"whenItDoesNotApply": "Parents already tagged with `@dbxModel` or `@dbxModelSubObject`; parents whose names appear in `modelValidate.ignoredExternalParents` (suppresses external-only warnings — in-package parents are never suppressed). Generic parameters, inline types, and TS utility wrappers (`Partial<T>`, `Pick<T, K>`, `Omit<T, K>`, `Readonly<T>`, `MaybeMap<T>`) are unwrapped to the underlying parent name before resolution.",
|
|
1246
|
-
"canonicalFix": "In-package parent: add `@dbxModelSubObject` to the parent interface's JSDoc and tag each persisted field with `@dbxModelVariable <longName>`. Alternative: redeclare the inherited fields directly on the child with their own JSDoc + tag (useful when the parent is a shared shape that shouldn't commit to a single longName). External parent: redeclare the inherited fields on the child with `@dbxModelVariable <longName>` tags when surface long-names are needed, or add the parent name to `modelValidate.ignoredExternalParents` in `dbx-mcp.config.json` when the inherited fields are framework plumbing (e.g. `IndexRef.i`, `DateRange.start/end`).",
|
|
1247
|
-
"seeAlso": [
|
|
1248
|
-
{
|
|
1249
|
-
"kind": "artifact",
|
|
1250
|
-
"target": "firestore-model"
|
|
1251
|
-
}
|
|
1252
|
-
]
|
|
1253
|
-
},
|
|
1254
|
-
{
|
|
1255
|
-
"code": "MODEL_SUBOBJECT_TAG_CONFLICT",
|
|
1256
|
-
"source": "dbx_model_validate",
|
|
1257
|
-
"severity": "error",
|
|
1258
|
-
"title": "An interface declaration carries both `@dbxModel` and `@dbxModelSubObject` JSDoc tags. The two tags model mutually exclusive concepts — `@dbxModel` marks a top-level Firestore model registered in the catalog via `firestoreModelIdentity`, while `@dbxModelSubObject` marks an embedded sub-object interface persisted only as part of a parent model's converter — so an interface must carry at most one",
|
|
1259
|
-
"whatItFlags": "An interface declaration carries both `@dbxModel` and `@dbxModelSubObject` JSDoc tags. The two tags model mutually exclusive concepts — `@dbxModel` marks a top-level Firestore model registered in the catalog via `firestoreModelIdentity`, while `@dbxModelSubObject` marks an embedded sub-object interface persisted only as part of a parent model's converter — so an interface must carry at most one.",
|
|
1260
|
-
"whenItApplies": "Any interface JSDoc block where both `@dbxModel` and `@dbxModelSubObject` are present.",
|
|
1261
|
-
"whenItDoesNotApply": "Interfaces carrying only one of the two tags (or neither).",
|
|
1262
|
-
"canonicalFix": "Remove whichever tag does not describe the interface. If the interface has a matching `firestoreModelIdentity` call, keep `@dbxModel`; if it is only embedded inside another model via `firestoreSubObject<T>()`, keep `@dbxModelSubObject`."
|
|
1263
|
-
},
|
|
1264
|
-
{
|
|
1265
|
-
"code": "SUB_MISSING_COLLECTION_FACTORY_FN",
|
|
1266
|
-
"source": "dbx_model_validate",
|
|
1267
|
-
"severity": "error",
|
|
1268
|
-
"title": "Subcollection model is missing its `<camelName>FirestoreCollectionFactory` function",
|
|
1269
|
-
"whatItFlags": "Subcollection model is missing its `<camelName>FirestoreCollectionFactory` function.",
|
|
1270
|
-
"whenItApplies": "Every subcollection model.",
|
|
1271
|
-
"whenItDoesNotApply": "Root models.",
|
|
1272
|
-
"canonicalFix": "Declare `export function <camelName>FirestoreCollectionFactory(...)`."
|
|
1273
|
-
},
|
|
1274
|
-
{
|
|
1275
|
-
"code": "SUB_MISSING_COLLECTION_FACTORY_TYPE",
|
|
1276
|
-
"source": "dbx_model_validate",
|
|
1277
|
-
"severity": "error",
|
|
1278
|
-
"title": "Subcollection model is missing its `<PascalName>FirestoreCollectionFactory` type alias",
|
|
1279
|
-
"whatItFlags": "Subcollection model is missing its `<PascalName>FirestoreCollectionFactory` type alias.",
|
|
1280
|
-
"whenItApplies": "Every subcollection model.",
|
|
1281
|
-
"whenItDoesNotApply": "Root models.",
|
|
1282
|
-
"canonicalFix": "Declare `export type <PascalName>FirestoreCollectionFactory = FirestoreCollectionWithParentFactory<...>;`."
|
|
1283
|
-
},
|
|
1284
|
-
{
|
|
1285
|
-
"code": "SUB_MISSING_COLLECTION_GROUP_FN",
|
|
1286
|
-
"source": "dbx_model_validate",
|
|
1287
|
-
"severity": "error",
|
|
1288
|
-
"title": "Subcollection model is missing its `<camelName>FirestoreCollectionGroup` function",
|
|
1289
|
-
"whatItFlags": "Subcollection model is missing its `<camelName>FirestoreCollectionGroup` function.",
|
|
1290
|
-
"whenItApplies": "Every subcollection model.",
|
|
1291
|
-
"whenItDoesNotApply": "Root models.",
|
|
1292
|
-
"canonicalFix": "Declare `export function <camelName>FirestoreCollectionGroup(firestoreContext)`."
|
|
1293
|
-
},
|
|
1294
|
-
{
|
|
1295
|
-
"code": "SUB_MISSING_COLLECTION_GROUP_REFERENCE",
|
|
1296
|
-
"source": "dbx_model_validate",
|
|
1297
|
-
"severity": "error",
|
|
1298
|
-
"title": "Subcollection model is missing its `<camelName>CollectionGroup` reference function",
|
|
1299
|
-
"whatItFlags": "Subcollection model is missing its `<camelName>CollectionGroup` reference function.",
|
|
1300
|
-
"whenItApplies": "Every subcollection model.",
|
|
1301
|
-
"whenItDoesNotApply": "Root models — they don't have a collection-group concept.",
|
|
1302
|
-
"canonicalFix": "Declare `export function <camelName>CollectionGroup(firestoreContext)`."
|
|
1303
|
-
},
|
|
1304
|
-
{
|
|
1305
|
-
"code": "SUB_MISSING_COLLECTION_GROUP_TYPE",
|
|
1306
|
-
"source": "dbx_model_validate",
|
|
1307
|
-
"severity": "error",
|
|
1308
|
-
"title": "Subcollection model is missing its `<PascalName>FirestoreCollectionGroup` type alias",
|
|
1309
|
-
"whatItFlags": "Subcollection model is missing its `<PascalName>FirestoreCollectionGroup` type alias.",
|
|
1310
|
-
"whenItApplies": "Every subcollection model.",
|
|
1311
|
-
"whenItDoesNotApply": "Root models.",
|
|
1312
|
-
"canonicalFix": "Declare `export type <PascalName>FirestoreCollectionGroup = FirestoreCollectionGroup<...>;`."
|
|
1313
|
-
},
|
|
1314
|
-
{
|
|
1315
|
-
"code": "SUB_MISSING_COLLECTION_REFERENCE_FACTORY",
|
|
1316
|
-
"source": "dbx_model_validate",
|
|
1317
|
-
"severity": "error",
|
|
1318
|
-
"title": "Subcollection model is missing its `<camelName>CollectionReferenceFactory` function",
|
|
1319
|
-
"whatItFlags": "Subcollection model is missing its `<camelName>CollectionReferenceFactory` function.",
|
|
1320
|
-
"whenItApplies": "Every subcollection model.",
|
|
1321
|
-
"whenItDoesNotApply": "Root models — they declare `<camelName>CollectionReference` instead.",
|
|
1322
|
-
"canonicalFix": "Declare `export function <camelName>CollectionReferenceFactory(...)`."
|
|
1323
|
-
},
|
|
1324
|
-
{
|
|
1325
|
-
"code": "CRUD_CLASS_MISSING_KEY",
|
|
1326
|
-
"source": "dbx_model_validate_api",
|
|
1327
|
-
"severity": "warning",
|
|
1328
|
-
"title": "A non-null CRUD key is missing the matching abstract member on `<Group>Functions`",
|
|
1329
|
-
"whatItFlags": "A non-null CRUD key is missing the matching abstract member on `<Group>Functions`.",
|
|
1330
|
-
"whenItApplies": "Every non-null key of `<Group>FunctionTypeCrudConfig` that doesn't appear as a member name on the abstract Functions class.",
|
|
1331
|
-
"whenItDoesNotApply": "Keys covered by an inherited member from a base class (rare — CRUD members are declared per file by convention).",
|
|
1332
|
-
"canonicalFix": "Add `abstract <key>: ModelFirebaseFunctionMapFunction<<Group>FunctionTypeMap, '<key>'>;` to the class."
|
|
1333
|
-
},
|
|
1334
|
-
{
|
|
1335
|
-
"code": "CRUD_CONFIG_CONST_WRONG_GENERIC",
|
|
1336
|
-
"source": "dbx_model_validate_api",
|
|
1337
|
-
"severity": "error",
|
|
1338
|
-
"title": "`<group>FunctionTypeCrudConfig` constant is annotated with the wrong generic argument",
|
|
1339
|
-
"whatItFlags": "`<group>FunctionTypeCrudConfig` constant is annotated with the wrong generic argument.",
|
|
1340
|
-
"whenItApplies": "When the type annotation on the const isn't the matching `<Group>FunctionTypeCrudConfig` type alias.",
|
|
1341
|
-
"whenItDoesNotApply": "No known false-positive cases — the generic must point at the local type alias.",
|
|
1342
|
-
"canonicalFix": "Set the annotation to `<Group>FunctionTypeCrudConfig` so the call map shape is inferred from the type map."
|
|
1343
|
-
},
|
|
1344
|
-
{
|
|
1345
|
-
"code": "CRUD_CONFIG_MISSING_RESULT_TUPLE",
|
|
1346
|
-
"source": "dbx_model_validate_api",
|
|
1347
|
-
"severity": "warning",
|
|
1348
|
-
"title": "A CRUD config leaf references the bare `*Params` interface without the `[Params, Result]` tuple form",
|
|
1349
|
-
"whatItFlags": "A CRUD config leaf references the bare `*Params` interface without the `[Params, Result]` tuple form.",
|
|
1350
|
-
"whenItApplies": "Every CRUD leaf that uses `<key>: <Foo>ParamsType` instead of `<key>: [<Foo>ParamsType, <Foo>Result]`.",
|
|
1351
|
-
"whenItDoesNotApply": "CRUD entries whose result type is intentionally `void` (rare — convention is to declare `*Result` and use the tuple form).",
|
|
1352
|
-
"canonicalFix": "Convert the leaf to the tuple form `[<Foo>ParamsType, <Foo>Result]` so the function signature carries the result type."
|
|
1353
|
-
},
|
|
1354
|
-
{
|
|
1355
|
-
"code": "CRUD_CONST_MISSING_KEY",
|
|
1356
|
-
"source": "dbx_model_validate_api",
|
|
1357
|
-
"severity": "warning",
|
|
1358
|
-
"title": "A non-null CRUD key is missing from the runtime `<group>FunctionTypeCrudConfig` const",
|
|
1359
|
-
"whatItFlags": "A non-null CRUD key is missing from the runtime `<group>FunctionTypeCrudConfig` const.",
|
|
1360
|
-
"whenItApplies": "Every non-null key declared on the `<Group>FunctionTypeCrudConfig` type that doesn't appear as a runtime key on the const.",
|
|
1361
|
-
"whenItDoesNotApply": "Keys whose runtime entry is contributed by another file (rare — convention is to keep type + const in lockstep).",
|
|
1362
|
-
"canonicalFix": "Add `<key>: [<Foo>ParamsType, <Foo>Result]` (or the bare `*Params` form) to the const."
|
|
1363
|
-
},
|
|
1364
|
-
{
|
|
1365
|
-
"code": "DECL_AFTER_FUNCTIONS_BLOCK",
|
|
1366
|
-
"source": "dbx_model_validate_api",
|
|
1367
|
-
"severity": "warning",
|
|
1368
|
-
"title": "A `*Params` / `*Result` declaration appears below the Functions block",
|
|
1369
|
-
"whatItFlags": "A `*Params` / `*Result` declaration appears below the Functions block.",
|
|
1370
|
-
"whenItApplies": "When a params or result declaration's line number falls after the first Functions-block declaration.",
|
|
1371
|
-
"whenItDoesNotApply": "Files where the declaration order is intentionally inverted for project-specific reasons.",
|
|
1372
|
-
"canonicalFix": "Move the params/result declaration above the Functions block so the file reads top-down: types → validators → Functions."
|
|
1373
|
-
},
|
|
1374
|
-
{
|
|
1375
|
-
"code": "FILE_GROUP_NAME_INCONSISTENT",
|
|
1376
|
-
"source": "dbx_model_validate_api",
|
|
1377
|
-
"severity": "error",
|
|
1378
|
-
"title": "The Functions block declarations don't all share the same `<group>` prefix",
|
|
1379
|
-
"whatItFlags": "The Functions block declarations don't all share the same `<group>` prefix.",
|
|
1380
|
-
"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.",
|
|
1381
|
-
"whenItDoesNotApply": "Files where the prefix mismatch is intentional (rare — convention requires consistent naming).",
|
|
1382
|
-
"canonicalFix": "Rename the divergent declaration so every Functions-block export shares the same `<group>` prefix."
|
|
1383
|
-
},
|
|
1384
|
-
{
|
|
1385
|
-
"code": "FILE_MISSING_CRUD_CONFIG_CONST",
|
|
1386
|
-
"source": "dbx_model_validate_api",
|
|
1387
|
-
"severity": "error",
|
|
1388
|
-
"title": "`<group>FunctionTypeCrudConfig` constant is missing from the file",
|
|
1389
|
-
"whatItFlags": "`<group>FunctionTypeCrudConfig` constant is missing from the file.",
|
|
1390
|
-
"whenItApplies": "Every `<model>.api.ts` file with a Functions block.",
|
|
1391
|
-
"whenItDoesNotApply": "Non-CRUD api filenames listed in `NON_CRUD_API_BASENAMES`.",
|
|
1392
|
-
"canonicalFix": "Add `export const <group>FunctionTypeCrudConfig: <Group>FunctionTypeCrudConfig = { ... };` mapping each CRUD key to its `[Params, Result]` tuple or `null`."
|
|
1393
|
-
},
|
|
1394
|
-
{
|
|
1395
|
-
"code": "FILE_MISSING_CRUD_CONFIG_TYPE",
|
|
1396
|
-
"source": "dbx_model_validate_api",
|
|
1397
|
-
"severity": "error",
|
|
1398
|
-
"title": "`<Group>FunctionTypeCrudConfig` type alias is missing from the file",
|
|
1399
|
-
"whatItFlags": "`<Group>FunctionTypeCrudConfig` type alias is missing from the file.",
|
|
1400
|
-
"whenItApplies": "Every `<model>.api.ts` file with a Functions block.",
|
|
1401
|
-
"whenItDoesNotApply": "Non-CRUD api filenames listed in `NON_CRUD_API_BASENAMES`.",
|
|
1402
|
-
"canonicalFix": "Add `export type <Group>FunctionTypeCrudConfig = ModelFirebaseCrudFunctionConfigMap<<Group>FunctionTypeMap>;` to bind the CRUD shape to the type map."
|
|
1403
|
-
},
|
|
1404
|
-
{
|
|
1405
|
-
"code": "FILE_MISSING_FUNCTION_MAP",
|
|
1406
|
-
"source": "dbx_model_validate_api",
|
|
1407
|
-
"severity": "error",
|
|
1408
|
-
"title": "`<group>FunctionMap` constant is missing from the file",
|
|
1409
|
-
"whatItFlags": "`<group>FunctionMap` constant is missing from the file.",
|
|
1410
|
-
"whenItApplies": "Every `<model>.api.ts` file with a Functions block.",
|
|
1411
|
-
"whenItDoesNotApply": "Non-CRUD api filenames listed in `NON_CRUD_API_BASENAMES`.",
|
|
1412
|
-
"canonicalFix": "Add `export const <group>FunctionMap = callModelFirebaseFunctionMapFactory(<group>FunctionTypeConfigMap, <group>FunctionTypeCrudConfig);` to wire the runtime call map."
|
|
1413
|
-
},
|
|
1414
|
-
{
|
|
1415
|
-
"code": "FILE_MISSING_FUNCTION_TYPE_CONFIG_MAP",
|
|
1416
|
-
"source": "dbx_model_validate_api",
|
|
1417
|
-
"severity": "error",
|
|
1418
|
-
"title": "`<group>FunctionTypeConfigMap` constant is missing from the file",
|
|
1419
|
-
"whatItFlags": "`<group>FunctionTypeConfigMap` constant is missing from the file.",
|
|
1420
|
-
"whenItApplies": "Every `<model>.api.ts` file with a Functions block.",
|
|
1421
|
-
"whenItDoesNotApply": "Non-CRUD api filenames listed in `NON_CRUD_API_BASENAMES`.",
|
|
1422
|
-
"canonicalFix": "Add `export const <group>FunctionTypeConfigMap: ModelFirebaseFunctionMapTypeConfigMap<<Group>FunctionTypeMap> = { ... };` aligned with the type-map keys.",
|
|
1423
|
-
"seeAlso": [
|
|
1424
|
-
{
|
|
1425
|
-
"kind": "doc",
|
|
1426
|
-
"target": "dbx__guide__call-model-api"
|
|
1427
|
-
}
|
|
1428
|
-
]
|
|
1429
|
-
},
|
|
1430
|
-
{
|
|
1431
|
-
"code": "FILE_MISSING_FUNCTION_TYPE_MAP",
|
|
1432
|
-
"source": "dbx_model_validate_api",
|
|
1433
|
-
"severity": "error",
|
|
1434
|
-
"title": "`<group>FunctionTypeMap` type alias is missing from the file",
|
|
1435
|
-
"whatItFlags": "`<group>FunctionTypeMap` type alias is missing from the file.",
|
|
1436
|
-
"whenItApplies": "Every `<model>.api.ts` file (other than the non-CRUD basenames listed in `NON_CRUD_API_BASENAMES`).",
|
|
1437
|
-
"whenItDoesNotApply": "Files matching a `NON_CRUD_API_BASENAMES` entry (e.g. `development.api.ts`) — those short-circuit structural checks.",
|
|
1438
|
-
"canonicalFix": "Add `export type <Group>FunctionTypeMap = { /* keys *\\/ };` at the top of the Functions block.",
|
|
1439
|
-
"seeAlso": [
|
|
1440
|
-
{
|
|
1441
|
-
"kind": "doc",
|
|
1442
|
-
"target": "dbx__guide__call-model-api"
|
|
1443
|
-
}
|
|
1444
|
-
]
|
|
1445
|
-
},
|
|
1446
|
-
{
|
|
1447
|
-
"code": "FILE_MISSING_FUNCTIONS_CLASS",
|
|
1448
|
-
"source": "dbx_model_validate_api",
|
|
1449
|
-
"severity": "error",
|
|
1450
|
-
"title": "`<Group>Functions` abstract class is missing from the file",
|
|
1451
|
-
"whatItFlags": "`<Group>Functions` abstract class is missing from the file.",
|
|
1452
|
-
"whenItApplies": "Every `<model>.api.ts` file with a Functions block.",
|
|
1453
|
-
"whenItDoesNotApply": "Non-CRUD api filenames listed in `NON_CRUD_API_BASENAMES`.",
|
|
1454
|
-
"canonicalFix": "Add `export abstract class <Group>Functions implements ModelFirebaseFunctionsConfigMap<<Group>FunctionTypeMap, <Group>FunctionTypeCrudConfig> { ... }` with one abstract member per non-null CRUD key."
|
|
1455
|
-
},
|
|
1456
|
-
{
|
|
1457
|
-
"code": "FILE_MISSING_MARK_CONSTANTS",
|
|
1458
|
-
"source": "dbx_model_validate_api",
|
|
1459
|
-
"severity": "warning",
|
|
1460
|
-
"title": "The file is missing the `// MARK: Constants` (or equivalent) section comment",
|
|
1461
|
-
"whatItFlags": "The file is missing the `// MARK: Constants` (or equivalent) section comment.",
|
|
1462
|
-
"whenItApplies": "Every CRUD api file expected to declare top-level constants alongside the params/results.",
|
|
1463
|
-
"whenItDoesNotApply": "Files with no top-level constants — the marker is purely organizational.",
|
|
1464
|
-
"canonicalFix": "Add a `// MARK: Constants` comment above the constants region so navigation and folding work consistently."
|
|
1465
|
-
},
|
|
1466
|
-
{
|
|
1467
|
-
"code": "FILE_MISSING_MARK_FUNCTIONS",
|
|
1468
|
-
"source": "dbx_model_validate_api",
|
|
1469
|
-
"severity": "warning",
|
|
1470
|
-
"title": "The file is missing the `// MARK: Functions` section comment above the Functions block",
|
|
1471
|
-
"whatItFlags": "The file is missing the `// MARK: Functions` section comment above the Functions block.",
|
|
1472
|
-
"whenItApplies": "Every CRUD api file with a Functions block.",
|
|
1473
|
-
"whenItDoesNotApply": "Files matching `NON_CRUD_API_BASENAMES` (no Functions block expected).",
|
|
1474
|
-
"canonicalFix": "Add a `// MARK: Functions` comment immediately above the Functions block so the file's top-down structure stays scannable."
|
|
1475
|
-
},
|
|
1476
|
-
{
|
|
1477
|
-
"code": "FILE_MISSING_MARK_KEYS",
|
|
1478
|
-
"source": "dbx_model_validate_api",
|
|
1479
|
-
"severity": "warning",
|
|
1480
|
-
"title": "The file is missing the `// MARK: Keys` section comment",
|
|
1481
|
-
"whatItFlags": "The file is missing the `// MARK: Keys` section comment.",
|
|
1482
|
-
"whenItApplies": "Every CRUD api file expected to declare key types alongside the params/results.",
|
|
1483
|
-
"whenItDoesNotApply": "Files with no key declarations — the marker is purely organizational.",
|
|
1484
|
-
"canonicalFix": "Add a `// MARK: Keys` comment above the keys region so navigation and folding work consistently."
|
|
1485
|
-
},
|
|
1486
|
-
{
|
|
1487
|
-
"code": "FILE_NOT_EXPORTED",
|
|
1488
|
-
"source": "dbx_model_validate_api",
|
|
1489
|
-
"severity": "error",
|
|
1490
|
-
"title": "A required Functions-block declaration exists but isn't `export`ed",
|
|
1491
|
-
"whatItFlags": "A required Functions-block declaration exists but isn't `export`ed.",
|
|
1492
|
-
"whenItApplies": "Any of the six Functions-block exports declared without the `export` keyword.",
|
|
1493
|
-
"whenItDoesNotApply": "No known false-positive cases — the call map / class are consumed across packages and must be exported.",
|
|
1494
|
-
"canonicalFix": "Add the `export` keyword to the declaration."
|
|
1495
|
-
},
|
|
1496
|
-
{
|
|
1497
|
-
"code": "FUNCTION_MAP_BAD_FACTORY_ARGS",
|
|
1498
|
-
"source": "dbx_model_validate_api",
|
|
1499
|
-
"severity": "error",
|
|
1500
|
-
"title": "`<group>FunctionMap = callModelFirebaseFunctionMapFactory(...)` was called with the wrong argument identifiers",
|
|
1501
|
-
"whatItFlags": "`<group>FunctionMap = callModelFirebaseFunctionMapFactory(...)` was called with the wrong argument identifiers.",
|
|
1502
|
-
"whenItApplies": "When the factory call's two argument identifiers don't match `<group>FunctionTypeConfigMap` and `<group>FunctionTypeCrudConfig` (in that order).",
|
|
1503
|
-
"whenItDoesNotApply": "No known false-positive cases — the factory must be passed the file's own config + crud-config consts.",
|
|
1504
|
-
"canonicalFix": "Pass `<group>FunctionTypeConfigMap` first and `<group>FunctionTypeCrudConfig` second, matching the local declarations."
|
|
1505
|
-
},
|
|
1506
|
-
{
|
|
1507
|
-
"code": "FUNCTIONS_BLOCK_OUT_OF_ORDER",
|
|
1508
|
-
"source": "dbx_model_validate_api",
|
|
1509
|
-
"severity": "warning",
|
|
1510
|
-
"title": "The Functions-block declarations aren't in canonical order",
|
|
1511
|
-
"whatItFlags": "The Functions-block declarations aren't in canonical order.",
|
|
1512
|
-
"whenItApplies": "When the actual on-disk order of `functionTypeMap` / `functionTypeConfigMap` / `crudConfigType` / `crudConfigConst` / `functionMap` / `functionsClass` doesn't match the canonical order in `FUNCTIONS_BLOCK_ORDER`.",
|
|
1513
|
-
"whenItDoesNotApply": "Files where the order is intentionally different for project-specific reasons.",
|
|
1514
|
-
"canonicalFix": "Reorder the Functions-block declarations to match `FUNCTIONS_BLOCK_ORDER`."
|
|
1515
|
-
},
|
|
1516
|
-
{
|
|
1517
|
-
"code": "FUNCTIONS_CLASS_BAD_IMPLEMENTS",
|
|
1518
|
-
"source": "dbx_model_validate_api",
|
|
1519
|
-
"severity": "error",
|
|
1520
|
-
"title": "`<Group>Functions` declares the wrong `implements` clause",
|
|
1521
|
-
"whatItFlags": "`<Group>Functions` declares the wrong `implements` clause.",
|
|
1522
|
-
"whenItApplies": "When the first `implements` clause text isn't `ModelFirebaseFunctionsConfigMap<<Group>FunctionTypeMap, <Group>FunctionTypeCrudConfig>` (with the local type/const names).",
|
|
1523
|
-
"whenItDoesNotApply": "No known false-positive cases — the implements clause keeps the abstract members in sync with the CRUD config.",
|
|
1524
|
-
"canonicalFix": "Replace the implements clause with `ModelFirebaseFunctionsConfigMap<<Group>FunctionTypeMap, <Group>FunctionTypeCrudConfig>`."
|
|
1525
|
-
},
|
|
1526
|
-
{
|
|
1527
|
-
"code": "FUNCTIONS_CLASS_NOT_ABSTRACT",
|
|
1528
|
-
"source": "dbx_model_validate_api",
|
|
1529
|
-
"severity": "error",
|
|
1530
|
-
"title": "`<Group>Functions` is declared as `class` rather than `abstract class`",
|
|
1531
|
-
"whatItFlags": "`<Group>Functions` is declared as `class` rather than `abstract class`.",
|
|
1532
|
-
"whenItApplies": "When the class declaration is missing the `abstract` modifier.",
|
|
1533
|
-
"whenItDoesNotApply": "No known false-positive cases — the Functions class is implemented downstream by the API app.",
|
|
1534
|
-
"canonicalFix": "Add the `abstract` modifier so concrete CRUD members are bound by the consuming `*ServerActions` class."
|
|
1535
|
-
},
|
|
1536
|
-
{
|
|
1537
|
-
"code": "NON_CRUD_API_FILENAME",
|
|
1538
|
-
"source": "dbx_model_validate_api",
|
|
1539
|
-
"severity": "warning",
|
|
1540
|
-
"title": "A `.api.ts` file follows the naming convention but is not a CRUD model api",
|
|
1541
|
-
"whatItFlags": "A `.api.ts` file follows the naming convention but is not a CRUD model api.",
|
|
1542
|
-
"whenItApplies": "Files whose basename appears in `NON_CRUD_API_BASENAMES` (e.g. `development.api.ts`).",
|
|
1543
|
-
"whenItDoesNotApply": "CRUD-style api files — those run the full structural pass.",
|
|
1544
|
-
"canonicalFix": "Either rename the file (drop `.api.ts`) or accept the warning — structural checks are intentionally short-circuited."
|
|
1545
|
-
},
|
|
1546
|
-
{
|
|
1547
|
-
"code": "PARAMS_FIELD_NOT_READONLY",
|
|
1548
|
-
"source": "dbx_model_validate_api",
|
|
1549
|
-
"severity": "warning",
|
|
1550
|
-
"title": "A field on a `*Params` interface is missing the `readonly` modifier",
|
|
1551
|
-
"whatItFlags": "A field on a `*Params` interface is missing the `readonly` modifier.",
|
|
1552
|
-
"whenItApplies": "Every property on a `*Params` interface (type aliases are skipped).",
|
|
1553
|
-
"whenItDoesNotApply": "Fields whose type system needs mutability (rare — params are immutable by convention).",
|
|
1554
|
-
"canonicalFix": "Add `readonly` to the property so the params shape stays immutable.",
|
|
1555
|
-
"seeAlso": [
|
|
1556
|
-
{
|
|
1557
|
-
"kind": "doc",
|
|
1558
|
-
"target": "dbx__note__typescript-programming"
|
|
1559
|
-
}
|
|
1560
|
-
]
|
|
1561
|
-
},
|
|
1562
|
-
{
|
|
1563
|
-
"code": "PARAMS_MAYBE_WITHOUT_CLEARABLE",
|
|
1564
|
-
"source": "dbx_model_validate_api",
|
|
1565
|
-
"severity": "warning",
|
|
1566
|
-
"title": "A `*ParamsType` validator declares a `Maybe<...>` field without `clearable(...)`",
|
|
1567
|
-
"whatItFlags": "A `*ParamsType` validator declares a `Maybe<...>` field without `clearable(...)`.",
|
|
1568
|
-
"whenItApplies": "When the params interface field is wrapped in `Maybe<T>` but the validator's matching property doesn't call `clearable(...)`.",
|
|
1569
|
-
"whenItDoesNotApply": "Fields that intentionally accept `null` / `undefined` without the clearable wrapper (rare — convention is to use `clearable`).",
|
|
1570
|
-
"canonicalFix": "Wrap the validator property's value with `clearable(...)` so optional / clearable fields decode correctly at runtime."
|
|
1571
|
-
},
|
|
1572
|
-
{
|
|
1573
|
-
"code": "PARAMS_MISSING_VALIDATOR",
|
|
1574
|
-
"source": "dbx_model_validate_api",
|
|
1575
|
-
"severity": "error",
|
|
1576
|
-
"title": "A `*Params` interface has no matching `*ParamsType` Arktype validator",
|
|
1577
|
-
"whatItFlags": "A `*Params` interface has no matching `*ParamsType` Arktype validator.",
|
|
1578
|
-
"whenItApplies": "Every `*Params` declaration referenced by the CRUD config.",
|
|
1579
|
-
"whenItDoesNotApply": "Params that are intentionally unvalidated (rare — every public CRUD entry needs a runtime validator).",
|
|
1580
|
-
"canonicalFix": "Add `export const <foo>ParamsType = type({ ... }) as unknown as RuntimeTypeValidator<<Foo>Params>;` adjacent to the interface.",
|
|
1581
|
-
"seeAlso": [
|
|
1582
|
-
{
|
|
1583
|
-
"kind": "doc",
|
|
1584
|
-
"target": "dbx__guide__call-model-api"
|
|
1585
|
-
}
|
|
1586
|
-
]
|
|
1587
|
-
},
|
|
1588
|
-
{
|
|
1589
|
-
"code": "PARAMS_NOT_EXPORTED",
|
|
1590
|
-
"source": "dbx_model_validate_api",
|
|
1591
|
-
"severity": "error",
|
|
1592
|
-
"title": "A `*Params` declaration exists but isn't `export`ed",
|
|
1593
|
-
"whatItFlags": "A `*Params` declaration exists but isn't `export`ed.",
|
|
1594
|
-
"whenItApplies": "Any `*Params` interface or type alias declared without the `export` keyword.",
|
|
1595
|
-
"whenItDoesNotApply": "Internal helper params that aren't part of the CRUD config (rare — most params are referenced by the call map).",
|
|
1596
|
-
"canonicalFix": "Add the `export` keyword so the params can be referenced by downstream packages and the validator's cast."
|
|
1597
|
-
},
|
|
1598
|
-
{
|
|
1599
|
-
"code": "PARAMS_VALIDATOR_NOT_ADJACENT",
|
|
1600
|
-
"source": "dbx_model_validate_api",
|
|
1601
|
-
"severity": "warning",
|
|
1602
|
-
"title": "A `*ParamsType` validator isn't declared adjacent to its `*Params` interface",
|
|
1603
|
-
"whatItFlags": "A `*ParamsType` validator isn't declared adjacent to its `*Params` interface.",
|
|
1604
|
-
"whenItApplies": "When the validator and its params interface are separated by another top-level declaration.",
|
|
1605
|
-
"whenItDoesNotApply": "Files where the validator must live in a different region for project-specific reasons.",
|
|
1606
|
-
"canonicalFix": "Move the validator immediately after its params interface so the pair stays grouped."
|
|
1607
|
-
},
|
|
1608
|
-
{
|
|
1609
|
-
"code": "PARAMS_VALIDATOR_NOT_EXPORTED",
|
|
1610
|
-
"source": "dbx_model_validate_api",
|
|
1611
|
-
"severity": "error",
|
|
1612
|
-
"title": "A `*ParamsType` validator declaration exists but isn't `export`ed",
|
|
1613
|
-
"whatItFlags": "A `*ParamsType` validator declaration exists but isn't `export`ed.",
|
|
1614
|
-
"whenItApplies": "Any `*ParamsType` constant declared without the `export` keyword.",
|
|
1615
|
-
"whenItDoesNotApply": "No known false-positive cases — validators are consumed by the runtime CRUD wiring.",
|
|
1616
|
-
"canonicalFix": "Add the `export` keyword so the validator can be referenced by the runtime wiring."
|
|
1617
|
-
},
|
|
1618
|
-
{
|
|
1619
|
-
"code": "PARAMS_VALIDATOR_WRONG_CAST",
|
|
1620
|
-
"source": "dbx_model_validate_api",
|
|
1621
|
-
"severity": "error",
|
|
1622
|
-
"title": "A `*ParamsType` validator is cast to the wrong target type",
|
|
1623
|
-
"whatItFlags": "A `*ParamsType` validator is cast to the wrong target type.",
|
|
1624
|
-
"whenItApplies": "When the validator's `as ... <Type>` cast doesn't reference the matching `*Params` interface.",
|
|
1625
|
-
"whenItDoesNotApply": "No known false-positive cases — the cast is what links the validator to the params interface at the type level.",
|
|
1626
|
-
"canonicalFix": "Cast the validator to `RuntimeTypeValidator<<Foo>Params>` (or `as unknown as RuntimeTypeValidator<<Foo>Params>`) so the CRUD config infers the right shape."
|
|
1627
|
-
},
|
|
1628
|
-
{
|
|
1629
|
-
"code": "RESULT_FIELD_NOT_READONLY",
|
|
1630
|
-
"source": "dbx_model_validate_api",
|
|
1631
|
-
"severity": "warning",
|
|
1632
|
-
"title": "A field on a `*Result` interface is missing the `readonly` modifier",
|
|
1633
|
-
"whatItFlags": "A field on a `*Result` interface is missing the `readonly` modifier.",
|
|
1634
|
-
"whenItApplies": "Every property on a `*Result` interface (type aliases are skipped).",
|
|
1635
|
-
"whenItDoesNotApply": "Fields whose type system needs mutability (rare — results are immutable by convention).",
|
|
1636
|
-
"canonicalFix": "Add `readonly` to the property so the result shape stays immutable.",
|
|
1637
|
-
"seeAlso": [
|
|
1638
|
-
{
|
|
1639
|
-
"kind": "doc",
|
|
1640
|
-
"target": "dbx__note__typescript-programming"
|
|
1641
|
-
}
|
|
1642
|
-
]
|
|
1643
|
-
},
|
|
1644
|
-
{
|
|
1645
|
-
"code": "TYPE_CONFIG_MAP_WRONG_GENERIC",
|
|
1646
|
-
"source": "dbx_model_validate_api",
|
|
1647
|
-
"severity": "error",
|
|
1648
|
-
"title": "`<group>FunctionTypeConfigMap` is annotated with the wrong generic argument",
|
|
1649
|
-
"whatItFlags": "`<group>FunctionTypeConfigMap` is annotated with the wrong generic argument.",
|
|
1650
|
-
"whenItApplies": "When the type annotation isn't `ModelFirebaseFunctionMapTypeConfigMap<<Group>FunctionTypeMap>`.",
|
|
1651
|
-
"whenItDoesNotApply": "No known false-positive cases — the generic ties the config map to the type map by design.",
|
|
1652
|
-
"canonicalFix": "Set the annotation to `ModelFirebaseFunctionMapTypeConfigMap<<Group>FunctionTypeMap>` matching the file's type-map name."
|
|
1653
|
-
},
|
|
1654
|
-
{
|
|
1655
|
-
"code": "FOLDER_MISSING_ACTION",
|
|
1656
|
-
"source": "dbx_model_validate_folder",
|
|
1657
|
-
"severity": "error",
|
|
1658
|
-
"title": "Required `<name>.action.ts` server-actions module is missing",
|
|
1659
|
-
"whatItFlags": "Required `<name>.action.ts` server-actions module is missing.",
|
|
1660
|
-
"whenItApplies": "Every canonical model folder.",
|
|
1661
|
-
"whenItDoesNotApply": "Reserved folders that don't follow the 5-file convention.",
|
|
1662
|
-
"canonicalFix": "Add `<name>.action.ts` declaring the abstract `<Model>ServerActions` class plus the action-context interface.",
|
|
1663
|
-
"seeAlso": [
|
|
1664
|
-
{
|
|
1665
|
-
"kind": "artifact",
|
|
1666
|
-
"target": "firestore-model"
|
|
1667
|
-
}
|
|
1668
|
-
]
|
|
1669
|
-
},
|
|
1670
|
-
{
|
|
1671
|
-
"code": "FOLDER_MISSING_API",
|
|
1672
|
-
"source": "dbx_model_validate_folder",
|
|
1673
|
-
"severity": "error",
|
|
1674
|
-
"title": "Required `<name>.api.ts` CRUD api module is missing",
|
|
1675
|
-
"whatItFlags": "Required `<name>.api.ts` CRUD api module is missing.",
|
|
1676
|
-
"whenItApplies": "Every canonical model folder.",
|
|
1677
|
-
"whenItDoesNotApply": "Reserved folders that don't follow the 5-file convention.",
|
|
1678
|
-
"canonicalFix": "Add `<name>.api.ts` declaring the params/result interfaces, validators, and Functions block.",
|
|
1679
|
-
"seeAlso": [
|
|
1680
|
-
{
|
|
1681
|
-
"kind": "tool",
|
|
1682
|
-
"target": "dbx_model_validate_api"
|
|
1683
|
-
}
|
|
1684
|
-
]
|
|
1685
|
-
},
|
|
1686
|
-
{
|
|
1687
|
-
"code": "FOLDER_MISSING_ID",
|
|
1688
|
-
"source": "dbx_model_validate_folder",
|
|
1689
|
-
"severity": "error",
|
|
1690
|
-
"title": "Required `<name>.id.ts` id-types module is missing",
|
|
1691
|
-
"whatItFlags": "Required `<name>.id.ts` id-types module is missing.",
|
|
1692
|
-
"whenItApplies": "Every canonical model folder.",
|
|
1693
|
-
"whenItDoesNotApply": "Reserved folders that don't follow the 5-file convention.",
|
|
1694
|
-
"canonicalFix": "Add `<name>.id.ts` exporting the model's id alias types and any composite-key helpers.",
|
|
1695
|
-
"seeAlso": [
|
|
1696
|
-
{
|
|
1697
|
-
"kind": "artifact",
|
|
1698
|
-
"target": "firestore-model"
|
|
1699
|
-
}
|
|
1700
|
-
]
|
|
1701
|
-
},
|
|
1702
|
-
{
|
|
1703
|
-
"code": "FOLDER_MISSING_INDEX",
|
|
1704
|
-
"source": "dbx_model_validate_folder",
|
|
1705
|
-
"severity": "error",
|
|
1706
|
-
"title": "Required `index.ts` barrel is missing",
|
|
1707
|
-
"whatItFlags": "Required `index.ts` barrel is missing.",
|
|
1708
|
-
"whenItApplies": "Every canonical model folder.",
|
|
1709
|
-
"whenItDoesNotApply": "Reserved folders that don't follow the 5-file convention.",
|
|
1710
|
-
"canonicalFix": "Add `index.ts` re-exporting every sibling `<name>.*.ts` module so the folder is consumed through one barrel."
|
|
1711
|
-
},
|
|
1712
|
-
{
|
|
1713
|
-
"code": "FOLDER_MISSING_MAIN",
|
|
1714
|
-
"source": "dbx_model_validate_folder",
|
|
1715
|
-
"severity": "error",
|
|
1716
|
-
"title": "Required `<name>.ts` main module is missing from the model folder",
|
|
1717
|
-
"whatItFlags": "Required `<name>.ts` main module is missing from the model folder.",
|
|
1718
|
-
"whenItApplies": "Every canonical model folder anchored on its folder basename.",
|
|
1719
|
-
"whenItDoesNotApply": "Reserved folders (`system`, `notification`, `storagefile`) — they have a different layout and surface a separate `RESERVED_MODEL_FOLDER` warning instead.",
|
|
1720
|
-
"canonicalFix": "Add `<name>.ts` containing the model's `firestoreModelIdentity`, interface, document class, converter, and collection wiring.",
|
|
1721
|
-
"seeAlso": [
|
|
1722
|
-
{
|
|
1723
|
-
"kind": "artifact",
|
|
1724
|
-
"target": "firestore-model"
|
|
1725
|
-
}
|
|
1726
|
-
]
|
|
1727
|
-
},
|
|
1728
|
-
{
|
|
1729
|
-
"code": "FOLDER_MISSING_QUERY",
|
|
1730
|
-
"source": "dbx_model_validate_folder",
|
|
1731
|
-
"severity": "error",
|
|
1732
|
-
"title": "Required `<name>.query.ts` query-helpers module is missing",
|
|
1733
|
-
"whatItFlags": "Required `<name>.query.ts` query-helpers module is missing.",
|
|
1734
|
-
"whenItApplies": "Every canonical model folder.",
|
|
1735
|
-
"whenItDoesNotApply": "Reserved folders that don't follow the 5-file convention.",
|
|
1736
|
-
"canonicalFix": "Add `<name>.query.ts` with the model's query-builder helpers.",
|
|
1737
|
-
"seeAlso": [
|
|
1738
|
-
{
|
|
1739
|
-
"kind": "artifact",
|
|
1740
|
-
"target": "firestore-model"
|
|
1741
|
-
}
|
|
1742
|
-
]
|
|
1743
|
-
},
|
|
1744
|
-
{
|
|
1745
|
-
"code": "FOLDER_NOT_DIRECTORY",
|
|
1746
|
-
"source": "dbx_model_validate_folder",
|
|
1747
|
-
"severity": "error",
|
|
1748
|
-
"title": "The path resolves to a file or other non-directory entry",
|
|
1749
|
-
"whatItFlags": "The path resolves to a file or other non-directory entry.",
|
|
1750
|
-
"whenItApplies": "Validating a path that exists but is not a directory.",
|
|
1751
|
-
"whenItDoesNotApply": "File-level model validation — use `dbx_model_validate` for `.ts` source files.",
|
|
1752
|
-
"canonicalFix": "Pass the model folder (e.g. `apps/.../src/lib/model/profile/`), not the `<name>.ts` file inside it."
|
|
1753
|
-
},
|
|
1754
|
-
{
|
|
1755
|
-
"code": "FOLDER_NOT_FOUND",
|
|
1756
|
-
"source": "dbx_model_validate_folder",
|
|
1757
|
-
"severity": "error",
|
|
1758
|
-
"title": "Folder does not exist on disk",
|
|
1759
|
-
"whatItFlags": "Folder does not exist on disk.",
|
|
1760
|
-
"whenItApplies": "Validating a folder path that doesn't resolve to a directory entry.",
|
|
1761
|
-
"whenItDoesNotApply": "Glob patterns that intentionally match zero folders — pass at least one valid path.",
|
|
1762
|
-
"canonicalFix": "Verify the path argument is a real folder under the workspace.",
|
|
1763
|
-
"seeAlso": [
|
|
1764
|
-
{
|
|
1765
|
-
"kind": "tool",
|
|
1766
|
-
"target": "dbx_model_validate_folder"
|
|
1767
|
-
}
|
|
1768
|
-
]
|
|
1769
|
-
},
|
|
1770
|
-
{
|
|
1771
|
-
"code": "FOLDER_STRAY_FILE",
|
|
1772
|
-
"source": "dbx_model_validate_folder",
|
|
1773
|
-
"severity": "warning",
|
|
1774
|
-
"title": "A `.ts` file in the folder doesn't start with the folder's `<name>.` prefix",
|
|
1775
|
-
"whatItFlags": "A `.ts` file in the folder doesn't start with the folder's `<name>.` prefix.",
|
|
1776
|
-
"whenItApplies": "Any `.ts` file that is not `index.ts` and is not prefixed with `<folder-name>.`.",
|
|
1777
|
-
"whenItDoesNotApply": "Files outside the canonical layout that the project intentionally hosts here (rare — prefer moving them out).",
|
|
1778
|
-
"canonicalFix": "Rename the file to `<folder-name>.<sub>.ts` so it stays grouped, or move it out of the model folder."
|
|
1779
|
-
},
|
|
1780
|
-
{
|
|
1781
|
-
"code": "RESERVED_MODEL_FOLDER",
|
|
1782
|
-
"source": "dbx_model_validate_folder",
|
|
1783
|
-
"severity": "warning",
|
|
1784
|
-
"title": "The folder name matches a reserved group (system / notification / storagefile)",
|
|
1785
|
-
"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.",
|
|
1786
|
-
"whenItApplies": "Folders named `system`, `notification`, or `storagefile`.",
|
|
1787
|
-
"whenItDoesNotApply": "Custom downstream folders that happen to share a substring — match is exact.",
|
|
1788
|
-
"canonicalFix": "Re-run validation with the recommended tool from the violation's message (e.g. `dbx_system_m_validate_folder`).",
|
|
1789
|
-
"seeAlso": [
|
|
1790
|
-
{
|
|
1791
|
-
"kind": "tool",
|
|
1792
|
-
"target": "dbx_system_m_validate_folder"
|
|
1793
|
-
},
|
|
1794
|
-
{
|
|
1795
|
-
"kind": "tool",
|
|
1796
|
-
"target": "dbx_notification_m_validate_folder"
|
|
1797
|
-
},
|
|
1798
|
-
{
|
|
1799
|
-
"kind": "tool",
|
|
1800
|
-
"target": "dbx_storagefile_m_validate_folder"
|
|
1801
|
-
}
|
|
1802
|
-
]
|
|
1803
|
-
},
|
|
1804
|
-
{
|
|
1805
|
-
"code": "NOTIF_API_DIR_NOT_FOUND",
|
|
1806
|
-
"source": "dbx_notification_m_validate_app",
|
|
1807
|
-
"severity": "error",
|
|
1808
|
-
"title": "The API app directory does not exist on disk",
|
|
1809
|
-
"whatItFlags": "The API app directory does not exist on disk.",
|
|
1810
|
-
"whenItApplies": "When the supplied `apiDir` does not resolve to a directory entry.",
|
|
1811
|
-
"whenItDoesNotApply": "API apps intentionally not validated — pass `--skip notification_m` instead.",
|
|
1812
|
-
"canonicalFix": "Verify the path argument resolves to an existing API app root.",
|
|
1813
|
-
"seeAlso": [
|
|
1814
|
-
{
|
|
1815
|
-
"kind": "tool",
|
|
1816
|
-
"target": "dbx_notification_m_validate_folder"
|
|
1817
|
-
}
|
|
1818
|
-
]
|
|
1819
|
-
},
|
|
1820
|
-
{
|
|
1821
|
-
"code": "NOTIF_API_NOTIFICATION_FOLDER_MISSING",
|
|
1822
|
-
"source": "dbx_notification_m_validate_app",
|
|
1823
|
-
"severity": "error",
|
|
1824
|
-
"title": "The API root exists but `src/app/common/model/notification/` is missing",
|
|
1825
|
-
"whatItFlags": "The API root exists but `src/app/common/model/notification/` is missing.",
|
|
1826
|
-
"whenItApplies": "API apps expected to wire the notification module but with no notification folder.",
|
|
1827
|
-
"whenItDoesNotApply": "API apps that intentionally don't wire notifications — pass `--skip notification_m`.",
|
|
1828
|
-
"canonicalFix": "Add `src/app/common/model/notification/` with `notification.module.ts`, `notification.task.service.ts`, and `notification.send.service.ts`.",
|
|
1829
|
-
"seeAlso": [
|
|
1830
|
-
{
|
|
1831
|
-
"kind": "artifact",
|
|
1832
|
-
"target": "notification-template"
|
|
1833
|
-
}
|
|
1834
|
-
]
|
|
1835
|
-
},
|
|
1836
|
-
{
|
|
1837
|
-
"code": "NOTIF_COMPONENT_DIR_NOT_FOUND",
|
|
1838
|
-
"source": "dbx_notification_m_validate_app",
|
|
1839
|
-
"severity": "error",
|
|
1840
|
-
"title": "The component package directory does not exist on disk",
|
|
1841
|
-
"whatItFlags": "The component package directory does not exist on disk.",
|
|
1842
|
-
"whenItApplies": "When the supplied `componentDir` does not resolve to a directory entry.",
|
|
1843
|
-
"whenItDoesNotApply": "Components intentionally not part of this validation pass — pass `--skip notification_m` to `dbx_app_validate` instead.",
|
|
1844
|
-
"canonicalFix": "Verify the path argument resolves to an existing component package root.",
|
|
1845
|
-
"seeAlso": [
|
|
1846
|
-
{
|
|
1847
|
-
"kind": "tool",
|
|
1848
|
-
"target": "dbx_notification_m_validate_folder"
|
|
1849
|
-
}
|
|
1850
|
-
]
|
|
1851
|
-
},
|
|
1852
|
-
{
|
|
1853
|
-
"code": "NOTIF_COMPONENT_NOTIFICATION_FOLDER_MISSING",
|
|
1854
|
-
"source": "dbx_notification_m_validate_app",
|
|
1855
|
-
"severity": "error",
|
|
1856
|
-
"title": "The component root exists but `src/lib/model/notification/` is missing",
|
|
1857
|
-
"whatItFlags": "The component root exists but `src/lib/model/notification/` is missing.",
|
|
1858
|
-
"whenItApplies": "Components that should ship template / task constants but lack the notification model folder.",
|
|
1859
|
-
"whenItDoesNotApply": "Components that intentionally don't extend the notification group.",
|
|
1860
|
-
"canonicalFix": "Add `src/lib/model/notification/notification.ts` and the rest of the notification artefacts.",
|
|
1861
|
-
"seeAlso": [
|
|
1862
|
-
{
|
|
1863
|
-
"kind": "artifact",
|
|
1864
|
-
"target": "notification-template"
|
|
1865
|
-
},
|
|
1866
|
-
{
|
|
1867
|
-
"kind": "artifact",
|
|
1868
|
-
"target": "notification-task"
|
|
1869
|
-
}
|
|
1870
|
-
]
|
|
1871
|
-
},
|
|
1872
|
-
{
|
|
1873
|
-
"code": "NOTIF_TASK_HANDLER_NAME_MISMATCH",
|
|
1874
|
-
"source": "dbx_notification_m_validate_app",
|
|
1875
|
-
"severity": "error",
|
|
1876
|
-
"title": "A `NotificationTaskServiceTaskHandlerConfig`'s binding name doesn't match its handler-array reference",
|
|
1877
|
-
"whatItFlags": "A `NotificationTaskServiceTaskHandlerConfig`'s binding name doesn't match its handler-array reference.",
|
|
1878
|
-
"whenItApplies": "When the handler is bound to a typed const but the local-variable name diverges from the array element name in `notificationTaskService({ handlers })`.",
|
|
1879
|
-
"whenItDoesNotApply": "Inline / anonymous handler literals (no binding name to check against).",
|
|
1880
|
-
"canonicalFix": "Rename the binding to match the handler-array element, or update the array reference to match the binding."
|
|
1881
|
-
},
|
|
1882
|
-
{
|
|
1883
|
-
"code": "NOTIF_TASK_HANDLER_ORPHAN",
|
|
1884
|
-
"source": "dbx_notification_m_validate_app",
|
|
1885
|
-
"severity": "error",
|
|
1886
|
-
"title": "A `NotificationTaskServiceTaskHandlerConfig` references a `type:` identifier that is not a declared task-type constant",
|
|
1887
|
-
"whatItFlags": "A `NotificationTaskServiceTaskHandlerConfig` references a `type:` identifier that is not a declared task-type constant.",
|
|
1888
|
-
"whenItApplies": "When the handler's `type:` is an identifier outside the component's declared constants and the trust list.",
|
|
1889
|
-
"whenItDoesNotApply": "Handler configs whose `type:` is imported from a trust-listed module.",
|
|
1890
|
-
"canonicalFix": "Either declare the matching task-type constant or remove the orphaned handler config."
|
|
1891
|
-
},
|
|
1892
|
-
{
|
|
1893
|
-
"code": "NOTIF_TASK_HANDLER_SPREAD_UNRESOLVED",
|
|
1894
|
-
"source": "dbx_notification_m_validate_app",
|
|
1895
|
-
"severity": "warning",
|
|
1896
|
-
"title": "The `handlers:` array spreads an identifier that doesn't resolve to a declared array binding",
|
|
1897
|
-
"whatItFlags": "The `handlers:` array spreads an identifier that doesn't resolve to a declared array binding.",
|
|
1898
|
-
"whenItApplies": "When `notificationTaskService({ handlers: [...spread] })` spreads an identifier that isn't a typed `NotificationTaskServiceTaskHandlerConfig[]` binding or trusted external.",
|
|
1899
|
-
"whenItDoesNotApply": "Spreads from trust-listed `@dereekb/*` modules (e.g. `storageFileProcessingNotificationTaskHandler`).",
|
|
1900
|
-
"canonicalFix": "Declare the spread as `const <name>: NotificationTaskServiceTaskHandlerConfig<...>[] = [...]` or import it from a trusted module."
|
|
1901
|
-
},
|
|
1902
|
-
{
|
|
1903
|
-
"code": "NOTIF_TASK_IN_VALIDATE_WITHOUT_HANDLER",
|
|
1904
|
-
"source": "dbx_notification_m_validate_app",
|
|
1905
|
-
"severity": "warning",
|
|
1906
|
-
"title": "A task type appears in `validate:` but has no matching `handlers:` registration",
|
|
1907
|
-
"whatItFlags": "A task type appears in `validate:` but has no matching `handlers:` registration.",
|
|
1908
|
-
"whenItApplies": "When `notificationTaskService({ validate, handlers })` lists a task type in `validate:` that the `handlers:` traversal doesn't reach.",
|
|
1909
|
-
"whenItDoesNotApply": "Tasks whose handler is provided by an upstream module (covered by the trust list).",
|
|
1910
|
-
"canonicalFix": "Add the matching `NotificationTaskServiceTaskHandlerConfig` for the task and include it in `handlers:`."
|
|
1911
|
-
},
|
|
1912
|
-
{
|
|
1913
|
-
"code": "NOTIF_TASK_MULTIPLE_SERVICES",
|
|
1914
|
-
"source": "dbx_notification_m_validate_app",
|
|
1915
|
-
"severity": "warning",
|
|
1916
|
-
"title": "Multiple `notificationTaskService({ ... })` calls were found",
|
|
1917
|
-
"whatItFlags": "Multiple `notificationTaskService({ ... })` calls were found.",
|
|
1918
|
-
"whenItApplies": "When more than one task-service factory exists in the API.",
|
|
1919
|
-
"whenItDoesNotApply": "Apps that intentionally compose multiple task services (rare — only the first call's config takes effect at runtime).",
|
|
1920
|
-
"canonicalFix": "Consolidate the calls into one — the second call's handlers are unused at runtime."
|
|
1921
|
-
},
|
|
1922
|
-
{
|
|
1923
|
-
"code": "NOTIF_TASK_NOT_IN_ALL_ARRAY",
|
|
1924
|
-
"source": "dbx_notification_m_validate_app",
|
|
1925
|
-
"severity": "error",
|
|
1926
|
-
"title": "A declared `*_NOTIFICATION_TASK_TYPE` is not present in any `ALL_*_NOTIFICATION_TASK_TYPES` aggregate array",
|
|
1927
|
-
"whatItFlags": "A declared `*_NOTIFICATION_TASK_TYPE` is not present in any `ALL_*_NOTIFICATION_TASK_TYPES` aggregate array.",
|
|
1928
|
-
"whenItApplies": "Every declared task-type constant.",
|
|
1929
|
-
"whenItDoesNotApply": "Task-type constants intentionally held outside any aggregate (rare — most apps centralise the list).",
|
|
1930
|
-
"canonicalFix": "Add the constant to `ALL_<NAME>_NOTIFICATION_TASK_TYPES: NotificationTaskType[]` so the aggregate stays comprehensive."
|
|
1931
|
-
},
|
|
1932
|
-
{
|
|
1933
|
-
"code": "NOTIF_TASK_NOT_REGISTERED_IN_SERVICE",
|
|
1934
|
-
"source": "dbx_notification_m_validate_app",
|
|
1935
|
-
"severity": "error",
|
|
1936
|
-
"title": "A declared `*_NOTIFICATION_TASK_TYPE` is not reachable from any `notificationTaskService({ handlers })` call",
|
|
1937
|
-
"whatItFlags": "A declared `*_NOTIFICATION_TASK_TYPE` is not reachable from any `notificationTaskService({ handlers })` call.",
|
|
1938
|
-
"whenItApplies": "Every declared task-type constant.",
|
|
1939
|
-
"whenItDoesNotApply": "Task-type constants whose handler is provided by an upstream module (covered by the trust list).",
|
|
1940
|
-
"canonicalFix": "Add a `NotificationTaskServiceTaskHandlerConfig<...>` for the task and include its binding in `notificationTaskService({ handlers: [...] })`.",
|
|
1941
|
-
"seeAlso": [
|
|
1942
|
-
{
|
|
1943
|
-
"kind": "artifact",
|
|
1944
|
-
"target": "notification-task"
|
|
1945
|
-
},
|
|
1946
|
-
{
|
|
1947
|
-
"kind": "doc",
|
|
1948
|
-
"target": "dbx__guide__notification-task"
|
|
1949
|
-
}
|
|
1950
|
-
]
|
|
1951
|
-
},
|
|
1952
|
-
{
|
|
1953
|
-
"code": "NOTIF_TASK_SERVICE_FACTORY_MISSING",
|
|
1954
|
-
"source": "dbx_notification_m_validate_app",
|
|
1955
|
-
"severity": "error",
|
|
1956
|
-
"title": "No `notificationTaskService({ ... })` call was found in the API",
|
|
1957
|
-
"whatItFlags": "No `notificationTaskService({ ... })` call was found in the API.",
|
|
1958
|
-
"whenItApplies": "APIs that declare at least one `*_NOTIFICATION_TASK_TYPE`.",
|
|
1959
|
-
"whenItDoesNotApply": "APIs whose task service is provided by an upstream module (rare — extend the scanner's subpaths if so).",
|
|
1960
|
-
"canonicalFix": "Add `notificationTaskService({ validate: [...], handlers: [...] })` and bind it through the notification module."
|
|
1961
|
-
},
|
|
1962
|
-
{
|
|
1963
|
-
"code": "NOTIF_TASK_TYPE_CODE_DUPLICATE",
|
|
1964
|
-
"source": "dbx_notification_m_validate_app",
|
|
1965
|
-
"severity": "warning",
|
|
1966
|
-
"title": "Two `*_NOTIFICATION_TASK_TYPE` constants share the same string literal value",
|
|
1967
|
-
"whatItFlags": "Two `*_NOTIFICATION_TASK_TYPE` constants share the same string literal value.",
|
|
1968
|
-
"whenItApplies": "When more than one task-type constant resolves to the same `'<value>'` literal.",
|
|
1969
|
-
"whenItDoesNotApply": "Constants intentionally aliased — but this defeats runtime task discrimination, so almost always a copy-paste.",
|
|
1970
|
-
"canonicalFix": "Rename one of the literals so each task code is unique."
|
|
1971
|
-
},
|
|
1972
|
-
{
|
|
1973
|
-
"code": "NOTIF_TEMPLATE_FACTORY_ARRAY_MISSING",
|
|
1974
|
-
"source": "dbx_notification_m_validate_app",
|
|
1975
|
-
"severity": "error",
|
|
1976
|
-
"title": "No top-level `<app>NotificationTemplateServiceConfigsArrayFactory` was found",
|
|
1977
|
-
"whatItFlags": "No top-level `<app>NotificationTemplateServiceConfigsArrayFactory` was found.",
|
|
1978
|
-
"whenItApplies": "APIs that declare at least one `NotificationTemplateTypeInfo`.",
|
|
1979
|
-
"whenItDoesNotApply": "APIs whose configs-array factory is provided by an upstream module (rare — convention is one factory per app).",
|
|
1980
|
-
"canonicalFix": "Declare `export function <app>NotificationTemplateServiceConfigsArrayFactory(context): NotificationTemplateServiceTypeConfig[] { return [<foo>NotificationTemplateFactory(context), ...]; }`."
|
|
1981
|
-
},
|
|
1982
|
-
{
|
|
1983
|
-
"code": "NOTIF_TEMPLATE_FACTORY_MISSING",
|
|
1984
|
-
"source": "dbx_notification_m_validate_app",
|
|
1985
|
-
"severity": "error",
|
|
1986
|
-
"title": "A `*_NOTIFICATION_TEMPLATE_TYPE` constant has no matching `NotificationTemplateServiceTypeConfig` reachable from the configs-array factory",
|
|
1987
|
-
"whatItFlags": "A `*_NOTIFICATION_TEMPLATE_TYPE` constant has no matching `NotificationTemplateServiceTypeConfig` reachable from the configs-array factory.",
|
|
1988
|
-
"whenItApplies": "Every declared template-type constant.",
|
|
1989
|
-
"whenItDoesNotApply": "Template types whose handler config is provided by an upstream module (covered by the trust list).",
|
|
1990
|
-
"canonicalFix": "Declare a `<foo>NotificationTemplateFactory` returning the `NotificationTemplateServiceTypeConfig` and call it from the app's configs-array factory.",
|
|
1991
|
-
"seeAlso": [
|
|
1992
|
-
{
|
|
1993
|
-
"kind": "artifact",
|
|
1994
|
-
"target": "notification-template"
|
|
1995
|
-
}
|
|
1996
|
-
]
|
|
1997
|
-
},
|
|
1998
|
-
{
|
|
1999
|
-
"code": "NOTIF_TEMPLATE_FACTORY_NOT_WIRED",
|
|
2000
|
-
"source": "dbx_notification_m_validate_app",
|
|
2001
|
-
"severity": "error",
|
|
2002
|
-
"title": "The configs-array factory exists but no NestJS provider binds it via `NOTIFICATION_TEMPLATE_SERVICE_CONFIGS_ARRAY_TOKEN`",
|
|
2003
|
-
"whatItFlags": "The configs-array factory exists but no NestJS provider binds it via `NOTIFICATION_TEMPLATE_SERVICE_CONFIGS_ARRAY_TOKEN`.",
|
|
2004
|
-
"whenItApplies": "When `<app>NotificationTemplateServiceConfigsArrayFactory` exists but no `{ provide: NOTIFICATION_TEMPLATE_SERVICE_CONFIGS_ARRAY_TOKEN, useFactory }` provider exists.",
|
|
2005
|
-
"whenItDoesNotApply": "APIs that wire the factory indirectly through an imported app-module (rare — extend the scanner's subpaths if so).",
|
|
2006
|
-
"canonicalFix": "Add a NestJS provider with `provide: NOTIFICATION_TEMPLATE_SERVICE_CONFIGS_ARRAY_TOKEN, useFactory: <app>NotificationTemplateServiceConfigsArrayFactory`."
|
|
2007
|
-
},
|
|
2008
|
-
{
|
|
2009
|
-
"code": "NOTIF_TEMPLATE_FACTORY_ORPHAN",
|
|
2010
|
-
"source": "dbx_notification_m_validate_app",
|
|
2011
|
-
"severity": "error",
|
|
2012
|
-
"title": "A `NotificationTemplateServiceTypeConfig` references a `type:` identifier that is not a declared template-type constant",
|
|
2013
|
-
"whatItFlags": "A `NotificationTemplateServiceTypeConfig` references a `type:` identifier that is not a declared template-type constant.",
|
|
2014
|
-
"whenItApplies": "When the handler config's `type:` is an identifier outside the component's declared constants and the trust list.",
|
|
2015
|
-
"whenItDoesNotApply": "Handler configs whose `type:` is imported from a trust-listed module.",
|
|
2016
|
-
"canonicalFix": "Either declare the matching template-type constant or remove the orphaned config."
|
|
2017
|
-
},
|
|
2018
|
-
{
|
|
2019
|
-
"code": "NOTIF_TEMPLATE_FACTORY_SPREAD_UNRESOLVED",
|
|
2020
|
-
"source": "dbx_notification_m_validate_app",
|
|
2021
|
-
"severity": "warning",
|
|
2022
|
-
"title": "The configs-array factory spreads an identifier that doesn't resolve to a declared function",
|
|
2023
|
-
"whatItFlags": "The configs-array factory spreads an identifier that doesn't resolve to a declared function.",
|
|
2024
|
-
"whenItApplies": "When `<app>NotificationTemplateServiceConfigsArrayFactory` spreads (`...fooNotifications(context)`) a function that isn't declared locally or imported.",
|
|
2025
|
-
"whenItDoesNotApply": "Spreads from trust-listed `@dereekb/*` modules.",
|
|
2026
|
-
"canonicalFix": "Declare the missing function or import it from a trusted module."
|
|
2027
|
-
},
|
|
2028
|
-
{
|
|
2029
|
-
"code": "NOTIF_TEMPLATE_INFO_MISSING",
|
|
2030
|
-
"source": "dbx_notification_m_validate_app",
|
|
2031
|
-
"severity": "error",
|
|
2032
|
-
"title": "A `*_NOTIFICATION_TEMPLATE_TYPE` constant has no matching `NotificationTemplateTypeInfo` object",
|
|
2033
|
-
"whatItFlags": "A `*_NOTIFICATION_TEMPLATE_TYPE` constant has no matching `NotificationTemplateTypeInfo` object.",
|
|
2034
|
-
"whenItApplies": "Every declared template-type constant in the component.",
|
|
2035
|
-
"whenItDoesNotApply": "Template types declared in an upstream `@dereekb/*` module — those are detected via the trust list and skipped.",
|
|
2036
|
-
"canonicalFix": "Declare `export const <foo>NotificationTemplateTypeInfo: NotificationTemplateTypeInfo = { type: <CONSTANT>, name, description, ... }` adjacent to the constant.",
|
|
2037
|
-
"seeAlso": [
|
|
2038
|
-
{
|
|
2039
|
-
"kind": "artifact",
|
|
2040
|
-
"target": "notification-template"
|
|
2041
|
-
}
|
|
2042
|
-
]
|
|
2043
|
-
},
|
|
2044
|
-
{
|
|
2045
|
-
"code": "NOTIF_TEMPLATE_INFO_MISSING_NAME_OR_DESCRIPTION",
|
|
2046
|
-
"source": "dbx_notification_m_validate_app",
|
|
2047
|
-
"severity": "warning",
|
|
2048
|
-
"title": "A `NotificationTemplateTypeInfo` object is missing the `name` and/or `description` field",
|
|
2049
|
-
"whatItFlags": "A `NotificationTemplateTypeInfo` object is missing the `name` and/or `description` field.",
|
|
2050
|
-
"whenItApplies": "Every declared `NotificationTemplateTypeInfo` whose `name` or `description` is empty / missing.",
|
|
2051
|
-
"whenItDoesNotApply": "Infos whose human-readable fields are intentionally blank (rare — most consumers surface them in admin UI).",
|
|
2052
|
-
"canonicalFix": "Populate `name: '...'` and `description: '...'` on the info object so admin / tooling surfaces have something to render."
|
|
2053
|
-
},
|
|
2054
|
-
{
|
|
2055
|
-
"code": "NOTIF_TEMPLATE_INFO_NOT_IN_RECORD",
|
|
2056
|
-
"source": "dbx_notification_m_validate_app",
|
|
2057
|
-
"severity": "error",
|
|
2058
|
-
"title": "A declared `NotificationTemplateTypeInfo` is not reachable from the metadata aggregator record",
|
|
2059
|
-
"whatItFlags": "A declared `NotificationTemplateTypeInfo` is not reachable from the metadata aggregator record.",
|
|
2060
|
-
"whenItApplies": "Every info object whose symbol does not appear in the resolved set traced from `notificationTemplateTypeInfoRecord([...])`.",
|
|
2061
|
-
"whenItDoesNotApply": "Infos intentionally excluded from the runtime record (rare — usually a missed registration step).",
|
|
2062
|
-
"canonicalFix": "Add the info symbol (or its containing `ALL_*_NOTIFICATION_TEMPLATE_TYPE_INFOS` aggregate) to the record array."
|
|
2063
|
-
},
|
|
2064
|
-
{
|
|
2065
|
-
"code": "NOTIF_TEMPLATE_INFO_TYPE_MISMATCH",
|
|
2066
|
-
"source": "dbx_notification_m_validate_app",
|
|
2067
|
-
"severity": "error",
|
|
2068
|
-
"title": "A `NotificationTemplateTypeInfo` object's `type:` does not match a declared template-type constant",
|
|
2069
|
-
"whatItFlags": "A `NotificationTemplateTypeInfo` object's `type:` does not match a declared template-type constant.",
|
|
2070
|
-
"whenItApplies": "When the info's `type:` references a missing constant or an identifier outside the trust list.",
|
|
2071
|
-
"whenItDoesNotApply": "Info objects whose `type:` is provided by an imported `@dereekb/*` constant — covered by the trust list.",
|
|
2072
|
-
"canonicalFix": "Either declare the missing template-type constant or update the info's `type:` to a real constant in the component."
|
|
2073
|
-
},
|
|
2074
|
-
{
|
|
2075
|
-
"code": "NOTIF_TEMPLATE_INFO_UNUSED",
|
|
2076
|
-
"source": "dbx_notification_m_validate_app",
|
|
2077
|
-
"severity": "warning",
|
|
2078
|
-
"title": "A declared `NotificationTemplateTypeInfo` is unused — its symbol isn't reachable from the metadata aggregator",
|
|
2079
|
-
"whatItFlags": "A declared `NotificationTemplateTypeInfo` is unused — its symbol isn't reachable from the metadata aggregator.",
|
|
2080
|
-
"whenItApplies": "When the info's symbol does not appear in any aggregate array or the resolved record set.",
|
|
2081
|
-
"whenItDoesNotApply": "Infos kept around for documentation / future wiring (rare — usually rename drift).",
|
|
2082
|
-
"canonicalFix": "Either remove the orphan info or add it to the appropriate `ALL_*_NOTIFICATION_TEMPLATE_TYPE_INFOS` aggregate."
|
|
2083
|
-
},
|
|
2084
|
-
{
|
|
2085
|
-
"code": "NOTIF_TEMPLATE_RECORD_MISSING",
|
|
2086
|
-
"source": "dbx_notification_m_validate_app",
|
|
2087
|
-
"severity": "error",
|
|
2088
|
-
"title": "No top-level `notificationTemplateTypeInfoRecord([...])` call was found",
|
|
2089
|
-
"whatItFlags": "No top-level `notificationTemplateTypeInfoRecord([...])` call was found.",
|
|
2090
|
-
"whenItApplies": "Components that declare at least one `NotificationTemplateTypeInfo`.",
|
|
2091
|
-
"whenItDoesNotApply": "Components whose record is provided by an upstream `@dereekb/*` module (rare — convention is one record per app).",
|
|
2092
|
-
"canonicalFix": "Declare `export const <APP>_FIREBASE_NOTIFICATION_TEMPLATE_TYPE_INFO_RECORD = notificationTemplateTypeInfoRecord([...]);` covering every template info."
|
|
2093
|
-
},
|
|
2094
|
-
{
|
|
2095
|
-
"code": "NOTIF_TEMPLATE_RECORD_NOT_WIRED",
|
|
2096
|
-
"source": "dbx_notification_m_validate_app",
|
|
2097
|
-
"severity": "error",
|
|
2098
|
-
"title": "The metadata record exists but is not wired through `appNotificationTemplateTypeInfoRecordService(...)` in the API",
|
|
2099
|
-
"whatItFlags": "The metadata record exists but is not wired through `appNotificationTemplateTypeInfoRecordService(...)` in the API.",
|
|
2100
|
-
"whenItApplies": "When `appNotificationTemplateTypeInfoRecordService(...)` is missing or its argument doesn't resolve to the declared record.",
|
|
2101
|
-
"whenItDoesNotApply": "APIs that wire the record indirectly through an imported app-module (rare — extend the scanner's subpaths if so).",
|
|
2102
|
-
"canonicalFix": "Add `appNotificationTemplateTypeInfoRecordService(<APP>_FIREBASE_NOTIFICATION_TEMPLATE_TYPE_INFO_RECORD)` to the API's notification module."
|
|
2103
|
-
},
|
|
2104
|
-
{
|
|
2105
|
-
"code": "NOTIF_TEMPLATE_SPREAD_UNRESOLVED",
|
|
2106
|
-
"source": "dbx_notification_m_validate_app",
|
|
2107
|
-
"severity": "error",
|
|
2108
|
-
"title": "The metadata record's `[...]` array spreads an identifier that doesn't resolve to a declared aggregate",
|
|
2109
|
-
"whatItFlags": "The metadata record's `[...]` array spreads an identifier that doesn't resolve to a declared aggregate.",
|
|
2110
|
-
"whenItApplies": "When `notificationTemplateTypeInfoRecord([...])` spreads a name that isn't a `ALL_*_NOTIFICATION_TEMPLATE_TYPE_INFOS` aggregate or trusted external.",
|
|
2111
|
-
"whenItDoesNotApply": "Spreads from trust-listed `@dereekb/*` modules.",
|
|
2112
|
-
"canonicalFix": "Declare the aggregate as `export const ALL_<NAME>_NOTIFICATION_TEMPLATE_TYPE_INFOS: NotificationTemplateTypeInfo[] = [...]` or import it from a trusted module."
|
|
2113
|
-
},
|
|
2114
|
-
{
|
|
2115
|
-
"code": "NOTIF_TEMPLATE_TYPE_CODE_DUPLICATE",
|
|
2116
|
-
"source": "dbx_notification_m_validate_app",
|
|
2117
|
-
"severity": "warning",
|
|
2118
|
-
"title": "Two `*_NOTIFICATION_TEMPLATE_TYPE` constants share the same string literal value",
|
|
2119
|
-
"whatItFlags": "Two `*_NOTIFICATION_TEMPLATE_TYPE` constants share the same string literal value.",
|
|
2120
|
-
"whenItApplies": "When more than one template-type constant resolves to the same `'<value>'` literal.",
|
|
2121
|
-
"whenItDoesNotApply": "Constants intentionally aliased — but this defeats persisted-document discrimination, so almost always a copy-paste.",
|
|
2122
|
-
"canonicalFix": "Rename one of the literals so each template code is unique."
|
|
2123
|
-
},
|
|
2124
|
-
{
|
|
2125
|
-
"code": "NOTIF_FOLDER_API_DIR_NOT_FOUND",
|
|
2126
|
-
"source": "dbx_notification_m_validate_folder",
|
|
2127
|
-
"severity": "error",
|
|
2128
|
-
"title": "The API app directory does not exist on disk",
|
|
2129
|
-
"whatItFlags": "The API app directory does not exist on disk.",
|
|
2130
|
-
"whenItApplies": "When the supplied `apiDir` does not resolve to a directory entry.",
|
|
2131
|
-
"whenItDoesNotApply": "API apps intentionally not validated — pass `--skip notification_m` instead.",
|
|
2132
|
-
"canonicalFix": "Verify the path argument resolves to an existing API app root.",
|
|
2133
|
-
"seeAlso": [
|
|
2134
|
-
{
|
|
2135
|
-
"kind": "tool",
|
|
2136
|
-
"target": "dbx_notification_m_validate_folder"
|
|
2137
|
-
}
|
|
2138
|
-
]
|
|
2139
|
-
},
|
|
2140
|
-
{
|
|
2141
|
-
"code": "NOTIF_FOLDER_API_FOLDER_MISSING",
|
|
2142
|
-
"source": "dbx_notification_m_validate_folder",
|
|
2143
|
-
"severity": "error",
|
|
2144
|
-
"title": "The API root exists but `src/app/common/model/notification/` is missing",
|
|
2145
|
-
"whatItFlags": "The API root exists but `src/app/common/model/notification/` is missing.",
|
|
2146
|
-
"whenItApplies": "API apps expected to wire the notification module but with no notification folder.",
|
|
2147
|
-
"whenItDoesNotApply": "API apps that intentionally don't wire notifications — pass `--skip notification_m`.",
|
|
2148
|
-
"canonicalFix": "Add `src/app/common/model/notification/` with `notification.module.ts`, `notification.task.service.ts`, and `notification.send.service.ts`.",
|
|
2149
|
-
"seeAlso": [
|
|
2150
|
-
{
|
|
2151
|
-
"kind": "artifact",
|
|
2152
|
-
"target": "notification-template"
|
|
2153
|
-
}
|
|
2154
|
-
]
|
|
2155
|
-
},
|
|
2156
|
-
{
|
|
2157
|
-
"code": "NOTIF_FOLDER_BARREL_REEXPORT_MISSING",
|
|
2158
|
-
"source": "dbx_notification_m_validate_folder",
|
|
2159
|
-
"severity": "error",
|
|
2160
|
-
"title": "`index.ts` re-exports a path that does not resolve to a sibling file or subfolder",
|
|
2161
|
-
"whatItFlags": "`index.ts` re-exports a path that does not resolve to a sibling file or subfolder.",
|
|
2162
|
-
"whenItApplies": "When `export * from './X'` in `index.ts` has no matching `./X.ts` or `./X/` under the notification folder root.",
|
|
2163
|
-
"whenItDoesNotApply": "Re-exports that intentionally point outside the folder (use a relative path that climbs out, not `./X`).",
|
|
2164
|
-
"canonicalFix": "Add the missing `<name>.ts` / `<name>/` sibling, or remove the dangling re-export from `index.ts`."
|
|
2165
|
-
},
|
|
2166
|
-
{
|
|
2167
|
-
"code": "NOTIF_FOLDER_COMPONENT_DIR_NOT_FOUND",
|
|
2168
|
-
"source": "dbx_notification_m_validate_folder",
|
|
2169
|
-
"severity": "error",
|
|
2170
|
-
"title": "The component package directory does not exist on disk",
|
|
2171
|
-
"whatItFlags": "The component package directory does not exist on disk.",
|
|
2172
|
-
"whenItApplies": "When the supplied `componentDir` does not resolve to a directory entry.",
|
|
2173
|
-
"whenItDoesNotApply": "Components intentionally not part of this validation pass — pass `--skip notification_m` to `dbx_app_validate` instead.",
|
|
2174
|
-
"canonicalFix": "Verify the path argument resolves to an existing component package root.",
|
|
2175
|
-
"seeAlso": [
|
|
2176
|
-
{
|
|
2177
|
-
"kind": "tool",
|
|
2178
|
-
"target": "dbx_notification_m_validate_folder"
|
|
2179
|
-
}
|
|
2180
|
-
]
|
|
2181
|
-
},
|
|
2182
|
-
{
|
|
2183
|
-
"code": "NOTIF_FOLDER_COMPONENT_FOLDER_MISSING",
|
|
2184
|
-
"source": "dbx_notification_m_validate_folder",
|
|
2185
|
-
"severity": "error",
|
|
2186
|
-
"title": "The component root exists but `src/lib/model/notification/` is missing",
|
|
2187
|
-
"whatItFlags": "The component root exists but `src/lib/model/notification/` is missing.",
|
|
2188
|
-
"whenItApplies": "Components that should ship `NotificationTemplateType` / `NotificationTaskType` constants but lack the notification model folder.",
|
|
2189
|
-
"whenItDoesNotApply": "Components that intentionally don't extend the notification group (rare — most apps with notifications do).",
|
|
2190
|
-
"canonicalFix": "Add `src/lib/model/notification/notification.ts` and the rest of the notification artefacts.",
|
|
2191
|
-
"seeAlso": [
|
|
2192
|
-
{
|
|
2193
|
-
"kind": "artifact",
|
|
2194
|
-
"target": "notification-template"
|
|
2195
|
-
},
|
|
2196
|
-
{
|
|
2197
|
-
"kind": "artifact",
|
|
2198
|
-
"target": "notification-task"
|
|
2199
|
-
}
|
|
2200
|
-
]
|
|
2201
|
-
},
|
|
2202
|
-
{
|
|
2203
|
-
"code": "NOTIF_FOLDER_HANDLERS_SUBFOLDER_MIXED",
|
|
2204
|
-
"source": "dbx_notification_m_validate_folder",
|
|
2205
|
-
"severity": "warning",
|
|
2206
|
-
"title": "A non-canonical `.ts` file lives at the API notification root alongside a `handlers/` subfolder",
|
|
2207
|
-
"whatItFlags": "A non-canonical `.ts` file lives at the API notification root alongside a `handlers/` subfolder.",
|
|
2208
|
-
"whenItApplies": "API folders that mix root-level handler files with a sibling `handlers/` subfolder.",
|
|
2209
|
-
"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.",
|
|
2210
|
-
"canonicalFix": "Move the handler file into `handlers/` so the convention stays consistent across the project."
|
|
2211
|
-
},
|
|
2212
|
-
{
|
|
2213
|
-
"code": "NOTIF_FOLDER_MODULE_FILE_MISSING",
|
|
2214
|
-
"source": "dbx_notification_m_validate_folder",
|
|
2215
|
-
"severity": "error",
|
|
2216
|
-
"title": "The API notification folder is missing the required `notification.module.ts` file",
|
|
2217
|
-
"whatItFlags": "The API notification folder is missing the required `notification.module.ts` file.",
|
|
2218
|
-
"whenItApplies": "Every API notification folder that exists.",
|
|
2219
|
-
"whenItDoesNotApply": "The NestJS notification module is provided elsewhere in the app (rare — convention is one module per folder).",
|
|
2220
|
-
"canonicalFix": "Add `notification.module.ts` declaring the NestJS module that binds the notification task / send service providers."
|
|
2221
|
-
},
|
|
2222
|
-
{
|
|
2223
|
-
"code": "NOTIF_FOLDER_SEND_SERVICE_FILE_MISSING",
|
|
2224
|
-
"source": "dbx_notification_m_validate_folder",
|
|
2225
|
-
"severity": "error",
|
|
2226
|
-
"title": "The API notification folder is missing the required `notification.send.service.ts` file",
|
|
2227
|
-
"whatItFlags": "The API notification folder is missing the required `notification.send.service.ts` file.",
|
|
2228
|
-
"whenItApplies": "Every API notification folder that exists.",
|
|
2229
|
-
"whenItDoesNotApply": "Apps whose `NotificationSendService` factory lives elsewhere (rare — convention is one factory per folder).",
|
|
2230
|
-
"canonicalFix": "Add `notification.send.service.ts` exporting the `NotificationSendService` factory wired through the notification module."
|
|
2231
|
-
},
|
|
2232
|
-
{
|
|
2233
|
-
"code": "NOTIF_FOLDER_TASK_SERVICE_FILE_MISSING",
|
|
2234
|
-
"source": "dbx_notification_m_validate_folder",
|
|
2235
|
-
"severity": "error",
|
|
2236
|
-
"title": "The API notification folder is missing the required `notification.task.service.ts` file",
|
|
2237
|
-
"whatItFlags": "The API notification folder is missing the required `notification.task.service.ts` file.",
|
|
2238
|
-
"whenItApplies": "Every API notification folder that exists.",
|
|
2239
|
-
"whenItDoesNotApply": "Apps whose `NotificationTaskService` factory lives elsewhere (rare — convention is one factory per folder).",
|
|
2240
|
-
"canonicalFix": "Add `notification.task.service.ts` exporting the `notificationTaskService({ ... })` factory call.",
|
|
2241
|
-
"seeAlso": [
|
|
2242
|
-
{
|
|
2243
|
-
"kind": "artifact",
|
|
2244
|
-
"target": "notification-task"
|
|
2245
|
-
}
|
|
2246
|
-
]
|
|
2247
|
-
},
|
|
2248
|
-
{
|
|
2249
|
-
"code": "NOTIF_FOLDER_UNEXPECTED_FILE_NAME",
|
|
2250
|
-
"source": "dbx_notification_m_validate_folder",
|
|
2251
|
-
"severity": "warning",
|
|
2252
|
-
"title": "A `.ts` file in the notification folder doesn't start with the `notification.` prefix",
|
|
2253
|
-
"whatItFlags": "A `.ts` file in the notification folder doesn't start with the `notification.` prefix.",
|
|
2254
|
-
"whenItApplies": "Any `.ts` file other than `index.ts` whose basename doesn't start with `notification.`.",
|
|
2255
|
-
"whenItDoesNotApply": "Files outside the canonical layout that the project intentionally hosts here (rare — prefer moving them out).",
|
|
2256
|
-
"canonicalFix": "Rename the file to `notification.<sub>.ts`, or move it out of the notification folder."
|
|
2257
|
-
},
|
|
2258
|
-
{
|
|
2259
|
-
"code": "STORAGEFILE_API_DIR_NOT_FOUND",
|
|
2260
|
-
"source": "dbx_storagefile_m_validate_app",
|
|
2261
|
-
"severity": "error",
|
|
2262
|
-
"title": "The API app's `src/app/common/model/storagefile/` directory does not exist",
|
|
2263
|
-
"whatItFlags": "The API app's `src/app/common/model/storagefile/` directory does not exist.",
|
|
2264
|
-
"whenItApplies": "When `apiDir` resolves to a directory but the storagefile API folder is missing.",
|
|
2265
|
-
"whenItDoesNotApply": "API apps that intentionally don't wire storage-file purposes — pass `--skip storagefile_m` instead.",
|
|
2266
|
-
"canonicalFix": "Add `<apiDir>/src/app/common/model/storagefile/` with `storagefile.module.ts`, `storagefile.upload.service.ts`, and `storagefile.init.ts`.",
|
|
2267
|
-
"seeAlso": [
|
|
2268
|
-
{
|
|
2269
|
-
"kind": "tool",
|
|
2270
|
-
"target": "dbx_storagefile_m_validate_folder"
|
|
2271
|
-
}
|
|
2272
|
-
]
|
|
2273
|
-
},
|
|
2274
|
-
{
|
|
2275
|
-
"code": "STORAGEFILE_API_FOLDER_MISSING",
|
|
2276
|
-
"source": "dbx_storagefile_m_validate_app",
|
|
2277
|
-
"severity": "error",
|
|
2278
|
-
"title": "The API root exists but neither `src/app/common/model/storagefile/` nor",
|
|
2279
|
-
"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/`).",
|
|
2280
|
-
"whenItApplies": "When the API package is present but has no storagefile or notification subfolders.",
|
|
2281
|
-
"whenItDoesNotApply": "API apps that don't wire storage-file or notification purposes.",
|
|
2282
|
-
"canonicalFix": "Add `src/app/common/model/storagefile/` and (if processing handlers are needed) `src/app/common/model/notification/handlers/`.",
|
|
2283
|
-
"seeAlso": [
|
|
2284
|
-
{
|
|
2285
|
-
"kind": "tool",
|
|
2286
|
-
"target": "dbx_storagefile_m_validate_folder"
|
|
2287
|
-
}
|
|
2288
|
-
]
|
|
2289
|
-
},
|
|
2290
|
-
{
|
|
2291
|
-
"code": "STORAGEFILE_COMPONENT_DIR_NOT_FOUND",
|
|
2292
|
-
"source": "dbx_storagefile_m_validate_app",
|
|
2293
|
-
"severity": "error",
|
|
2294
|
-
"title": "The component's `src/lib/model/storagefile/` directory does not exist",
|
|
2295
|
-
"whatItFlags": "The component's `src/lib/model/storagefile/` directory does not exist.",
|
|
2296
|
-
"whenItApplies": "When `componentDir` resolves to a directory but the storagefile model folder is missing.",
|
|
2297
|
-
"whenItDoesNotApply": "Components that intentionally don't ship storage-file purposes — pass `--skip storagefile_m` to `dbx_app_validate` instead.",
|
|
2298
|
-
"canonicalFix": "Add `<componentDir>/src/lib/model/storagefile/storagefile.ts` and the rest of the storagefile artefacts.",
|
|
2299
|
-
"seeAlso": [
|
|
2300
|
-
{
|
|
2301
|
-
"kind": "artifact",
|
|
2302
|
-
"target": "storagefile-purpose"
|
|
2303
|
-
},
|
|
2304
|
-
{
|
|
2305
|
-
"kind": "tool",
|
|
2306
|
-
"target": "dbx_storagefile_m_validate_folder"
|
|
2307
|
-
}
|
|
2308
|
-
]
|
|
2309
|
-
},
|
|
2310
|
-
{
|
|
2311
|
-
"code": "STORAGEFILE_COMPONENT_FOLDER_MISSING",
|
|
2312
|
-
"source": "dbx_storagefile_m_validate_app",
|
|
2313
|
-
"severity": "error",
|
|
2314
|
-
"title": "The component root exists but has no `src/lib/model/storagefile/` subfolder",
|
|
2315
|
-
"whatItFlags": "The component root exists but has no `src/lib/model/storagefile/` subfolder.",
|
|
2316
|
-
"whenItApplies": "When the component package is present but has no storagefile model folder.",
|
|
2317
|
-
"whenItDoesNotApply": "Components that don't extend the storagefile group.",
|
|
2318
|
-
"canonicalFix": "Run `dbx_artifact_scaffold artifact=\"storagefile-purpose\"` to scaffold the folder layout.",
|
|
2319
|
-
"seeAlso": [
|
|
2320
|
-
{
|
|
2321
|
-
"kind": "artifact",
|
|
2322
|
-
"target": "storagefile-purpose"
|
|
2323
|
-
}
|
|
2324
|
-
]
|
|
2325
|
-
},
|
|
2326
|
-
{
|
|
2327
|
-
"code": "STORAGEFILE_FILE_TYPE_IDENTIFIER_DUPLICATE",
|
|
2328
|
-
"source": "dbx_storagefile_m_validate_app",
|
|
2329
|
-
"severity": "warning",
|
|
2330
|
-
"title": "Two `UploadedFileTypeIdentifier` constants share the same string",
|
|
2331
|
-
"whatItFlags": "Two `UploadedFileTypeIdentifier` constants share the same string\nliteral value.",
|
|
2332
|
-
"whenItApplies": "When more than one file-type identifier constant resolves to the same `'<value>'`.",
|
|
2333
|
-
"whenItDoesNotApply": "File-type identifiers intentionally re-used across purposes (rare — almost always a bug).",
|
|
2334
|
-
"canonicalFix": "Rename one of the literals so each file-type code is unique."
|
|
2335
|
-
},
|
|
2336
|
-
{
|
|
2337
|
-
"code": "STORAGEFILE_GROUP_IDS_FUNCTION_MISSING",
|
|
2338
|
-
"source": "dbx_storagefile_m_validate_app",
|
|
2339
|
-
"severity": "warning",
|
|
2340
|
-
"title": "A `*_PURPOSE` constant has no `<purpose>FileGroupIds(...)` or",
|
|
2341
|
-
"whatItFlags": "A `*_PURPOSE` constant has no `<purpose>FileGroupIds(...)` or\n`<purpose>StorageFileGroupIds(...)` helper function in the same\ncomponent.",
|
|
2342
|
-
"whenItApplies": "Validating a downstream `-firebase` component that declares at least one `StorageFilePurpose` constant.",
|
|
2343
|
-
"whenItDoesNotApply": "Purposes that intentionally hold no group membership (rare — most purposes belong to a workspace's group convention).",
|
|
2344
|
-
"canonicalFix": "Declare `export function <purpose>FileGroupIds(input): StorageFileGroupIds` adjacent to the purpose constant.",
|
|
2345
|
-
"canonicalFixTemplate": "```ts\nexport function <purpose>FileGroupIds(input: { /* ids the group needs *\\/ }): StorageFileGroupIds {\nreturn [storageFileGroupId({ /* ... *\\/ })];\n}\n```",
|
|
2346
|
-
"seeAlso": [
|
|
2347
|
-
{
|
|
2348
|
-
"kind": "artifact",
|
|
2349
|
-
"target": "storagefile-purpose"
|
|
2350
|
-
}
|
|
2351
|
-
]
|
|
2352
|
-
},
|
|
2353
|
-
{
|
|
2354
|
-
"code": "STORAGEFILE_PROCESSING_CONFIG_MISSING",
|
|
2355
|
-
"source": "dbx_storagefile_m_validate_app",
|
|
2356
|
-
"severity": "error",
|
|
2357
|
-
"title": "A purpose with subtasks has no",
|
|
2358
|
-
"whatItFlags": "A purpose with subtasks has no\n`StorageFileProcessingPurposeSubtaskProcessorConfig` whose `target:`\nreferences it.",
|
|
2359
|
-
"whenItApplies": "Every purpose that declares a `*ProcessingSubtask` union.",
|
|
2360
|
-
"whenItDoesNotApply": "Purposes whose processing config is provided by an upstream module.",
|
|
2361
|
-
"canonicalFix": "Add a config with `target: <PURPOSE_CONST>, flow: [{ subtask: <SUBTASK_CONST>, ... }, ...]`.",
|
|
2362
|
-
"seeAlso": [
|
|
2363
|
-
{
|
|
2364
|
-
"kind": "artifact",
|
|
2365
|
-
"target": "storagefile-processor"
|
|
2366
|
-
}
|
|
2367
|
-
]
|
|
2368
|
-
},
|
|
2369
|
-
{
|
|
2370
|
-
"code": "STORAGEFILE_PROCESSING_CONFIG_ORPHAN",
|
|
2371
|
-
"source": "dbx_storagefile_m_validate_app",
|
|
2372
|
-
"severity": "error",
|
|
2373
|
-
"title": "A processing config references a `target:` identifier that is not",
|
|
2374
|
-
"whatItFlags": "A processing config references a `target:` identifier that is not\nany declared `StorageFilePurpose` constant.",
|
|
2375
|
-
"whenItApplies": "When the `target:` identifier is local but not declared.",
|
|
2376
|
-
"whenItDoesNotApply": "When the target is imported from a trust-listed module.",
|
|
2377
|
-
"canonicalFix": "Either declare the purpose or remove the orphaned config."
|
|
2378
|
-
},
|
|
2379
|
-
{
|
|
2380
|
-
"code": "STORAGEFILE_PROCESSING_HANDLER_MISSING",
|
|
2381
|
-
"source": "dbx_storagefile_m_validate_app",
|
|
2382
|
-
"severity": "error",
|
|
2383
|
-
"title": "The component declares purposes with subtasks but no",
|
|
2384
|
-
"whatItFlags": "The component declares purposes with subtasks but no\n`storageFileProcessingNotificationTaskHandler({ processors })` call\nis present in the API.",
|
|
2385
|
-
"whenItApplies": "When at least one purpose declares a `*ProcessingSubtask` union and `*_PROCESSING_SUBTASK` constants.",
|
|
2386
|
-
"whenItDoesNotApply": "Purposes that store a file but do not need processing.",
|
|
2387
|
-
"canonicalFix": "Add a `storageFileProcessingNotificationTaskHandler({ processors: [...] })` call and wire it into the notification-task service.",
|
|
2388
|
-
"seeAlso": [
|
|
2389
|
-
{
|
|
2390
|
-
"kind": "artifact",
|
|
2391
|
-
"target": "storagefile-processor"
|
|
2392
|
-
}
|
|
2393
|
-
]
|
|
2394
|
-
},
|
|
2395
|
-
{
|
|
2396
|
-
"code": "STORAGEFILE_PROCESSING_SUBTASK_NOT_HANDLED",
|
|
2397
|
-
"source": "dbx_storagefile_m_validate_app",
|
|
2398
|
-
"severity": "error",
|
|
2399
|
-
"title": "A `*_PROCESSING_SUBTASK` declared on a purpose's union is absent",
|
|
2400
|
-
"whatItFlags": "A `*_PROCESSING_SUBTASK` declared on a purpose's union is absent\nfrom the matching processor config's `flow:` array.",
|
|
2401
|
-
"whenItApplies": "Every purpose × subtask pairing.",
|
|
2402
|
-
"whenItDoesNotApply": "Subtasks whose processor lives in a separate, dedicated config (uncommon — usually a missed flow step).",
|
|
2403
|
-
"canonicalFix": "Add `{ subtask: <SUBTASK_CONST>, processor: ... }` to the config's `flow:` array.",
|
|
2404
|
-
"seeAlso": [
|
|
2405
|
-
{
|
|
2406
|
-
"kind": "artifact",
|
|
2407
|
-
"target": "storagefile-processor-subtask"
|
|
2408
|
-
}
|
|
2409
|
-
]
|
|
2410
|
-
},
|
|
2411
|
-
{
|
|
2412
|
-
"code": "STORAGEFILE_PURPOSE_DUPLICATE",
|
|
2413
|
-
"source": "dbx_storagefile_m_validate_app",
|
|
2414
|
-
"severity": "warning",
|
|
2415
|
-
"title": "Two `StorageFilePurpose` constants share the same string literal value",
|
|
2416
|
-
"whatItFlags": "Two `StorageFilePurpose` constants share the same string literal value.",
|
|
2417
|
-
"whenItApplies": "When more than one purpose constant resolves to the same `'<value>'` literal.",
|
|
2418
|
-
"whenItDoesNotApply": "Purposes intentionally aliased — but this defeats persisted-document discrimination, so almost always a copy-paste.",
|
|
2419
|
-
"canonicalFix": "Rename one of the literals so each purpose code is unique."
|
|
2420
|
-
},
|
|
2421
|
-
{
|
|
2422
|
-
"code": "STORAGEFILE_PURPOSE_MISSING_FILE_TYPE_IDENTIFIER",
|
|
2423
|
-
"source": "dbx_storagefile_m_validate_app",
|
|
2424
|
-
"severity": "error",
|
|
2425
|
-
"title": "A `*_PURPOSE: StorageFilePurpose` constant has no matching",
|
|
2426
|
-
"whatItFlags": "A `*_PURPOSE: StorageFilePurpose` constant has no matching\n`*_UPLOADED_FILE_TYPE_IDENTIFIER` constant alongside it.",
|
|
2427
|
-
"whenItApplies": "Every declared `StorageFilePurpose` constant.",
|
|
2428
|
-
"whenItDoesNotApply": "Purposes whose file-type identifier is intentionally imported from a trust-listed `@dereekb/firebase` module.",
|
|
2429
|
-
"canonicalFix": "Declare `<PREFIX>_UPLOADED_FILE_TYPE_IDENTIFIER: UploadedFileTypeIdentifier = '...'` next to the purpose.",
|
|
2430
|
-
"seeAlso": [
|
|
2431
|
-
{
|
|
2432
|
-
"kind": "artifact",
|
|
2433
|
-
"target": "storagefile-purpose"
|
|
2434
|
-
}
|
|
2435
|
-
]
|
|
2436
|
-
},
|
|
2437
|
-
{
|
|
2438
|
-
"code": "STORAGEFILE_PURPOSE_NOT_IN_UPLOAD_SERVICE",
|
|
2439
|
-
"source": "dbx_storagefile_m_validate_app",
|
|
2440
|
-
"severity": "error",
|
|
2441
|
-
"title": "A declared `UploadedFileTypeIdentifier` constant has no",
|
|
2442
|
-
"whatItFlags": "A declared `UploadedFileTypeIdentifier` constant has no\n`StorageFileInitializeFromUploadServiceInitializer` reachable from any\n`storageFileInitializeFromUploadService(...)` call.",
|
|
2443
|
-
"whenItApplies": "Every declared file-type identifier.",
|
|
2444
|
-
"whenItDoesNotApply": "File-type identifiers that are intentionally orphaned (rare — usually a typo in a binding name; see `STORAGEFILE_UPLOAD_INITIALIZER_NAME_MISMATCH`).",
|
|
2445
|
-
"canonicalFix": "Add an initializer with `type: <CONSTANT>` and include it in the upload-service `initializer` array.",
|
|
2446
|
-
"seeAlso": [
|
|
2447
|
-
{
|
|
2448
|
-
"kind": "artifact",
|
|
2449
|
-
"target": "storagefile-upload-handler"
|
|
2450
|
-
}
|
|
2451
|
-
]
|
|
2452
|
-
},
|
|
2453
|
-
{
|
|
2454
|
-
"code": "STORAGEFILE_UPLOAD_INITIALIZER_NAME_MISMATCH",
|
|
2455
|
-
"source": "dbx_storagefile_m_validate_app",
|
|
2456
|
-
"severity": "error",
|
|
2457
|
-
"title": "A `type:` constant is declared and referenced by an initializer, but",
|
|
2458
|
-
"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.",
|
|
2459
|
-
"whenItApplies": "When an initializer literal exists but the wrapping factory's local-variable name diverges from the call-site binding.",
|
|
2460
|
-
"whenItDoesNotApply": "Initializer factories that intentionally compose multiple bindings via `...spread` (the validator handles spreads via `STORAGEFILE_UPLOAD_SERVICE_SPREAD_UNRESOLVED`).",
|
|
2461
|
-
"canonicalFix": "Rename the local variable to match the binding name used in the `initializer` array element / spread, or update the array."
|
|
2462
|
-
},
|
|
2463
|
-
{
|
|
2464
|
-
"code": "STORAGEFILE_UPLOAD_INITIALIZER_ORPHAN",
|
|
2465
|
-
"source": "dbx_storagefile_m_validate_app",
|
|
2466
|
-
"severity": "error",
|
|
2467
|
-
"title": "An upload initializer references a `type:` identifier that is not a",
|
|
2468
|
-
"whatItFlags": "An upload initializer references a `type:` identifier that is not a\ndeclared `UploadedFileTypeIdentifier` constant in the component (or a\ntrust-listed external).",
|
|
2469
|
-
"whenItApplies": "Every initializer literal seen in the API.",
|
|
2470
|
-
"whenItDoesNotApply": "When the type identifier is imported from `@dereekb/firebase`/`@dereekb/firebase-server` — those are auto-trusted.",
|
|
2471
|
-
"canonicalFix": "Either declare the missing constant in the component or remove the initializer."
|
|
2472
|
-
},
|
|
2473
|
-
{
|
|
2474
|
-
"code": "STORAGEFILE_UPLOAD_SERVICE_FACTORY_MISSING",
|
|
2475
|
-
"source": "dbx_storagefile_m_validate_app",
|
|
2476
|
-
"severity": "error",
|
|
2477
|
-
"title": "No `storageFileInitializeFromUploadService(...)` call was found in",
|
|
2478
|
-
"whatItFlags": "No `storageFileInitializeFromUploadService(...)` call was found in\nthe API.",
|
|
2479
|
-
"whenItApplies": "APIs that declare at least one `UploadedFileTypeIdentifier` and therefore need to wire the upload service.",
|
|
2480
|
-
"whenItDoesNotApply": "APIs whose upload service is provided by an upstream module (and the call lives outside the scanned subpaths — extend the scanner if so).",
|
|
2481
|
-
"canonicalFix": "Add a factory whose return value is built from `storageFileInitializeFromUploadService({ initializer: [...] })` and bind it as a NestJS provider.",
|
|
2482
|
-
"seeAlso": [
|
|
2483
|
-
{
|
|
2484
|
-
"kind": "artifact",
|
|
2485
|
-
"target": "storagefile-upload-handler"
|
|
2486
|
-
}
|
|
2487
|
-
]
|
|
2488
|
-
},
|
|
2489
|
-
{
|
|
2490
|
-
"code": "STORAGEFILE_UPLOAD_SERVICE_MULTIPLE_FACTORIES",
|
|
2491
|
-
"source": "dbx_storagefile_m_validate_app",
|
|
2492
|
-
"severity": "warning",
|
|
2493
|
-
"title": "Multiple `storageFileInitializeFromUploadService(...)` calls were",
|
|
2494
|
-
"whatItFlags": "Multiple `storageFileInitializeFromUploadService(...)` calls were\nfound.",
|
|
2495
|
-
"whenItApplies": "When more than one upload-service factory exists in the API.",
|
|
2496
|
-
"whenItDoesNotApply": "Apps that intentionally compose multiple factories (rare — only the first one runs).",
|
|
2497
|
-
"canonicalFix": "Consolidate the factories into one — only the first call's config takes effect at runtime."
|
|
2498
|
-
},
|
|
2499
|
-
{
|
|
2500
|
-
"code": "STORAGEFILE_UPLOAD_SERVICE_NOT_WIRED",
|
|
2501
|
-
"source": "dbx_storagefile_m_validate_app",
|
|
2502
|
-
"severity": "error",
|
|
2503
|
-
"title": "The upload-service factory exists but no NestJS provider binds it via",
|
|
2504
|
-
"whatItFlags": "The upload-service factory exists but no NestJS provider binds it via\n`provide: StorageFileInitializeFromUploadService, useFactory: ...`.",
|
|
2505
|
-
"whenItApplies": "When the API has at least one upload-service factory.",
|
|
2506
|
-
"whenItDoesNotApply": "When the binding lives in a module imported transitively from a trust-listed `@dereekb` package.",
|
|
2507
|
-
"canonicalFix": "Add a NestJS provider with `provide: StorageFileInitializeFromUploadService, useFactory: <factory>` to a module imported by the app."
|
|
2508
|
-
},
|
|
2509
|
-
{
|
|
2510
|
-
"code": "STORAGEFILE_UPLOAD_SERVICE_SPREAD_UNRESOLVED",
|
|
2511
|
-
"source": "dbx_storagefile_m_validate_app",
|
|
2512
|
-
"severity": "warning",
|
|
2513
|
-
"title": "A `...spread` element inside the `initializer` array does not resolve",
|
|
2514
|
-
"whatItFlags": "A `...spread` element inside the `initializer` array does not resolve\nto a declared array binding or factory call.",
|
|
2515
|
-
"whenItApplies": "When the spread identifier is local but not declared anywhere reachable.",
|
|
2516
|
-
"whenItDoesNotApply": "Spread identifiers from trust-listed `@dereekb/*` modules.",
|
|
2517
|
-
"canonicalFix": "Declare the spread as `const <name>: StorageFileInitializeFromUploadServiceInitializer[] = [...]` or import it from a trusted module."
|
|
2518
|
-
},
|
|
2519
|
-
{
|
|
2520
|
-
"code": "STORAGEFILE_FOLDER_API_DIR_NOT_FOUND",
|
|
2521
|
-
"source": "dbx_storagefile_m_validate_folder",
|
|
2522
|
-
"severity": "error",
|
|
2523
|
-
"title": "The API app directory does not exist on disk",
|
|
2524
|
-
"whatItFlags": "The API app directory does not exist on disk.",
|
|
2525
|
-
"whenItApplies": "When the supplied `apiDir` does not resolve to a directory entry.",
|
|
2526
|
-
"whenItDoesNotApply": "API apps intentionally not validated — pass `--skip storagefile_m` instead.",
|
|
2527
|
-
"canonicalFix": "Verify the path argument resolves to an existing API app root.",
|
|
2528
|
-
"seeAlso": [
|
|
2529
|
-
{
|
|
2530
|
-
"kind": "tool",
|
|
2531
|
-
"target": "dbx_storagefile_m_validate_folder"
|
|
2532
|
-
}
|
|
2533
|
-
]
|
|
2534
|
-
},
|
|
2535
|
-
{
|
|
2536
|
-
"code": "STORAGEFILE_FOLDER_API_FOLDER_MISSING",
|
|
2537
|
-
"source": "dbx_storagefile_m_validate_folder",
|
|
2538
|
-
"severity": "error",
|
|
2539
|
-
"title": "The API root exists but `src/app/common/model/storagefile/` is missing",
|
|
2540
|
-
"whatItFlags": "The API root exists but `src/app/common/model/storagefile/` is missing.",
|
|
2541
|
-
"whenItApplies": "API apps expected to wire the storagefile module but with no storagefile folder.",
|
|
2542
|
-
"whenItDoesNotApply": "API apps that intentionally don't wire storage uploads — pass `--skip storagefile_m`.",
|
|
2543
|
-
"canonicalFix": "Add `src/app/common/model/storagefile/` with `storagefile.module.ts`, `storagefile.upload.service.ts`, and `storagefile.init.ts`.",
|
|
2544
|
-
"seeAlso": [
|
|
2545
|
-
{
|
|
2546
|
-
"kind": "artifact",
|
|
2547
|
-
"target": "storagefile-purpose"
|
|
2548
|
-
}
|
|
2549
|
-
]
|
|
2550
|
-
},
|
|
2551
|
-
{
|
|
2552
|
-
"code": "STORAGEFILE_FOLDER_BARREL_REEXPORT_MISSING",
|
|
2553
|
-
"source": "dbx_storagefile_m_validate_folder",
|
|
2554
|
-
"severity": "error",
|
|
2555
|
-
"title": "`index.ts` re-exports a path that does not resolve to a sibling file or subfolder",
|
|
2556
|
-
"whatItFlags": "`index.ts` re-exports a path that does not resolve to a sibling file or subfolder.",
|
|
2557
|
-
"whenItApplies": "When `export * from './X'` in `index.ts` has no matching `./X.ts` or `./X/` under the storagefile folder root.",
|
|
2558
|
-
"whenItDoesNotApply": "Re-exports that intentionally point outside the folder (use a relative path that climbs out, not `./X`).",
|
|
2559
|
-
"canonicalFix": "Add the missing `<name>.ts` / `<name>/` sibling, or remove the dangling re-export from `index.ts`."
|
|
2560
|
-
},
|
|
2561
|
-
{
|
|
2562
|
-
"code": "STORAGEFILE_FOLDER_COMPONENT_DIR_NOT_FOUND",
|
|
2563
|
-
"source": "dbx_storagefile_m_validate_folder",
|
|
2564
|
-
"severity": "error",
|
|
2565
|
-
"title": "The component package directory does not exist on disk",
|
|
2566
|
-
"whatItFlags": "The component package directory does not exist on disk.",
|
|
2567
|
-
"whenItApplies": "When the supplied `componentDir` does not resolve to a directory entry.",
|
|
2568
|
-
"whenItDoesNotApply": "Components intentionally not part of this validation pass — pass `--skip storagefile_m` to `dbx_app_validate` instead.",
|
|
2569
|
-
"canonicalFix": "Verify the path argument resolves to an existing component package root.",
|
|
2570
|
-
"seeAlso": [
|
|
2571
|
-
{
|
|
2572
|
-
"kind": "tool",
|
|
2573
|
-
"target": "dbx_storagefile_m_validate_folder"
|
|
2574
|
-
}
|
|
2575
|
-
]
|
|
2576
|
-
},
|
|
2577
|
-
{
|
|
2578
|
-
"code": "STORAGEFILE_FOLDER_COMPONENT_FOLDER_MISSING",
|
|
2579
|
-
"source": "dbx_storagefile_m_validate_folder",
|
|
2580
|
-
"severity": "error",
|
|
2581
|
-
"title": "The component root exists but `src/lib/model/storagefile/` is missing",
|
|
2582
|
-
"whatItFlags": "The component root exists but `src/lib/model/storagefile/` is missing.",
|
|
2583
|
-
"whenItApplies": "Components that should ship `StorageFilePurpose` constants but lack the storagefile model folder.",
|
|
2584
|
-
"whenItDoesNotApply": "Components that intentionally don't extend the storagefile group (rare — most apps with file uploads do).",
|
|
2585
|
-
"canonicalFix": "Run `dbx_artifact_scaffold artifact=\"storagefile-purpose\"` to scaffold the folder, or add `src/lib/model/storagefile/storagefile.ts` by hand.",
|
|
2586
|
-
"seeAlso": [
|
|
2587
|
-
{
|
|
2588
|
-
"kind": "artifact",
|
|
2589
|
-
"target": "storagefile-purpose"
|
|
2590
|
-
}
|
|
2591
|
-
]
|
|
2592
|
-
},
|
|
2593
|
-
{
|
|
2594
|
-
"code": "STORAGEFILE_FOLDER_HANDLERS_SUBFOLDER_MIXED",
|
|
2595
|
-
"source": "dbx_storagefile_m_validate_folder",
|
|
2596
|
-
"severity": "warning",
|
|
2597
|
-
"title": "A non-canonical `.ts` file lives at the API storagefile root alongside a `handlers/` subfolder",
|
|
2598
|
-
"whatItFlags": "A non-canonical `.ts` file lives at the API storagefile root alongside a `handlers/` subfolder.",
|
|
2599
|
-
"whenItApplies": "API folders that mix root-level handler files with a sibling `handlers/` subfolder.",
|
|
2600
|
-
"whenItDoesNotApply": "Strictly canonical files (`storagefile.module.ts`, `storagefile.upload.service.ts`, `storagefile.init.ts`) — those are allowed at the root.",
|
|
2601
|
-
"canonicalFix": "Move the handler file into `handlers/` so the convention stays consistent across the project."
|
|
2602
|
-
},
|
|
2603
|
-
{
|
|
2604
|
-
"code": "STORAGEFILE_FOLDER_INIT_FILE_MISSING",
|
|
2605
|
-
"source": "dbx_storagefile_m_validate_folder",
|
|
2606
|
-
"severity": "error",
|
|
2607
|
-
"title": "The API storagefile folder is missing the required `storagefile.init.ts` file",
|
|
2608
|
-
"whatItFlags": "The API storagefile folder is missing the required `storagefile.init.ts` file.",
|
|
2609
|
-
"whenItApplies": "Every API storagefile folder that exists.",
|
|
2610
|
-
"whenItDoesNotApply": "Apps that don't expose storagefile server-actions on the action context (rare — most do).",
|
|
2611
|
-
"canonicalFix": "Add `storagefile.init.ts` with the storage-file init server-actions config wired through the action context."
|
|
2612
|
-
},
|
|
2613
|
-
{
|
|
2614
|
-
"code": "STORAGEFILE_FOLDER_MODULE_FILE_MISSING",
|
|
2615
|
-
"source": "dbx_storagefile_m_validate_folder",
|
|
2616
|
-
"severity": "error",
|
|
2617
|
-
"title": "The API storagefile folder is missing the required `storagefile.module.ts` file",
|
|
2618
|
-
"whatItFlags": "The API storagefile folder is missing the required `storagefile.module.ts` file.",
|
|
2619
|
-
"whenItApplies": "Every API storagefile folder that exists.",
|
|
2620
|
-
"whenItDoesNotApply": "The NestJS storage-file module is provided elsewhere in the app (rare — convention is one module per folder).",
|
|
2621
|
-
"canonicalFix": "Add `storagefile.module.ts` declaring the NestJS module that binds the upload service provider."
|
|
2622
|
-
},
|
|
2623
|
-
{
|
|
2624
|
-
"code": "STORAGEFILE_FOLDER_UNEXPECTED_FILE_NAME",
|
|
2625
|
-
"source": "dbx_storagefile_m_validate_folder",
|
|
2626
|
-
"severity": "warning",
|
|
2627
|
-
"title": "A `.ts` file in the storagefile folder doesn't start with the `storagefile.` prefix",
|
|
2628
|
-
"whatItFlags": "A `.ts` file in the storagefile folder doesn't start with the `storagefile.` prefix.",
|
|
2629
|
-
"whenItApplies": "Any `.ts` file other than `index.ts` whose basename doesn't start with `storagefile.`.",
|
|
2630
|
-
"whenItDoesNotApply": "Files outside the canonical layout that the project intentionally hosts here (rare — prefer moving them out).",
|
|
2631
|
-
"canonicalFix": "Rename the file to `storagefile.<sub>.ts`, or move it out of the storagefile folder."
|
|
2632
|
-
},
|
|
2633
|
-
{
|
|
2634
|
-
"code": "STORAGEFILE_FOLDER_UPLOAD_SERVICE_FILE_MISSING",
|
|
2635
|
-
"source": "dbx_storagefile_m_validate_folder",
|
|
2636
|
-
"severity": "error",
|
|
2637
|
-
"title": "The API storagefile folder is missing the required `storagefile.upload.service.ts` file",
|
|
2638
|
-
"whatItFlags": "The API storagefile folder is missing the required `storagefile.upload.service.ts` file.",
|
|
2639
|
-
"whenItApplies": "Every API storagefile folder that exists.",
|
|
2640
|
-
"whenItDoesNotApply": "API apps whose upload service is provided by an upstream module imported transitively (rare — usually a missed scaffold step).",
|
|
2641
|
-
"canonicalFix": "Add `storagefile.upload.service.ts` exporting the `storageFileInitializeFromUploadService(...)` factory function.",
|
|
2642
|
-
"seeAlso": [
|
|
2643
|
-
{
|
|
2644
|
-
"kind": "artifact",
|
|
2645
|
-
"target": "storagefile-purpose"
|
|
2646
|
-
}
|
|
2647
|
-
]
|
|
2648
|
-
},
|
|
2649
|
-
{
|
|
2650
|
-
"code": "SYSTEM_CONVERTER_MAP_NOT_LAST",
|
|
2651
|
-
"source": "dbx_system_m_validate_folder",
|
|
2652
|
-
"severity": "warning",
|
|
2653
|
-
"title": "The aggregate `<app>SystemStateStoredDataConverterMap` is not the last top-level export in `system.ts`",
|
|
2654
|
-
"whatItFlags": "The aggregate `<app>SystemStateStoredDataConverterMap` is not the last top-level export in `system.ts`.",
|
|
2655
|
-
"whenItApplies": "When the converter-map declaration appears before another top-level export in `system.ts`.",
|
|
2656
|
-
"whenItDoesNotApply": "Files where the convention isn't followed for project-specific reasons — but it makes scanning the aggregator harder.",
|
|
2657
|
-
"canonicalFix": "Move the `<app>SystemStateStoredDataConverterMap` declaration to the end of `system.ts` so it always sits below the triples it aggregates."
|
|
2658
|
-
},
|
|
2659
|
-
{
|
|
2660
|
-
"code": "SYSTEM_FOLDER_DISALLOWED_FILE",
|
|
2661
|
-
"source": "dbx_system_m_validate_folder",
|
|
2662
|
-
"severity": "error",
|
|
2663
|
-
"title": "A file disallowed at the system folder root is present (`system.id.ts` or `system.query.ts`)",
|
|
2664
|
-
"whatItFlags": "A file disallowed at the system folder root is present (`system.id.ts` or `system.query.ts`).",
|
|
2665
|
-
"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).",
|
|
2666
|
-
"whenItDoesNotApply": "No known false-positive cases — the listed files conflict with the SystemState convention.",
|
|
2667
|
-
"canonicalFix": "Delete the disallowed file. The reason is included in the violation message."
|
|
2668
|
-
},
|
|
2669
|
-
{
|
|
2670
|
-
"code": "SYSTEM_FOLDER_MISSING_INDEX",
|
|
2671
|
-
"source": "dbx_system_m_validate_folder",
|
|
2672
|
-
"severity": "error",
|
|
2673
|
-
"title": "Required `index.ts` barrel is missing from the system folder",
|
|
2674
|
-
"whatItFlags": "Required `index.ts` barrel is missing from the system folder.",
|
|
2675
|
-
"whenItApplies": "Every system folder that resolves to an existing directory.",
|
|
2676
|
-
"whenItDoesNotApply": "The base `@dereekb/firebase` system folder — covered above.",
|
|
2677
|
-
"canonicalFix": "Add `index.ts` re-exporting `system.ts` (and any optional siblings) so the folder is consumed through one barrel."
|
|
2678
|
-
},
|
|
2679
|
-
{
|
|
2680
|
-
"code": "SYSTEM_FOLDER_MISSING_MAIN",
|
|
2681
|
-
"source": "dbx_system_m_validate_folder",
|
|
2682
|
-
"severity": "error",
|
|
2683
|
-
"title": "Required `system.ts` main module is missing from the system folder",
|
|
2684
|
-
"whatItFlags": "Required `system.ts` main module is missing from the system folder.",
|
|
2685
|
-
"whenItApplies": "Every system folder that resolves to an existing directory.",
|
|
2686
|
-
"whenItDoesNotApply": "The base `@dereekb/firebase` system folder — that ships machinery (`systemStateIdentity` etc.) and should not be validated with this tool.",
|
|
2687
|
-
"canonicalFix": "Add `system.ts` declaring the downstream `<NAME>_SYSTEM_STATE_TYPE` constants, `<Foo>SystemData` interfaces, converters, and the aggregate `<app>SystemStateStoredDataConverterMap`.",
|
|
2688
|
-
"seeAlso": [
|
|
2689
|
-
{
|
|
2690
|
-
"kind": "doc",
|
|
2691
|
-
"target": "dbx__ref__system-state"
|
|
2692
|
-
}
|
|
2693
|
-
]
|
|
2694
|
-
},
|
|
2695
|
-
{
|
|
2696
|
-
"code": "SYSTEM_FOLDER_NOT_DIRECTORY",
|
|
2697
|
-
"source": "dbx_system_m_validate_folder",
|
|
2698
|
-
"severity": "error",
|
|
2699
|
-
"title": "The supplied path resolves to a file or other non-directory entry",
|
|
2700
|
-
"whatItFlags": "The supplied path resolves to a file or other non-directory entry.",
|
|
2701
|
-
"whenItApplies": "When the path exists but is not a directory.",
|
|
2702
|
-
"whenItDoesNotApply": "File-level system validation — pass the folder, not `system.ts`.",
|
|
2703
|
-
"canonicalFix": "Pass the system folder (e.g. `apps/.../src/lib/model/system/`), not the `system.ts` file inside it."
|
|
2704
|
-
},
|
|
2705
|
-
{
|
|
2706
|
-
"code": "SYSTEM_FOLDER_NOT_FOUND",
|
|
2707
|
-
"source": "dbx_system_m_validate_folder",
|
|
2708
|
-
"severity": "error",
|
|
2709
|
-
"title": "The supplied path does not exist on disk",
|
|
2710
|
-
"whatItFlags": "The supplied path does not exist on disk.",
|
|
2711
|
-
"whenItApplies": "When the folder path argument does not resolve to an entry.",
|
|
2712
|
-
"whenItDoesNotApply": "Glob patterns intentionally matching zero folders — pass at least one valid path.",
|
|
2713
|
-
"canonicalFix": "Verify the path resolves to an existing system model folder under the workspace."
|
|
2714
|
-
},
|
|
2715
|
-
{
|
|
2716
|
-
"code": "SYSTEM_FOLDER_STRAY_FILE",
|
|
2717
|
-
"source": "dbx_system_m_validate_folder",
|
|
2718
|
-
"severity": "warning",
|
|
2719
|
-
"title": "A `.ts` file in the system folder doesn't follow the `system.<sub>.ts` convention",
|
|
2720
|
-
"whatItFlags": "A `.ts` file in the system folder doesn't follow the `system.<sub>.ts` convention.",
|
|
2721
|
-
"whenItApplies": "Any `.ts` file other than `index.ts` whose basename doesn't start with `system.`.",
|
|
2722
|
-
"whenItDoesNotApply": "Files outside the canonical layout that the project intentionally hosts here (rare — prefer moving them out).",
|
|
2723
|
-
"canonicalFix": "Rename the file to `system.<sub>.ts`, or move it out of the system folder."
|
|
2724
|
-
},
|
|
2725
|
-
{
|
|
2726
|
-
"code": "SYSTEM_MISSING_CONVERTER",
|
|
2727
|
-
"source": "dbx_system_m_validate_folder",
|
|
2728
|
-
"severity": "error",
|
|
2729
|
-
"title": "A `<NAME>_SYSTEM_STATE_TYPE` / `<Foo>SystemData` pair has no matching `<foo>SystemDataConverter`",
|
|
2730
|
-
"whatItFlags": "A `<NAME>_SYSTEM_STATE_TYPE` / `<Foo>SystemData` pair has no matching `<foo>SystemDataConverter`.",
|
|
2731
|
-
"whenItApplies": "Every state-type constant whose name normalizes to a `<Foo>SystemData` interface but no `<foo>SystemDataConverter` constant exists.",
|
|
2732
|
-
"whenItDoesNotApply": "Converters provided by an upstream package and re-exported through `system.ts` (rare — usually a missed scaffold step).",
|
|
2733
|
-
"canonicalFix": "Add `export const <foo>SystemDataConverter: SystemStateStoredDataFieldConverterConfig<<Foo>SystemData> = { ... }` adjacent to the interface.",
|
|
2734
|
-
"seeAlso": [
|
|
2735
|
-
{
|
|
2736
|
-
"kind": "doc",
|
|
2737
|
-
"target": "dbx__ref__system-state"
|
|
2738
|
-
}
|
|
2739
|
-
]
|
|
2740
|
-
},
|
|
2741
|
-
{
|
|
2742
|
-
"code": "SYSTEM_MISSING_CONVERTER_MAP",
|
|
2743
|
-
"source": "dbx_system_m_validate_folder",
|
|
2744
|
-
"severity": "error",
|
|
2745
|
-
"title": "`system.ts` declares state-type triples but no aggregate `<app>SystemStateStoredDataConverterMap` is exported",
|
|
2746
|
-
"whatItFlags": "`system.ts` declares state-type triples but no aggregate `<app>SystemStateStoredDataConverterMap` is exported.",
|
|
2747
|
-
"whenItApplies": "When `system.ts` contains at least one `<NAME>_SYSTEM_STATE_TYPE` / `<Foo>SystemData` / `<foo>SystemDataConverter` triple.",
|
|
2748
|
-
"whenItDoesNotApply": "`system.ts` files that declare zero triples (an empty downstream system folder is still valid as long as `system.ts` exists).",
|
|
2749
|
-
"canonicalFix": "Add `export const <app>SystemStateStoredDataConverterMap: SystemStateStoredDataConverterMap = { ... }` mapping each `<NAME>_SYSTEM_STATE_TYPE` to its converter.",
|
|
2750
|
-
"seeAlso": [
|
|
2751
|
-
{
|
|
2752
|
-
"kind": "doc",
|
|
2753
|
-
"target": "dbx__ref__system-state"
|
|
2754
|
-
}
|
|
2755
|
-
]
|
|
2756
|
-
},
|
|
2757
|
-
{
|
|
2758
|
-
"code": "SYSTEM_MISSING_TYPE_CONSTANT",
|
|
2759
|
-
"source": "dbx_system_m_validate_folder",
|
|
2760
|
-
"severity": "error",
|
|
2761
|
-
"title": "A `<Foo>SystemData` interface has no matching `<NAME>_SYSTEM_STATE_TYPE` constant",
|
|
2762
|
-
"whatItFlags": "A `<Foo>SystemData` interface has no matching `<NAME>_SYSTEM_STATE_TYPE` constant.",
|
|
2763
|
-
"whenItApplies": "Every `<Foo>SystemData` interface declared in `system.ts`.",
|
|
2764
|
-
"whenItDoesNotApply": "Interfaces provided by an upstream package and re-exported here (rare — usually a missed scaffold step).",
|
|
2765
|
-
"canonicalFix": "Add `export const <NAME>_SYSTEM_STATE_TYPE: SystemStateType = '<value>'` adjacent to the interface."
|
|
2766
|
-
},
|
|
2767
|
-
{
|
|
2768
|
-
"code": "SYSTEM_ORPHAN_CONVERTER",
|
|
2769
|
-
"source": "dbx_system_m_validate_folder",
|
|
2770
|
-
"severity": "error",
|
|
2771
|
-
"title": "A `<foo>SystemDataConverter` exists with no matching `<Foo>SystemData` interface or `<NAME>_SYSTEM_STATE_TYPE` constant",
|
|
2772
|
-
"whatItFlags": "A `<foo>SystemDataConverter` exists with no matching `<Foo>SystemData` interface or `<NAME>_SYSTEM_STATE_TYPE` constant.",
|
|
2773
|
-
"whenItApplies": "When the converter's prefix has no sibling interface + constant.",
|
|
2774
|
-
"whenItDoesNotApply": "The converter is intentionally re-exported from another package (rare — usually a typo or rename drift).",
|
|
2775
|
-
"canonicalFix": "Either declare the matching interface + constant pair or rename the converter so it pairs with an existing triple."
|
|
2776
|
-
},
|
|
2777
|
-
{
|
|
2778
|
-
"code": "SYSTEM_ORPHAN_TYPE_CONSTANT",
|
|
2779
|
-
"source": "dbx_system_m_validate_folder",
|
|
2780
|
-
"severity": "error",
|
|
2781
|
-
"title": "A `<Foo>SystemData` interface exists but no matching `<NAME>_SYSTEM_STATE_TYPE` constant — pair is orphaned",
|
|
2782
|
-
"whatItFlags": "A `<Foo>SystemData` interface exists but no matching `<NAME>_SYSTEM_STATE_TYPE` constant — pair is orphaned.",
|
|
2783
|
-
"whenItApplies": "When `<Foo>SystemData` is declared without a same-prefix state-type constant.",
|
|
2784
|
-
"whenItDoesNotApply": "The interface is intentionally re-exported from another package (rare — usually a typo or rename drift).",
|
|
2785
|
-
"canonicalFix": "Either declare the matching `<NAME>_SYSTEM_STATE_TYPE` constant or rename the interface so it pairs with an existing constant."
|
|
2786
|
-
},
|
|
2787
|
-
{
|
|
2788
|
-
"code": "SYSTEM_TYPE_NOT_IN_MAP",
|
|
2789
|
-
"source": "dbx_system_m_validate_folder",
|
|
2790
|
-
"severity": "error",
|
|
2791
|
-
"title": "A declared `<NAME>_SYSTEM_STATE_TYPE` constant is not referenced by the aggregate converter map",
|
|
2792
|
-
"whatItFlags": "A declared `<NAME>_SYSTEM_STATE_TYPE` constant is not referenced by the aggregate converter map.",
|
|
2793
|
-
"whenItApplies": "Every state-type constant declared in `system.ts`.",
|
|
2794
|
-
"whenItDoesNotApply": "State types provided by upstream packages (the validator only reports locally declared constants).",
|
|
2795
|
-
"canonicalFix": "Add the constant as a key on `<app>SystemStateStoredDataConverterMap` so the runtime knows which converter to use."
|
|
2796
|
-
},
|
|
2797
|
-
{
|
|
2798
|
-
"code": "SYSTEM_UNKNOWN_MAP_KEY",
|
|
2799
|
-
"source": "dbx_system_m_validate_folder",
|
|
2800
|
-
"severity": "warning",
|
|
2801
|
-
"title": "The aggregate converter map references a key that is not a declared state-type constant in `system.ts`",
|
|
2802
|
-
"whatItFlags": "The aggregate converter map references a key that is not a declared state-type constant in `system.ts`.",
|
|
2803
|
-
"whenItApplies": "When a key on `<app>SystemStateStoredDataConverterMap` is neither a local `<NAME>_SYSTEM_STATE_TYPE` constant nor an imported identifier.",
|
|
2804
|
-
"whenItDoesNotApply": "Keys imported from upstream packages — those are detected via `importedIdentifiers` and skipped.",
|
|
2805
|
-
"canonicalFix": "Either declare the missing constant locally or import it from the upstream package that owns it."
|
|
2806
|
-
}
|
|
2807
|
-
]
|