KNUCK-A040
KNUCK-A040: dead-fallback lint -- flag ?? on any field the Prisma schema declares non-null
Suggested
Justin Cooke
Body
## Context `apps/web/src/app/api/studio/[team]/deps/route.ts` line 60 contains: ```ts actor: edge.createdBy ?? "system", ``` After KNUCK-A007b1a promoted `TaskDependencyEdge.createdBy` from `String?` to `String` (NOT NULL), the `?? "system"` branch is unreachable dead code -- Prisma will never return a null `createdBy`. Dead fallbacks like this hide the real invariant, and if the fallback ever fires (e.g. due to a driver bug), it silently violates the actor-prefix contract by writing an unprefixed value into an audit log. ## Acceptance Criteria - New ESLint rule `operant/no-dead-fallback-on-non-null-field` - Rule parses `packages/database/prisma/schema/*.prisma` at lint time, builds a set of `Model.field -> non-null` - Flags `??`, `||`, and `!== null ? ... : ...` on any expression of form `<var>.<field>` where the model+field pair is in the non-null set - Suggested autofix: remove the fallback and the alternate branch - Escape hatch: `// eslint-disable-next-line operant/no-dead-fallback-on-non-null-field` with mandatory reason - Applies to `apps/**/*.ts`, `packages/**/*.ts` (excluding test files, per project convention) - Ship with unit tests for: flagged (non-null field with fallback), not-flagged (nullable field with fallback), autofix output ## Non-goals - Not enforcing at runtime (compile-time only) - Not handling deeply-nested field access (e.g. `x.y.z ?? d` where `z` is on a joined model) ## Effort Single Ledger ticket. Blockers: A007b1a merged (done). Related but not blocked by A039. ## Filed as follow-on to PR #278 (KNUCK-A007b1a). --- <!-- admission-rejected --> **Admission rejected (missing_feature_id):** ticket body is missing `feature_id: FEAT-...` frontmatter — declare which feature this ticket implements
Attachments
Loading attachments…
Comments
Loading comments…