Skip to content

[edit] Confirm before deleting an entry — a one-click destructive delete that skips the confirmation its own bullets have #860

Description

@s-annam

Problem

Deleting an entry from the reconstructed résumé is a one-click destructive action with no confirmation — while deleting a single bullet inside that same entry asks first. The gradient is inverted: the cheaper, more recoverable action is guarded and the more expensive one is not.

So one click destroys the entry and all N of its bullets, with no intermediate state.

Before #858 this only applied to user-added entries — trivially re-creatable, so no confirm was warranted. #858 extended entry deletion to parsed entries, and that changes the calculus: a parsed entry carries parser output, and the only recovery is resetAll (which discards every edit in the session) or re-uploading the PDF.

#856 explicitly scoped out an undo toast. It did not scope out a confirm, and the asymmetry with #626 is what stands out.

Raised as a Secondary on #858 (#858) and deferred there on the reviewer's own recommendation — the index-remap and round-trip work in that PR is already large and well-tested, and this is a separable UX change.

Scope — all four sections

The same one-click delete ships in every section that has a remove control:

Section Label Site
Achievements Remove achievement src/components/features/ReconstructedResume.tsx:1058
Projects Remove project src/components/features/ReconstructedResume.tsx:814
Experience Remove role src/components/features/ReconstructedRole.tsx:440
Education Remove education src/components/features/ReconstructedEducationSkills.tsx:166

Reuse analysis

Capability: confirm a destructive delete before it commits.

Existing surfaces found:

Decision: extend the #626 inline-confirm pattern rather than introducing a Dialog. A modal for a row-level delete is heavier than the interaction warrants and would diverge from the bullet path this issue exists to align with. No new component; the confirm state belongs beside the existing removes.pending shape.

Implementation sketch

  1. Lift the [edit] no way to delete a bullet outside the WebGPU-gated rewrite panel; cleared bullets leave a ghost row #626 pending-confirm shape so an entry row can hold it, alongside the bullet row's existing one. Keep one definition — do not copy the strip into four sections.
  2. Route all four RemoveButton sites through it: first click arms, second confirms, blur/escape disarms.
  3. The confirm copy should name the blast radius, since it is not one row: "Remove this role and its N bullets?".
  4. removeEntryWithBullets stays the single delete definition — the confirm gates the call, it does not change the two-write ordering the docblock pins.

Acceptance criteria

  • Deleting a parsed entry in each of the four sections requires a confirm step before anything is written to the edit model.
  • The confirm names the number of bullets that go with the entry.
  • Dismissing the confirm (escape, blur, or an explicit cancel) leaves the entry and every bullet untouched — no partial write.
  • The per-bullet confirm from [edit] no way to delete a bullet outside the WebGPU-gated rewrite panel; cleared bullets leave a ghost row #626 is unchanged, and entry deletion still routes bullets through removeBullet in the pinned bullets-first order (src/lib/edit/entry-remove.ts).
  • Deleting a user-added entry follows the same path — no second, unguarded branch.
  • npm run verify green.

Not in scope

Metadata

Metadata

Assignees

No one assigned

    Labels

    improvementEnhancing existing functionality

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions