Feature Owner (original implementation): Patrick Babala (Patpatty19)
Updated by / current owner: Patrick Babala
Module: Authoring — [7.3] Verification Prompt (Reusable Confirm-Destructive Modal)
Priority: P1 (audit quick win — unblocks [1.6], [3.7], [6.4], [9.5])
Status: Handoff — New (v1.0)
Date: 2026-10-01
Issue: wyzlab/WyzQuests #777 — Reusable Confirm-Destructive Modal.
PRs covered by this revision: #780 — feat/reusable-confirm-destructive-modal (primary; merged 2026-08-20). Related/integrated work: #772 (learner-group destructive flows adopted the component).
Audit: docs/FEATURE_AUDIT_MAY2026.md Module 7, item 7.3 — “Build a reusable <ConfirmDestructiveModal> component to standardise. Quick win.”
QA cases: QA-024 (permanent delete), QA-045 / QA-046 (secure asset delete), QA-073.5 (secure user delete), QA-081 (verification prompt shows).
Companion doc: Internal Technical Guide — docs/INTERNAL_TECHNICAL_GUIDE_reusable-confirm-destructive-modal.md (architecture, DB schema, API specs, helpers, ops, troubleshooting). This Hand-Off stays product-facing; where engineering depth is needed it cross-references the ITG instead of duplicating it.
EXECUTIVE SUMMARY
What is this feature?
The Reusable Confirm-Destructive Modal is a single shared <ConfirmDestructiveModal> component that standardises every destructive confirmation in WyzQuests behind a typed-token challenge: the destructive button stays disabled until the user types the exact token (DELETE, RESET, or an entity title). It replaces ten one-off confirmation dialogs and adds server-side re-validation of the typed token on the four highest-risk endpoints (permanent delete, asset purge, learner reset, admin user delete).
Why does it matter?
Before this feature, destructive confirmations were inconsistent — some flows used a bespoke type-to-confirm input with a different token, some used a soft “Are you sure?”, and several ran with no confirmation at all (gamification badge/trigger deletes, notification deletes, activity deletes). The May 2026 audit flagged this as “Inconsistent” (item 7.3) and called the shared component the single highest-leverage item to land. It protects irreversible actions (deleting content, purging assets, resetting learner progress, deleting accounts) and gives those actions a consistent, hard-to-misclick confirmation.
MVP scope (current implementation):
One controlled component with a typed-token gate, busy state, brand styling, and an optional content slot.
Exact-token enforcement client-side; the confirm button is disabled until the token matches.
Server-side token double-check on the four named endpoints.
Adoption across creator hub, content library, quest editor, learner, forum, reviewer, admin, and agency.
Removal of ten ad-hoc confirmation modals.
Shipped scope (v1.0):
Component —
components/shared/confirm-destructive-modal.tsx(title, description,confirmToken,confirmLabel,onConfirm,isSubmitting,matchMode,extraContent,cancelLabel,submittingLabel).Server checks —
permanent-delete(DELETE),purge-assets(Zod literalDELETE),reset-quest(Zod literalRESET),delete-user(Zod literalDELETE+ re-auth).Helper —
components/learner/resetQuest.ts(resetQuestProgress) owns the reset request, token, toasts, and returns a success boolean.Schema —
purgeAssetsSchemainshared/schemas/contentManagementSchema.ts.Cleanup — ten ad-hoc modals removed:
DeleteConfirmationModal,BulkDeleteModal,PurgeAssetModal,ResetQuestDialog,DeleteUserModal,FolderDeleteConfirmationModal,DeleteAllDialog,DeleteFolderDialog,DeletePostDialog,DeleteCommentDialog.
Still deferred: server-side token validation for the 13+ non-named destructive flows; unit/component tests for the shared modal and schemas; correcting the stale Playwright selectors (#confirm-delete, #confirm-purge-asset); a configurable input id.
1. USER PAIN POINT & SOLUTION
Current State (Without Feature)
Every destructive action had its own dialog, or none. Tokens differed (DELETE vs. the entity title vs. nothing), copy varied, and the highest-risk flows (admin delete, asset purge) used one-off inputs that were deleted or diverged over time. Users could trigger an irreversible delete from a single click in several surfaces.
Pain Point
Emotional: Users are uneasy about irreversible actions and cannot tell whether a confirmation is “real” (typed) or just a click-through.
Functional: Inconsistent confirmation UX; some destructive paths had no confirmation guard.
Business Impact: Higher risk of accidental data loss, slower QA (each flow tested differently), and duplicated maintenance across ten dialogs.
Future State (With Feature)
Every destructive action presents the same modal: a warning icon, a plain-language description of what will be destroyed, and a required typed token. The button cannot be pressed until the token matches, and the four highest-risk endpoints re-check the token server-side. One component to maintain, one interaction to learn.
Marketing Hook
“Type it to delete it — every destructive action, one consistent, server-verified guard.”
2. CODEBASE ASSESSMENT
Current Implementation Status
The feature is a single shared client component plus server-side token checks on four endpoints and adoption across the creator, content-library, quest-editor, learner, forum, reviewer, admin, and agency surfaces. Ten ad-hoc confirmation modals were deleted. All four named endpoints enforce their token server-side; the remaining flows are client-gated only (documented gap).
Primary Files
components/shared/confirm-destructive-modal.tsx— the shared component (token gate, busy state,extraContentslot).components/learner/resetQuest.ts— shared reset helper (confirm_text: "RESET", returns boolean).shared/schemas/contentManagementSchema.ts—permanentDeleteSchema,purgeAssetsSchema(confirm_text: z.literal("DELETE")).app/api/creator/(content)/permanent-delete/route.ts— exactDELETEenforcement for single + bulk;PERMANENT_DELETE_FAILEDaudit.app/api/creator/(background-assets)/purge-assets/route.ts— Zod-literal token +ApiResponseHelperenvelope.app/api/learner/reset-quest/route.ts— Zod-literalRESET.app/api/admin/delete-user/route.ts— Zod-literalDELETE+ re-auth token.app/admin/manage-users/page.tsx,app/admin/agencies/page.tsx,app/agency/team/page.tsx— admin/agency destructive flows (typed confirm → ReAuth for delete).components/creator/{MyContent,TrashContent,ContentListRow}.tsx,app/creator/archive/page.tsx— single + bulk permanent delete.components/creator/background-assets/AssetList.tsx— purge (single + bulk).components/content-library/{ContentCard,FolderCard,FolderTreeView,FolderPermissionsModal,ContentLibraryPage,FolderWrapper}.tsx— folder/content delete + permission removal.components/creator/groups/DeleteGroupDialog.tsx,GroupMembersTable.tsx,components/creator/enrollment/GroupEnrollmentTable.tsx,app/creator/learner-groups/[id]/page.tsx— learner-group destructive flows.app/quest-editor/**(canvas linear/exploration, form-editor, enrollment,SettingsDropdown,ArchivedNodesModal) — editor deletes.components/forum/{PostDetail,CommentSection}.tsx,components/reviewer/{GuestInviteModal,comments/CommentThread}.tsx,components/notification/Notifications.tsx,components/admin/gamification/{BadgeList,TriggerList,AgencyBadgeRequirements}.tsx.Migrations:
supabase/migrations/20260414_create_audit_logs_table.sql,20260526_create_admin_reauth_tokens.sql,20260612_update_rls_policies_multi_role.sql,20260824_fix_not_null_set_null_user_fks.sql,20260504_create_quest_folder.sql.
Current Behavior Summary
The modal is fully controlled by its parent (
open/onOpenChange); the parent owns the request and theisSubmittingstate.The token input resets on every open; Enter submits only when valid; both buttons disable and a spinner shows while submitting.
matchModedefaults to"exact"; canvas “Delete All” uses"case-insensitive"with the quest title as the token.An empty token can never be confirmed (guards untitled drafts).
The four named endpoints re-validate the token before any destructive side effect; mismatch is rejected with a 400 (and, for permanent delete, an audit row).
Successful deletes write to
audit_logsin the admin and permanent-delete paths.
Strengths Already Present
Single component for all destructive confirmations; ten ad-hoc dialogs removed.
Exact-token gate plus a non-empty-token guard; mismatch hint and
aria-invalidfeedback.Parent-owned busy state keeps the modal open until the request resolves (adopted in
GroupMembersTable, learner-group unassign,FolderPermissionsModal,Notifications).Server-side token re-validation on the four highest-risk endpoints (AC3).
Reset flow gates destructive client state (progress clear, reload, dialog close) on the server result, so a failed reset is never shown as success.
extraContentslot preserves per-flow needs (bulk item lists, member-reassignment select) without branching the component.Folder-delete copy matches the actual server behaviour (items move to the library root via
ON DELETE SET NULL; only the folder structure is deleted).
Gaps / Hardening Opportunities
Server-side token enforcement exists only on the four named endpoints; ~13 other destructive flows are client-gated only (scoped follow-up).
No unit or component tests for the shared modal or the token schemas.
The Playwright specs for permanent delete and asset purge still target the removed modals’ ids (
#confirm-delete,#confirm-purge-asset); the component uses#confirm-destructive.The token input id (
confirm-destructive) is hardcoded and not configurable, so multiple mounted modals produce duplicate DOM ids.permanentDeleteSchema.confirm_textisz.string().min(1)(not a Zod literal); the exact-match rule is an imperative guard in the route. Its docstring still mentions a title-match branch that no longer exists.No DB transaction around delete + storage cleanup, and no rate limiting or re-auth on permanent delete / purge / reset.
3. 4D FRAMEWORK MAPPING
Diagnose
Destructive actions had inconsistent or missing confirmations, differing tokens, and duplicated one-off dialogs — a data-loss and maintainability risk.
Design
Standardise on one controlled component that requires a typed token, keeps the parent in charge of the request, and re-validates the token server-side on the highest-risk endpoints.
Develop
Build ConfirmDestructiveModal, migrate every destructive flow to it with per-flow content via a slot, delete the ad-hoc dialogs, and add Zod/guard token checks to permanent-delete, purge-assets, reset-quest, and delete-user.
Deliver
Every destructive action looks and behaves the same, cannot be triggered without typing the token, and the four riskiest operations are verified again on the server.
4. USER FLOWS
Entry Point
The user triggers any destructive action from an existing surface (e.g. a delete icon in My Content / Trash, a Purge button in the asset trash, Reset Progress in the learner dashboard, or Delete in Admin → Manage Users). The parent opens <ConfirmDestructiveModal>.
Success Criteria
The modal shows a clear title, a plain-language description of the destruction, and the required token.
The destructive button is disabled until the token matches exactly (or case-insensitively for title tokens).
The request runs once, with the modal showing a busy spinner until it resolves.
On success the modal closes and a confirmation toast is shown; on failure the modal stays open (or reverts the optimistic UI) so the user can retry.
The four named endpoints reject a missing/incorrect token server-side.
Main Flow (Happy Path)
User clicks the destructive action; the parent opens the modal.
The modal shows the warning icon, title, description, and “Type
<TOKEN>to confirm”.The user types the token; once it matches, the destructive button enables.
The user presses the button (or Enter); the parent sends the request with the token attached and sets
isSubmitting.The endpoint re-validates the token, performs the destructive operation, and returns success.
The parent shows a success toast and closes the modal; the list refreshes.
Edge Cases
Wrong token: input shows a red border and “Text does not match. Type exactly
<TOKEN>.”; button stays disabled.Empty token (untitled draft): an empty
confirmTokencan never be confirmed, even with empty input.Case-insensitive title token: canvas “Delete All” matches the quest title trimmed/lowercased.
Submitting: both buttons disable, the dialog cannot be closed, and Enter is a no-op until the request resolves.
Server token mismatch (permanent delete):
400 'Please type "DELETE" to confirm permanent deletion'and aPERMANENT_DELETE_FAILEDaudit row.Admin delete: typed
DELETEthen a separate Re-Auth challenge; a wrong password blocks the delete.Reset failure: the dialog stays open with an error toast; progress is not cleared client-side.
Folder delete: empty folders delete instantly; typed confirm only when the folder has content or sub-folders, and the copy says items move to the library root rather than being deleted.
Bulk delete: the modal lists the selected items; the response reports any
missingIds(already deleted concurrently).
Decision Points
IF the caller is a creator/agency context → permanent delete and purge are allowed subject to ownership/folder-admin checks.
IF the caller is an ADMIN → delete-user requires the typed
DELETEand a valid re-auth token.IF the caller is a learner → reset-quest requires
RESETand an existing enrollment.IF
matchModeiscase-insensitive→ the title token is compared trimmed and lowercased.IF the token is empty → the destructive button is never enabled.
5. INFORMATION ARCHITECTURE
Primary Information (Always visible)
Modal title (per-flow, e.g. “Delete User Account”, “Permanently Delete File”, “Are you absolutely sure?”).
Warning icon and destructive description.
“Type
<TOKEN>to confirm” label.Token input.
Cancel and destructive confirm buttons.
Secondary Information
Optional
extraContentabove the input: bulk item list, folder-delete scope, or member-reassignment select.Busy spinner and submitting label (“Deleting…”, “Purging…”, “Resetting…”, “Removing…”) while the request runs.
Mismatch hint under the input when the token is wrong.
Tertiary Information (Hidden until needed)
The exact token per flow (
DELETE,RESET, or the entity title).The endpoint and payload (owned by the parent, not the modal).
Actions
Primary CTA: the destructive confirm button (disabled until the token matches).
Secondary Actions: Cancel (and, where implemented, keeping the modal open on failure).
6. WIREFRAMES
The feature is a single centered modal dialog, reused on every destructive path. The title and description change per flow; the token and labels change per flow.
Key Screens:
Confirm Destructive modal (warning icon circle, title, description, optional content slot, token label + input, Cancel / destructive confirm).
Busy state (spinner in the confirm button; both buttons disabled; dialog not closable).
Mismatch state (red input border + “Text does not match. Type exactly
<TOKEN>.”).
Annotations:
The confirm button uses the destructive variant; the title uses the brand heading style.
The token input resets every time the modal opens.
The optional content slot carries bulk item lists (permanent delete / purge) and the group member-reassignment select (delete group).
For admin delete-user, the modal chains before the existing Re-Auth modal, not in place of it.
The architecture/system diagram lives with the companion ITG (
docs/INTERNAL_TECHNICAL_GUIDE_reusable-confirm-destructive-modal.md), not here.
7. WIREFLOWS
User triggers a destructive action → modal opens with the token challenge → user types the token → button enables → user confirms → parent sends the request with the token → server re-validates (on the four named endpoints) → success toast + modal closes + list refreshes, or failure keeps the modal open with an error so the user can retry. For admin delete-user the chain is typed DELETE → Re-Auth → delete.
8. PROTOTYPE
Figma Prototype Link: Not currently available for this feature.
How to test:
Open My Content → Trash, delete an item, and confirm the modal requires typing
DELETEbefore the button enables.Type a wrong token and confirm the mismatch hint appears and the button stays disabled.
Purge a trashed background asset and confirm
DELETEis required and the server rejects a wrong token.As a learner, open Reset Progress on a quest, confirm
RESETis required, and verify a failed reset leaves the dialog open.As an admin, delete a user: type
DELETE, then complete the Re-Auth challenge and confirm the delete is audited.Open a canvas with nodes, use “Delete All”, and confirm the token is the quest title (case-insensitive). Empty drafts must never be confirmable.
9. DATA MODEL
The feature adds no tables or columns; it reuses existing stores.
Core Tables
audit_logs— sensitive-action trail written by the feature:PERMANENT_DELETE_FAILED(permanent-delete token mismatch),USER_DELETE,REAUTH_TOKEN_INVALID(admin delete). Columns:id,user_id(FK →app_users.id,ON DELETE SET NULL),action,entity_type,entity_id,details(JSONB),ip_address,user_agent,created_at.admin_reauth_tokens— short-lived single-use re-auth tokens consumed before an admin user delete.quest_enrollments— reset writesprogressback to{ percentage: 0, visited_cards: [], last_visited_at: null }; milestone XP is intentionally not re-armed.quest_folders/quests.quest_folder_id—ON DELETE SET NULL, which is why folder deletion moves content to the root rather than deleting it.
Key Constraint / Note
audit_logs.user_idis nullable after20260824_fix_not_null_set_null_user_fks.sql; before that migration the cascadeON DELETE SET NULLon user delete fails with23502.
Full column types, indexes, RLS policies, and migration supersession are in the ITG §3 (Data Model / Schema).
10. API CONTRACTS
All four endpoints use the standard ApiResponseHelper envelope: success { success: true, message?, data, error: null }, error { success: false, message, data: null, error: { code, message, details? } }.
Permanent Delete
Endpoint:
DELETE /api/creator/permanent-deleteAuth: creator context (CREATOR / AGENCY / ADMIN) + per-item ownership or folder-admin check.
Body:
{ content_type: "quests" | "adventures", content_id | content_ids, confirm_text: "DELETE" }.Behavior: validates the payload, verifies ownership, enforces
confirm_text === "DELETE"(mismatch →400+PERMANENT_DELETE_FAILEDaudit), deletes the rows, then cleans up storage/asset_metadata.Response:
{ deletedIds, missingIds }.
Purge Assets
Endpoint:
DELETE /api/creator/purge-assetsAuth: creator context + per-asset ownership check.
Body:
{ asset_id | asset_ids, confirm_text: "DELETE" }(purgeAssetsSchema,z.literal("DELETE")).Behavior: validates the token, deletes DB rows first, then removes storage files for the rows that were deleted.
Response:
{ deletedIds, missingIds }.
Reset Quest Progress
Endpoint:
POST /api/learner/reset-questAuth: any authenticated user, plus an existing
quest_enrollmentsrow for the learner.Body:
{ quest_id, confirm_text: "RESET" }(z.literal("RESET")).Behavior: resets
progress; milestone XP is not re-armed.Response:
{ progress }.
Delete User
Endpoint:
DELETE /api/admin/delete-userAuth: ADMIN + valid
reauthToken+ typedconfirm_text: "DELETE".Body:
{ userId, reauthToken, confirm_text: "DELETE" }.Behavior: consumes the re-auth token, refuses ADMIN targets, deletes the Supabase Auth identity, cleans up agency memberships, deletes the profile row, and audits
USER_DELETE.Response:
200 "User <email> has been permanently deleted".
Auth checks, exact error strings, and full request/response shapes are in the ITG §3 (API Specification).
11. DATA REQUIREMENTS
Frontend Needs
The destructive flow’s title, description, token, and confirm label (parent-supplied).
The parent-owned
isSubmittingflag.Optional
extraContentdata (bulk item names, folder scope, member-reassignment options).The modal
openstate and a close callback.
Backend Needs
Zod-validated request bodies with the
confirm_texttoken (the four named endpoints).Ownership / role authorization per endpoint.
audit_logsfor the permanent-delete mismatch and admin-delete trail.Supabase Storage (
public-assets) cleanup for permanent delete and purge.Re-auth token issue/consume for admin user delete.
12. SECURITY & AUTHORIZATION
Who can access this feature?
Creator (agency or standalone): ✔ permanent delete, purge, folders/content, editor, activities (subject to ownership).
Agency OWNER/ADMIN: ✔ agency member removal, agency delete (typed confirm → Re-Auth), and creator flows.
Admin: ✔ user delete (typed
DELETE+ Re-Auth), gamification deletes, notifications, forum/reviewer moderation.Reviewer: ✔ forum/reviewer comment and invite revoke flows.
Learner: ✔ Reset Progress on their own enrollment (
RESET).
Authorization Logic
The modal itself performs no authorization — it only gates the click. The parent and the endpoint enforce access.
The four named endpoints re-validate the typed token server-side (AC3): permanent-delete (exact
DELETE), purge-assets (z.literal("DELETE")), reset-quest (z.literal("RESET")), delete-user (z.literal("DELETE")+ re-auth).Admin user delete requires a single-use, time-bounded (≤5 min) re-authentication token in addition to the typed token.
Ownership/folder-admin checks and role checks are unchanged by this feature.
Authentication is Supabase Auth; the legacy-named
app_users.clerk_idcolumn stores the Supabase auth UUID.
Note: server-side token enforcement covers only the four named endpoints; the remaining ~13 destructive flows are client-gated only (see Open Questions).
13. ERROR HANDLING
Common Errors
Client mismatch (
"Text does not match. Type exactly \"DELETE\"."/"...\"RESET\"."/ the title).Permanent delete token rejected (
'Please type "DELETE" to confirm permanent deletion').Invalid permanent delete payload (
"Invalid permanent delete request payload").Invalid purge payload (
"Invalid permanent purge request payload").No IDs provided (
"No content IDs provided"/"No asset IDs provided").Not permitted (
"You do not have permission to delete this content").Content/asset not found (
"Content not found or access denied"/"Assets not found").Already deleted (
"Content not found. It may have been already deleted.").Reset errors (
"Enrollment not found"/"Failed to reset quest progress").Admin delete errors (
"Invalid input","Re-authentication token is invalid or expired. Please re-authenticate.","Cannot delete admin users","Failed to delete user").
Handling Guidance
Keep the modal open on failure so the user can retry (parent owns this).
For a server token mismatch, re-check the token wired at the call site; do not bypass the client gate.
For an expired/used re-auth token, re-run the Re-Auth modal; tokens are single-use and last ≤5 minutes.
Treat storage-cleanup warnings as non-fatal (the DB row is already deleted) but flag orphaned files operationally.
Surface exact messages to the user; do not silently swallow delete or reset failures.
14. TESTING CHECKLIST
Happy Path
Destructive button stays disabled until the token is typed exactly.
Typing the token enables the button; confirming runs the request once with a spinner.
Success closes the modal and shows a toast.
Permanent delete and purge accept
DELETE; learner reset acceptsRESET; canvas “Delete All” accepts the quest title (case-insensitive).Admin delete-user requires
DELETEand then a successful Re-Auth.
Edge Cases
Wrong token → mismatch hint, button disabled.
Empty input with an empty token → button never enables.
isSubmitting→ both buttons disabled, dialog not closable, Enter no-op.Server rejects a wrong permanent-delete token →
400+PERMANENT_DELETE_FAILED.Reset failure → dialog stays open, progress not cleared client-side.
Admin Re-Auth failure → delete blocked.
Folder delete → empty folders delete instantly; non-empty folders warn that items move to the root.
Bulk delete → item list shown;
missingIdsreported.Multiple modals mounted on one page → currently share the input id (known limitation).
Coverage Notes
E2E:
tests/e2e/creator/permanent-delete.spec.ts,tests/e2e/creator/secure-asset-delete.spec.ts,tests/e2e/creator/archive-restore-delete.spec.ts,tests/e2e/admin/secure-user-delete.spec.ts.No unit/component tests exist for the shared modal or the token schemas.
The permanent-delete and asset-purge specs still reference the removed modals’ input ids and need their selectors updated.
15. OPEN QUESTIONS
For Product
Should the remaining ~13 destructive flows get server-side token enforcement like the four named endpoints? — Still open. Today they are client-gated only.
Should permanent delete and purge require re-authentication (like admin user delete)? — Still open. Only admin delete-user has re-auth.
Should the shared modal be exposed as a documented pattern for future destructive features? — Still open. Currently it is code-standard only.
For Engineering
Should the shared modal get unit/component tests (token gate,
matchMode, empty-token guard,isSubmitting)? — Still open.Should the stale Playwright selectors (
#confirm-delete,#confirm-purge-asset) be updated to the component’s#confirm-destructive? — Still open.Should the token input id be configurable to avoid duplicate DOM ids when multiple modals mount? — Still open.
Should
permanentDeleteSchema.confirm_textbecomez.literal("DELETE")for parity with the other endpoints, and its stale docstring corrected? — Still open.
16. OUT OF SCOPE (v1.1+)
Server-side token validation for the non-named destructive flows — out of scope (follow-up issue).
Replacing W0.5 re-authentication for admin actions — out of scope (unchanged; the modal chains before it).
Converting soft delete / archive / restore dialogs to the destructive modal — out of scope (those are non-destructive).
A design-system variant gallery of the modal — out of scope.
Making the modal fetch or own request lifecycle — out of scope (parent-owned by design).
17. SUCCESS METRICS
Destructive-flow confirmation coverage (share of destructive actions gated by the shared modal).
Accidental-destruction reports (target: zero from a stray click).
Server token-rejection rate on the four named endpoints (should be near zero in normal use).
Reduction in duplicate confirmation dialogs (10 removed).
QA time for destructive flows (one consistent interaction to test).
18. DEPENDENCIES
This feature depends on
Shadcn/UI
Dialog,Button,Input,Labelandlucide-reacticons.Zod v4 for the server-side token schemas.
ApiResponseHelper(W1.4 response envelope).Supabase Postgres (content, assets, enrollments), Supabase Auth (admin delete), and Supabase Storage (
public-assets).The W0.5 re-authentication service (
admin_reauth_tokens) for admin user delete.audit_logsfor the permanent-delete mismatch and admin-delete trail.
These features depend on this
Content Management
[1.6]permanent delete (single + bulk).Background Asset Library
[3.7]secure purge.Manage Users
[6.4]permanent user delete.Learner quest
[9.5]Reset Progress.Learner groups
[11.5], content library folders, quest editor, forum, reviewer, notifications, and gamification destructive flows.
19. TIMELINE & OWNERSHIP
Original owner / Hand-Off author: Patrick Babala (Patpatty19).
Implementation updates & current owner: Patrick Babala.
Reviewers: Christian Denzon (@cdnzn) — Round 1; clydetims (@clydetims) — Round 2 (PR #780).
QA: Manual end-to-end verification across the migrated flows; e2e specs QA-024, QA-045/QA-046, QA-073.5, QA-081.
Shipped: PR #780 merged 2026-08-20 (
13373adbcore,1210c258learner groups + content library,07530207round-1 fixes); integrated viab65e7991on 2026-08-21.Estimated Completion: core complete; remaining items are the Open Questions and Out of Scope sections above.
REFERENCES
Issue: wyzlab/WyzQuests #777 — Reusable Confirm-Destructive Modal.
Primary PR: #780 —
feat/reusable-confirm-destructive-modal(merged 2026-08-20).Related PR: #772 — learner-group destructive flows.
Audit:
docs/FEATURE_AUDIT_MAY2026.mdModule 7, item 7.3 (and D1/§5 priority notes).Migrations:
supabase/migrations/20260414_create_audit_logs_table.sql,20260526_create_admin_reauth_tokens.sql,20260612_update_rls_policies_multi_role.sql,20260824_fix_not_null_set_null_user_fks.sql,20260504_create_quest_folder.sql.QA:
tests/e2e/creator/permanent-delete.spec.ts(QA-024),tests/e2e/creator/secure-asset-delete.spec.ts(QA-045/QA-046),tests/e2e/admin/secure-user-delete.spec.ts(QA-073.5),tests/e2e/creator/archive-restore-delete.spec.ts.Companion ITG:
docs/INTERNAL_TECHNICAL_GUIDE_reusable-confirm-destructive-modal.md.
VERSION HISTORY
1.0 — 2026-10-01 — Patrick Babala. Initial Hand-Off for the Reusable Confirm-Destructive Modal (
[7.3], PR #780). Covers the shared component, typed-token gate, server-side token checks, migrated destructive flows, removed ad-hoc modals, API contracts, security/authorization, testing checklist, and known limitations.