Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

21 KiB

Scratchpad — Deletion UX Improvement

  • Plan slug: deletion-ux-improvement
  • Created: 2026-02-12
  • Source plan: .ai/deletion_improvement_plan.md (v2, schema-verified)

What This Is

Keep a lightweight, continuously-updated log of discoveries and decisions made while implementing this plan.

Decisions

  • (2026-02-12) Plain functions over class: DeletionValidationService class replaced with plain exported functions in deletionValidation.ts. Codebase uses functional patterns everywhere (server actions, model methods, utilities). No instance state in the service = no reason for a class.
  • (2026-02-12) Atomic validate-and-delete: deleteEntityWithValidation runs validation + tag cleanup + deletion in a single withTransaction call. Prevents TOCTOU race condition present in current deleteClient (separate transactions for validation and deletion).
  • (2026-02-12) Separate read-only precheck: preCheckDeletion kept as a separate action for the dialog preview step (when dialog opens). This is read-only and lightweight.
  • (2026-02-12) DeleteEntityDialog as new component: Created as a new component in @alga-psa/ui, NOT a modification of existing ConfirmationDialog. The deletion UX (dependency lists, alternatives, loading states) is complex enough to warrant its own component. ConfirmationDialog stays general-purpose.
  • (2026-02-12) Alternative action dispatch by action type string: onAlternativeAction('deactivate') instead of magic handler name strings like markClientInactive. The component consumer maps action types to their own handlers.
  • (2026-02-12) Automatic tag cleanup via config: tagEntityType field in EntityDeletionConfig triggers automatic deleteEntityTags call in deleteEntityWithValidation. Eliminates manual tag cleanup calls scattered across packages.
  • (2026-02-12) Package is @alga-psa/ui, not @alga-psa/ui-kit: Verified that ConfirmationDialog, Dialog, Button etc. are all in @alga-psa/ui. The @alga-psa/ui-kit package exists separately but is not the target.

Discoveries / Constraints

  • (2026-02-12) Schema corrections from v1 plan — multiple foreign key names were wrong:
    • company_idclient_id everywhere (contacts, tickets, projects, invoices, assets, interactions)
    • user_team_members → actual table is team_members
    • company_billing_plans → does not exist; contracts use contract_lines + client_contracts
    • company_tax_settings.tax_rate_id → column doesn't exist; use client_tax_rates.tax_rate_id
    • schedule_entries.user_id → doesn't exist; users are assigned via schedule_entry_assignees (M2M join table)
    • invoices.tax_rate_id → doesn't exist; tax rates link via client_tax_rates
  • (2026-02-12) Client deletion checks is_default: The default company cannot be deleted. This is an entity-specific precondition that runs before the generic validation. Other entities may have similar preconditions.
  • (2026-02-12) Tag cleanup currently integrated in 4 places: tickets, clients, contacts, project tasks. Missing from: projects (parent entity), assets, documents, and others.
  • (2026-02-12) Cascade tag cleanup for projects: When deleting a project, child tasks need bulk tag cleanup via deleteEntitiesTags(trx, taskIds, 'project_task').
  • (2026-02-12) ConfirmationDialog has 3-button support: Uses thirdButtonLabel + onCancel for three-way choices. Used by TagManager, TaskForm, ClientDetails, BoardsSettings. This is general-purpose, NOT deletion-specific.
  • (2026-02-12) ConfirmationDialog has radio options: options prop renders radio buttons, used for recurring event scope selection. Also NOT deletion-specific.
  • (2026-02-12) Status entity has dynamic deps: Status dependencies depend on status_type (ticket statuses check tickets.status_id, interaction statuses check interactions.status_id). Needs special handling in the action, not in static config.
  • (2026-02-12) Permission helper variants: Some packages use hasPermission directly, others use hasPermissionAsync() wrapper to avoid circular dependencies. Watch for this during migration.
  • (2026-02-12) notes_document_id cleanup: Several entities (clients, contacts) have a notes_document_id that needs cleanup during deletion. This is entity-specific logic in performDelete, not part of the generic system.

