Problem
PATCH and DELETE in app/api/jobs/route.ts (lines 74, 106) use findIndex to locate a job by company + role. If two jobs in the same section share the same company and role, only the first one is ever reachable — the second cannot be edited, moved, or deleted.
There is also no guard on the write path (POST) to prevent duplicate company+role pairs from being inserted in the first place.
Reproduction
- Add two jobs with identical company and role to the same section (e.g. via direct edit of
jobs.json or a scrape that returns the same listing twice)
- Try to delete or move the second one — the first is always affected instead
Root cause
findIndex((j) => j.company === company && j.role === role) returns the first match. The composite key company::role (now via jobKey()) is not guaranteed unique within a section.
Options considered
- UUID per job — generate a stable
id on insert, use it for all mutations. Blocks duplicate identity entirely. Requires schema change and migration.
- Block duplicates on insert — reject
POST if jobKey(company, role) already exists in that section. Keeps findIndex safe but permanently prevents tracking two roles with identical titles at the same company.
- Index-based mutations — pass array index from client for delete/move. No schema change, but fragile under concurrent edits.
Proposed fix
Add to the slice backlog as a sequenced slice after the IJobRepository interface (Slice 5), since the right fix (UUID) touches the repository contract and all mutation paths.
Affected files
app/api/jobs/route.ts — PATCH (line 74), DELETE (line 106)
lib/jobs.ts — job types (no id field currently)
app/page.tsx — all jobKey() call sites used as React keys and mutation identifiers
Problem
PATCHandDELETEinapp/api/jobs/route.ts(lines 74, 106) usefindIndexto locate a job bycompany + role. If two jobs in the same section share the same company and role, only the first one is ever reachable — the second cannot be edited, moved, or deleted.There is also no guard on the write path (
POST) to prevent duplicatecompany+rolepairs from being inserted in the first place.Reproduction
jobs.jsonor a scrape that returns the same listing twice)Root cause
findIndex((j) => j.company === company && j.role === role)returns the first match. The composite keycompany::role(now viajobKey()) is not guaranteed unique within a section.Options considered
idon insert, use it for all mutations. Blocks duplicate identity entirely. Requires schema change and migration.POSTifjobKey(company, role)already exists in that section. KeepsfindIndexsafe but permanently prevents tracking two roles with identical titles at the same company.Proposed fix
Add to the slice backlog as a sequenced slice after the
IJobRepositoryinterface (Slice 5), since the right fix (UUID) touches the repository contract and all mutation paths.Affected files
app/api/jobs/route.ts— PATCH (line 74), DELETE (line 106)lib/jobs.ts— job types (noidfield currently)app/page.tsx— alljobKey()call sites used as React keys and mutation identifiers