|
================================================================================
|
|
Gate 3a — Dead Code
|
|
Node: W13_gate_dead_code
|
|
Ticket: #3250 (oms-bug-fixes / chips + summary)
|
|
Repo: oms-web
|
|
Branch: feat/3250-oms-ui-bug-fixes-chips-s
|
|
Result: PASS (0 items removed — no provably-dead code found in scope)
|
|
================================================================================
|
|
|
|
SCOPE — files scanned (sides.web.feature_files, 12 files)
|
|
--------------------------------------------------------------------------------
|
|
1. app/(app)/admin/items/page.tsx
|
|
2. app/(app)/admin/projects/page.tsx
|
|
3. app/(app)/admin/suppliers/page.tsx
|
|
4. app/(app)/admin/uom/page.tsx
|
|
5. app/(app)/admin/users/page.tsx
|
|
6. app/(app)/expense-summary/[project]/page.tsx
|
|
7. app/(app)/expense-summary/page.tsx
|
|
8. app/(app)/expense-summary/ExpenseSummaryRowActions.tsx
|
|
9. app/(app)/expenses/page.tsx
|
|
10. app/(app)/orders/page.tsx
|
|
11. components/forms/ExpenseForm.tsx
|
|
12. components/forms/ResetPasswordForm.tsx
|
|
|
|
METHOD
|
|
--------------------------------------------------------------------------------
|
|
* Full read of all 12 files (no sampling).
|
|
* eslint @typescript-eslint/no-unused-vars over all 12 files
|
|
(args:all, argsIgnorePattern ^_, varsIgnorePattern ^_).
|
|
* npx tsc --noEmit -p tsconfig.json (whole project).
|
|
* Cross-repo grep for every exported symbol across app/, components/,
|
|
lib/, tests/ — test files INCLUDED before considering any deletion.
|
|
* Route-reachability grep for each App Router segment in scope
|
|
(lib/nav.ts, lib/permissions/registry.ts, <Link>, router.push).
|
|
* Barrel scan: find app components lib -name "index.ts*".
|
|
* git diff main...HEAD -- prisma/ for schema fields added by this ticket.
|
|
* Comment scan for commented-out code blocks and TODO/FIXME/XXX/HACK.
|
|
|
|
--------------------------------------------------------------------------------
|
|
STEP 1 RESULTS
|
|
--------------------------------------------------------------------------------
|
|
|
|
[1] UNUSED EXPORTS ......................................................... 0
|
|
|
|
Every exported symbol in scope has at least one non-test importer:
|
|
|
|
ExpenseSummaryRowActions -> app/(app)/expense-summary/page.tsx:7,26
|
|
(+ tests/expense-summary-row-actions.test.tsx)
|
|
ResetPasswordForm -> app/(app)/profile/reset-password/page.tsx:3,13
|
|
(+ tests/reset-password-form.test.tsx,
|
|
tests/profile-reset-password-page.test.tsx)
|
|
ExpenseForm -> app/(app)/expenses/new/page.tsx:2,13
|
|
app/(app)/expenses/[id]/edit/page.tsx:5,16
|
|
(+ tests/expense-form.test.tsx,
|
|
tests/expenses-new-edit-pages.test.tsx)
|
|
generateMetadata -> Next.js App Router convention export
|
|
(app/(app)/expense-summary/[project]/page.tsx:21)
|
|
metadata / default export -> Next.js App Router convention exports
|
|
(all 8 page.tsx files in scope)
|
|
|
|
[2] UNUSED IMPORTS / UNREFERENCED LOCALS ................................... 0
|
|
|
|
eslint no-unused-vars output over all 12 files:
|
|
|
|
components/forms/ResetPasswordForm.tsx
|
|
111:5 error Definition for rule 'react-hooks/exhaustive-deps' was not
|
|
found react-hooks/exhaustive-deps
|
|
1 problem (1 error, 0 warnings)
|
|
|
|
NOT a finding. That is an artifact of the ad-hoc --no-eslintrc config used
|
|
for this scan (the react-hooks plugin was not loaded, so the file's own
|
|
inline eslint-disable comment on line 111 had no rule to resolve). Zero
|
|
no-unused-vars violations were reported. The repo's real lint config
|
|
already passed in W12 (docs/gate-evidence/W12_gate_lint-oms-bug-fixes.txt).
|
|
|
|
`npx tsc --noEmit` over the whole project: clean, no output.
|
|
|
|
[3] COMMENTED-OUT CODE BLOCKS (>3 lines) ................................... 0
|
|
|
|
Per-file count of code-shaped comment lines (^\s*//.*[;{}()=]\s*$):
|
|
all 12 files: 0
|
|
|
|
All block comments in scope are prose rationale tied to a spec reference
|
|
(ticket #3247/#3248/#3250 notes, TB-OMS-SRS-UP-001 §10.1, SCR-014), not
|
|
disabled code. Retained deliberately.
|
|
|
|
[4] DEAD BARREL ENTRIES .................................................... 0
|
|
|
|
Only one barrel exists under app/ components/ lib/:
|
|
|
|
lib/permissions/index.ts
|
|
export * from "./registry"; -> lib/permissions/registry.ts EXISTS
|
|
export * from "./evaluate"; -> lib/permissions/evaluate.ts EXISTS
|
|
export * from "./guard"; -> lib/permissions/guard.ts EXISTS
|
|
|
|
No re-export points at a deleted or renamed file, so there is no dead
|
|
barrel entry to remove. See OBSERVATIONS #2 below for a related, separate
|
|
note about this file that is deliberately NOT actioned here.
|
|
|
|
[5] ORPHANED ROUTE SEGMENTS ................................................ 0
|
|
|
|
/expense-summary
|
|
reachable: lib/nav.ts:40 sidebar entry
|
|
{ href: "/expense-summary", label: "Expense Summary",
|
|
icon: "BarChart3", permission: "expense_summary:read" }
|
|
guarded: lib/permissions/registry.ts:111
|
|
|
|
/expense-summary/[project]
|
|
reachable: app/(app)/expense-summary/ExpenseSummaryRowActions.tsx:9
|
|
<Link href={`/expense-summary/${projectId}`}>
|
|
rendered from the Actions column of the parent list
|
|
(app/(app)/expense-summary/page.tsx:26)
|
|
guarded: lib/permissions/registry.ts:111 (/^\/expense-summary(\/.*)?$/)
|
|
|
|
/admin/items, /admin/projects, /admin/suppliers, /admin/uom, /admin/users,
|
|
/expenses, /orders
|
|
all pre-existing sidebar routes in lib/nav.ts; unchanged by this ticket.
|
|
|
|
[6] UNUSED PRISMA SCHEMA FIELDS / MODELS ................................... 0
|
|
|
|
git diff main...HEAD -- prisma/ => empty.
|
|
This ticket introduces no schema change, so there is no shipped-but-unused
|
|
field to report. (Had there been one it would be reported, not deleted —
|
|
dropping a field is a migration decision, not this gate's.)
|
|
|
|
[7] TODO / FIXME / XXX / HACK MARKERS ...................................... 0
|
|
|
|
grep over all 12 files: none.
|
|
|
|
--------------------------------------------------------------------------------
|
|
STEP 2 — REMOVALS
|
|
--------------------------------------------------------------------------------
|
|
|
|
NOTHING REMOVED. No file in this checkout was modified by this gate.
|
|
|
|
Every candidate examined was traced to a live reference before being ruled out.
|
|
No symbol was deleted on the strength of "no importer found in app/ or
|
|
components/" alone — tests/ was searched too in every case, per the gate's own
|
|
rule that test-only references still count as live.
|
|
|
|
--------------------------------------------------------------------------------
|
|
OBSERVATIONS — reported, deliberately NOT auto-fixed
|
|
--------------------------------------------------------------------------------
|
|
|
|
#1 STALE TEST ASSERTION (pre-existing failure, NOT dead code)
|
|
tests/expense-summary-page.test.tsx:29
|
|
|
|
expect(screen.getByText("View Details")).toHaveAttribute(
|
|
"href", "/expense-summary/p1");
|
|
|
|
This assertion fails. Confirmed by running it:
|
|
|
|
npx vitest run tests/expense-summary-page.test.tsx \
|
|
tests/expense-summary-row-actions.test.tsx
|
|
Test Files 1 failed | 1 passed (2)
|
|
Tests 1 failed | 4 passed (5)
|
|
TestingLibraryElementError at tests/expense-summary-page.test.tsx:29:19
|
|
|
|
Cause: ticket #3250 R5 replaced the old text link with an icon-only
|
|
control. ExpenseSummaryRowActions.tsx:9 renders a <Link> whose accessible
|
|
name is aria-label="View Expense Summary" wrapping an <Eye> icon — there is
|
|
no "View Details" text node in the tree any more. The href itself is
|
|
correct; only the query for the element is stale.
|
|
|
|
NOT fixed here, for two reasons:
|
|
(a) Rewriting a test assertion is authoring test code, which is outside
|
|
this gate's whitelist (unused exports/imports, duplicate components,
|
|
orphaned routes, unused schema fields, dead barrel entries).
|
|
(b) It is genuinely ambiguous which side is wrong. If the icon-only
|
|
treatment is the intended R5 outcome, the test should be updated to
|
|
getByLabelText("View Expense Summary"). If the design actually calls
|
|
for a visible "View Details" label, the component is the regression.
|
|
Picking one silently would either mask a real UI regression or
|
|
overwrite a deliberate design decision. Escalating instead.
|
|
|
|
Owner: the test/UI gate, not this one. Flagged so it is not mistaken for a
|
|
dead-code finding and not silently carried past this node.
|
|
|
|
#2 UNIMPORTED BARREL (pre-existing, out of ticket scope)
|
|
lib/permissions/index.ts
|
|
|
|
Zero importers repo-wide — `grep -rn 'from "@/lib/permissions"'` across
|
|
app/, components/, lib/, tests/ returns nothing. Consumers import the
|
|
concrete modules (@/lib/permissions/ui, /registry, /guard, /evaluate)
|
|
directly instead.
|
|
|
|
NOT removed:
|
|
* It is not a dead barrel entry in this gate's sense — all three
|
|
re-export targets exist on disk (see [4] above).
|
|
* It is pre-existing, not introduced by this ticket. `git cat-file -e
|
|
main:lib/permissions/index.ts` succeeds; last touched by 1e617eb
|
|
"Data Layer (oms-rbac-v2)".
|
|
* It is not in sides.web.feature_files. Deleting a file outside this
|
|
ticket's scope on a shared branch is beyond what a per-ticket dead-code
|
|
gate should do unilaterally.
|
|
|
|
Recommend a separate housekeeping ticket: either delete the barrel or
|
|
adopt it consistently.
|
|
|
|
#3 DUPLICATED CONSTANT (both copies live — a DRY issue, not dead code)
|
|
EXPENSE_TYPE_OPTIONS is declared twice with identical contents:
|
|
|
|
components/forms/ExpenseForm.tsx:37 (typed OptionRow[])
|
|
app/(app)/expense-summary/[project]/page.tsx:11 (untyped)
|
|
|
|
Both are referenced by their own module and neither is exported:
|
|
ExpenseForm.tsx:127 -> <Listbox options={...}>
|
|
expense-summary/[project]/page.tsx:41,72 -> type-label lookup + filter
|
|
|
|
NOT removed: neither copy is dead, so deleting either breaks a live
|
|
reference. Collapsing them means introducing a shared module and rewiring
|
|
two importers — a refactor, not a dead-code deletion, and it crosses the
|
|
server/client component boundary (ExpenseForm.tsx is "use client", the
|
|
summary page is a server component). Flagged for follow-up; the seven
|
|
values must stay in sync with the ExpenseType enum meanwhile.
|
|
|
|
--------------------------------------------------------------------------------
|
|
SUMMARY
|
|
--------------------------------------------------------------------------------
|
|
files scanned .............. 12
|
|
unused exports ............. 0
|
|
unused imports ............. 0
|
|
commented-out blocks ....... 0
|
|
dead barrel entries ........ 0
|
|
orphaned routes ............ 0
|
|
unused schema fields ....... 0
|
|
TODO/FIXME markers ......... 0
|
|
------------------------------
|
|
items removed .............. 0
|
|
files modified ............. 0 (this gate wrote only this evidence file)
|
|
observations escalated ..... 3 (1 failing test, 1 unimported barrel,
|
|
1 duplicated constant)
|
|
|
|
GATE STATUS: PASS
|
|
|
|
PASS basis: no provably-dead code exists in the 12 files in scope, so there
|
|
was nothing to remove. Observation #1 is a real, currently-failing test —
|
|
it is a test-correctness defect, not a dead-code finding, and is recorded
|
|
here so it is visibly owned by a downstream gate rather than lost.
|
|
================================================================================
|