Commands / Runbooks

  • (2026-02-12) Verify schema: docker exec -e PGPASSWORD="$(cat secrets/db_password_server)" bigmac_postgres psql -h localhost -p 5432 -U app_user -d server -c "SELECT column_name FROM information_schema.columns WHERE table_name = 'TABLE_NAME'"
  • (2026-02-12) Docker compose project: bigmac (detected from container names like bigmac_postgres)
  • (2026-02-12) DB access: Exposed on port 5433, credentials in server/.env + secrets/db_password_server
  • Source plan: /Users/natalliabukhtsik/Desktop/projects/bigmac/.ai/deletion_improvement_plan.md
  • Client deletion (gold standard): packages/clients/src/actions/clientActions.ts:832-1123
  • Client dialog usage: packages/clients/src/components/clients/ClientDetails.tsx:1262-1365
  • ConfirmationDialog: packages/ui/src/components/ConfirmationDialog.tsx
  • Existing DeleteConfirmationDialog wrapper: packages/ui/src/components/settings/dialogs/DeleteConfirmationDialog.tsx
  • Tag cleanup utilities: packages/tags/src/lib/tagCleanup.ts
  • Tag migration: server/migrations/20250702000000_normalize_tags_with_mappings.cjs

Open Questions

  • Should DeleteEntityDialog support dark mode styling from the start? (active dark mode work on dark_times branch)

  • For cascade entities (tickets, projects), should the dialog explain what gets cascade-deleted?

  • Should bulk delete in TicketingDashboard use validateBulkDeletion immediately or defer to P3?

  • (2026-02-12) Added deletion type definitions in packages/types/src/deletion.ts (DeletionValidationResult, DeletionDependency, DeletionAlternative) for shared deletion UX types.

  • (2026-02-12) Added DeletionBlockCode union and wired it into DeletionValidationResult.code.

  • (2026-02-12) Added EntityDeletionConfig and EntityDependencyConfig types (with tagEntityType) to deletion types.

  • (2026-02-12) Exported deletion types from packages/types/src/index.ts barrel.

  • (2026-02-12) Implemented validateDeletion with dependency counting, custom countQuery support, pluralized labels, block message, alternatives, and viewUrl template expansion.

  • (2026-02-12) Added schema-verified deletion configs for core entities plus getDeletionConfig lookup in packages/core/src/config/deletion/index.ts.

  • (2026-02-12) Added deletion actions (preCheckDeletion, deleteEntityWithValidation, validateBulkDeletion), permission checks, and exports; added useDeletionValidation hook.

  • (2026-02-12) Added DeleteEntityDialog component with validation states, dependency list, alternatives, and loading states; exported from @alga-psa/ui.

  • (2026-02-12) Refactored client deletion to use deleteEntityWithValidation, added validateClientDeletion precheck, removed manual tag cleanup, and swapped ClientDetails delete dialog to DeleteEntityDialog with preview + alternative action wiring.

  • (2026-02-12) Refactored contact deletion to use deleteEntityWithValidation and DeleteEntityDialog; removed manual tag cleanup in contactActions.

  • (2026-02-12) Updated user deletion action to use deleteEntityWithValidation and wired UserManagementSettings to DeleteEntityDialog with dependency preview and deactivate alternative.

  • (2026-02-12) Migrated team deletion to deleteEntityWithValidation and updated TeamList to use DeleteEntityDialog with dependency preview.

  • (2026-02-12) Migrated contract line deletion to deleteEntityWithValidation and updated ContractLines UI to use DeleteEntityDialog with dependency preview.

  • (2026-02-12) Added deletion type tests (deletion.test.ts) covering T001-T005; marked T001 complete.

  • (2026-02-12) Marked T002 complete for DeletionDependency type coverage.

  • (2026-02-12) Marked T003 complete for DeletionAlternative type coverage.

  • (2026-02-12) Marked T004 complete for EntityDeletionConfig tagEntityType coverage.

  • (2026-02-12) Marked T005 complete for deletion type barrel exports coverage.

  • (2026-02-12) Added validateDeletion unit tests (T006-T018 coverage started); marked T006 complete.

  • (2026-02-12) Marked T007 complete for validateDeletion dependency block coverage.

  • (2026-02-12) Marked T008 complete for validateDeletion foreignKey counting coverage.

  • (2026-02-12) Marked T009 complete for validateDeletion custom countQuery coverage.

  • (2026-02-12) Marked T010 complete for validateDeletion singular label formatting.

  • (2026-02-12) Marked T011 complete for validateDeletion plural label formatting.

  • (2026-02-12) Marked T012 complete for validateDeletion label endings in 's'.

  • (2026-02-12) Marked T013 complete for validateDeletion block message formatting.

  • (2026-02-12) Marked T014 complete for validateDeletion inactive alternative.

  • (2026-02-12) Marked T015 complete for validateDeletion archive alternative.

  • (2026-02-12) Marked T016 complete for validateDeletion no-alternatives case.

  • (2026-02-12) Marked T017 complete for validateDeletion viewUrl templates.

  • (2026-02-12) Marked T018 complete for validateDeletion missing viewUrlTemplate.

  • (2026-02-12) Added deletion config tests (T019-T030 coverage started); marked T019 complete.

  • (2026-02-12) Marked T020 complete for client document_associations countQuery.

  • (2026-02-12) Marked T021 complete for client inactive/tagEntityType config.

  • (2026-02-12) Marked T022 complete for contact foreign key config.

  • (2026-02-12) Marked T023 complete for contact portal user countQuery.

  • (2026-02-12) Marked T024 complete for team_members dependency config.

  • (2026-02-12) Marked T025 complete for schedule_entry_assignees dependency config.

  • (2026-02-12) Marked T026 complete for contract_line usage_tracking foreign key.

  • (2026-02-12) Marked T027 complete for client_tax_rates dependency config.

  • (2026-02-12) Marked T028 complete for board category dependency config.

  • (2026-02-12) Marked T029 complete for getDeletionConfig known entity coverage.

  • (2026-02-12) Marked T030 complete for getDeletionConfig unknown entity coverage.

  • (2026-02-12) Added deletion action tests (T031-T066 coverage started); marked T031 complete.

  • (2026-02-12) Marked T032 complete for preCheckDeletion permission denial.

  • (2026-02-12) Marked T033 complete for preCheckDeletion client permission mapping.

  • (2026-02-12) Marked T034 complete for preCheckDeletion canDelete true.

  • (2026-02-12) Marked T035 complete for preCheckDeletion dependency list.

  • (2026-02-12) Marked T036 complete for preCheckDeletion unknown entity.

  • (2026-02-12) Marked T037 complete for deleteEntityWithValidation single transaction.

  • (2026-02-12) Marked T038 complete for deleteEntityWithValidation skip on failed validation.

  • (2026-02-12) Marked T039 complete for deleteEntityWithValidation tag cleanup order.

  • (2026-02-12) Marked T040 complete for deleteEntityWithValidation no tag cleanup when unset.

  • (2026-02-12) Marked T041 complete for deleteEntityWithValidation success result.

  • (2026-02-12) Marked T042 complete for deleteEntityWithValidation dependency re-check.

  • (2026-02-12) Marked T043 complete for deleteEntityWithValidation rollback behavior.

  • (2026-02-12) Added DeleteEntityDialog tests (T044-T058 coverage started); marked T044 complete.

  • (2026-02-12) Marked T045 complete for DeleteEntityDialog confirmation message.

  • (2026-02-12) Marked T046 complete for DeleteEntityDialog delete button.

  • (2026-02-12) Marked T047 complete for DeleteEntityDialog cannot-delete title.

  • (2026-02-12) Marked T048 complete for DeleteEntityDialog dependency list.

  • (2026-02-12) Marked T049 complete for DeleteEntityDialog view links.

  • (2026-02-12) Marked T050 complete for DeleteEntityDialog missing view link.

  • (2026-02-12) Marked T051 complete for DeleteEntityDialog primary alternative.

  • (2026-02-12) Marked T052 complete for DeleteEntityDialog secondary alternative styling.

  • (2026-02-12) Marked T053 complete for DeleteEntityDialog no-alternatives case.

  • (2026-02-12) Marked T054 complete for DeleteEntityDialog deleting spinners.

  • (2026-02-12) Marked T055 complete for DeleteEntityDialog disabled buttons while deleting.

  • (2026-02-12) Marked T056 complete for DeleteEntityDialog alternative action handler.

  • (2026-02-12) Marked T057 complete for DeleteEntityDialog cancel handler.

  • (2026-02-12) Marked T058 complete for DeleteEntityDialog confirm handler.

  • (2026-02-12) Added useDeletionValidation hook tests (T059-T062 coverage started); marked T059 complete.

  • (2026-02-12) Marked T060 complete for useDeletionValidation validationResult.

  • (2026-02-12) Marked T061 complete for useDeletionValidation error handling.

  • (2026-02-12) Marked T062 complete for useDeletionValidation reset behavior.

  • (2026-02-12) Marked T063 complete for validateBulkDeletion single transaction.

  • (2026-02-12) Marked T064 complete for validateBulkDeletion all-pass case.

  • (2026-02-12) Marked T065 complete for validateBulkDeletion partial failure case.

  • (2026-02-12) Marked T066 complete for validateBulkDeletion unknown entity handling.

  • (2026-02-12) Added deletion migration tests (T067-T099 coverage started) and migration updates for categories, interaction types, and boards; marked T067 complete.

  • (2026-02-12) Marked T068 complete for client IS_DEFAULT precondition.

  • (2026-02-12) Marked T069 complete for client tag cleanup removal.

  • (2026-02-12) Marked T070 complete for ClientDetails DeleteEntityDialog usage.

  • (2026-02-12) Marked T071 complete for ClientDetails delete preview validation.

  • (2026-02-12) Marked T072 complete for ClientDetails deactivate alternative wiring.

  • (2026-02-12) Marked T073 complete for ClientDetails dependency JSX removal.

  • (2026-02-12) Marked T074 complete for contact deletion migration coverage.

  • (2026-02-12) Marked T075 complete for contact tag cleanup removal.

  • (2026-02-12) Marked T076 complete for user deletion migration coverage.

  • (2026-02-12) Marked T077 complete for team deletion migration coverage.

  • (2026-02-12) Marked T078 complete for contract line deletion migration coverage.

  • (2026-02-12) Marked T079 complete for service deletion migration coverage.

  • (2026-02-12) Marked T080 complete for tax rate deletion migration coverage.

  • (2026-02-12) Marked T081 complete for invoice template deletion migration coverage.

  • (2026-02-12) Marked T082 complete for ticket deletion migration coverage.

  • (2026-02-12) Marked T083 complete for ticket tag cleanup removal.

  • (2026-02-12) Marked T084 complete for project deletion migration coverage.

  • (2026-02-12) Marked T085 complete for project task tag cleanup in deletion.

  • (2026-02-12) Marked T086 complete for project task tag cleanup removal.

  • (2026-02-12) Marked T087 complete for category deletion migration coverage.

  • (2026-02-12) Marked T088 complete for status deletion migration coverage.

  • (2026-02-12) Marked T089 complete for priority deletion migration coverage.

  • (2026-02-12) Marked T090 complete for board deletion migration coverage.

  • (2026-02-12) Marked T091 complete for document deletion migration coverage.

  • (2026-02-12) Marked T092 complete for asset deletion migration coverage.

  • (2026-02-12) Marked T093 complete for schedule entry deletion migration coverage.

  • (2026-02-12) Marked T094 complete for survey template deletion migration coverage.

  • (2026-02-12) Marked T095 complete for workflow deletion migration coverage.

  • (2026-02-12) Marked T096 complete for role deletion migration coverage.

  • (2026-02-12) Marked T097 complete for interaction type deletion migration coverage.

  • (2026-02-12) Marked T098 complete for ConfirmationDialog capability coverage.

  • (2026-02-12) Marked T099 complete for ConfirmationDialog non-deletion usage coverage.

  • (2026-02-12) Fixed migration test paths (contact/actions, scheduleActions, surveyActions, workflow-runtime-v2-actions, policyActions) and adjusted DeleteEntityDialog title test to handle duplicate title nodes.

  • (2026-02-12) Migrated billing service deletion to deleteEntityWithValidation + DeleteEntityDialog, added preCheckDeletion preview and deactivate alternative in ServiceCatalogManager; deleteService now returns validation result for dialog handling.

  • (2026-02-12) Migrated billing tax rate deletion to DeleteEntityDialog + deleteEntityWithValidation with dependency preview via preCheckDeletion; removed custom confirm dialog flow in TaxRates.

  • (2026-02-12) Migrated invoice template deletion to DeleteEntityDialog + deleteEntityWithValidation; added preCheckDeletion preview and expanded invoice_template deletion config to include clients and conditional rules.

  • (2026-02-12) Migrated ticket deletion to deleteEntityWithValidation with DeleteEntityDialog preview in TicketingDashboard; removed manual ticket tag cleanup and updated bulk delete to use validation helper.

  • (2026-02-12) Migrated project deletion to deleteEntityWithValidation + DeleteEntityDialog with preCheckDeletion preview; added project task tag cleanup via deleteEntitiesTags and removed manual project task tag deletion in ProjectTask model.

  • (2026-02-12) Wired reference-data category deletion to deleteEntityWithValidation and added DeleteEntityDialog + preCheckDeletion preview in TicketingConfigStep.

  • (2026-02-12) Added dynamic status deletion dependencies in core config; migrated status deletion actions/UI to DeleteEntityDialog with preCheckDeletion and deleteEntityWithValidation (ProjectStatusSettings + onboarding statuses).

  • (2026-02-12) Migrated priority deletion to deleteEntityWithValidation and DeleteEntityDialog (PrioritySettings + onboarding priorities) with ITIL-standard guard via validatePriorityDeletion.

  • (2026-02-12) Migrated board deletion in onboarding to DeleteEntityDialog + preCheckDeletion and routed reference-data board deletion through deleteEntityWithValidation.

  • (2026-02-12) Migrated document deletion to deleteEntityWithValidation and DeleteEntityDialog in DocumentStorageCard; updated deleteDocument to return validation result and adjusted bulk delete handling.

  • (2026-02-12) Migrated asset deletion to deleteEntityWithValidation and DeleteEntityDialog (DeleteAssetButton), with dependency preview via preCheckDeletion.

  • (2026-02-12) Schedule entry deletion migrated: deleteScheduleEntry now uses deleteEntityWithValidation, preserves private-entry checks, returns DeletionValidationResult, and permission mapping now treats schedule_entry as user_schedule. Updated ScheduleCalendar and EntryPopup to use DeleteEntityDialog with preCheckDeletion and recurrence-scope selection; WeeklyScheduleEvent now defers delete confirmation to ScheduleCalendar dialog. Technician dispatch ScheduleEvent now uses DeleteEntityDialog with preview and validates before delete; delete pipeline returns validation results for dialog display.

  • (2026-02-12) Lint note: eslint still reports pre-existing warnings and the feature-to-feature import error in TechnicianDispatchDashboard (scheduling -> tickets). Not introduced by this change.

  • (2026-02-12) Survey template deletion migrated: Added survey_template deletion config (survey_triggers, survey_invitations, survey_responses deps) and mapped survey_template permissions to settings for delete checks. deleteSurveyTemplate now uses deleteEntityWithValidation and returns DeletionValidationResult. TemplateList + TemplateForm now use DeleteEntityDialog with preCheckDeletion for preview and deletion.

  • (2026-02-12) Lint note: surveys eslint still reports existing feature-to-feature import error (surveys -> tickets) and warnings unrelated to this change.

  • (2026-02-12) Workflow deletion migrated: Added preCheckWorkflowDefinitionDeletion and updated deleteWorkflowDefinitionAction to use deleteEntityWithValidation with active-run/system checks returning DeletionValidationResult. WorkflowList now uses DeleteEntityDialog with dependency preview and handles validation failures; bulk delete respects new result shape. Updated deletion permission checks to use workflow 'manage' action (no delete permission exists) via permissionActionFor.

  • (2026-02-12) Lint note: workflows eslint shows many pre-existing warnings; no new errors.

  • (2026-02-12) Role deletion migrated: deleteRole now uses deleteEntityWithValidation with admin-role guard and returns DeletionValidationResult. RoleManagement uses DeleteEntityDialog with preCheckDeletion preview and handles validation failures. Added permission mapping for role deletions to security_settings.

  • (2026-02-12) Lint note: auth package retains pre-existing warnings (unused Flex/Text, handleUpdateRole, explicit any).

  • (2026-02-12) Interaction type deletion migrated: deleteReferenceDataItem now routes interaction_types through deleteEntityWithValidation using interaction_type config. No dedicated UI entrypoint found for interaction type settings; action now returns DeletionValidationResult for DeleteEntityDialog usage where applicable.

  • (2026-02-12) Lint note: reference-data eslint warnings are pre-existing.