[ { "id": "T001", "description": "DeletionValidationResult type includes canDelete, code, message, dependencies, alternatives fields", "implemented": true, "featureIds": ["F001"] }, { "id": "T002", "description": "DeletionDependency type includes type, count, label, description, viewUrl fields", "implemented": true, "featureIds": ["F001"] }, { "id": "T003", "description": "DeletionAlternative type includes action, label, description, warning fields", "implemented": true, "featureIds": ["F001"] }, { "id": "T004", "description": "EntityDeletionConfig includes tagEntityType optional field", "implemented": true, "featureIds": ["F003"] }, { "id": "T005", "description": "All deletion types are exported from @alga-psa/types barrel", "implemented": true, "featureIds": ["F004"] }, { "id": "T006", "description": "validateDeletion returns canDelete:true when entity has no dependencies", "implemented": true, "featureIds": ["F005"] }, { "id": "T007", "description": "validateDeletion returns canDelete:false with dependency list when entity has blocking deps", "implemented": true, "featureIds": ["F005"] }, { "id": "T008", "description": "validateDeletion counts dependencies using foreignKey from config", "implemented": true, "featureIds": ["F005"] }, { "id": "T009", "description": "validateDeletion uses custom countQuery when provided (document_associations polymorphic table)", "implemented": true, "featureIds": ["F006"] }, { "id": "T010", "description": "validateDeletion formats '1 ticket' (singular) correctly", "implemented": true, "featureIds": ["F007"] }, { "id": "T011", "description": "validateDeletion formats '5 tickets' (plural) correctly", "implemented": true, "featureIds": ["F007"] }, { "id": "T012", "description": "validateDeletion handles labels ending in 's' without double-pluralizing", "implemented": true, "featureIds": ["F007"] }, { "id": "T013", "description": "Block message includes all dependency labels joined with commas", "implemented": true, "featureIds": ["F008"] }, { "id": "T014", "description": "Alternatives include 'Mark as Inactive' when supportsInactive is true", "implemented": true, "featureIds": ["F009"] }, { "id": "T015", "description": "Alternatives include 'Archive' when supportsArchive is true", "implemented": true, "featureIds": ["F009"] }, { "id": "T016", "description": "Alternatives are empty when neither supportsInactive nor supportsArchive", "implemented": true, "featureIds": ["F009"] }, { "id": "T017", "description": "viewUrl is populated from viewUrlTemplate with entityId substitution", "implemented": true, "featureIds": ["F010"] }, { "id": "T018", "description": "viewUrl is undefined when viewUrlTemplate is not configured", "implemented": true, "featureIds": ["F010"] }, { "id": "T019", "description": "Client config has correct foreign keys: contacts.client_id, tickets.client_id, projects.client_id, invoices.client_id, interactions.client_id, assets.client_id, usage_tracking.client_id, bucket_usage.client_id", "implemented": true, "featureIds": ["F011"] }, { "id": "T020", "description": "Client config uses custom countQuery for document_associations with entity_type='company'", "implemented": true, "featureIds": ["F011"] }, { "id": "T021", "description": "Client config has supportsInactive=true and tagEntityType='client'", "implemented": true, "featureIds": ["F011"] }, { "id": "T022", "description": "Contact config has correct foreign keys: tickets.contact_name_id, interactions.contact_name_id", "implemented": true, "featureIds": ["F012"] }, { "id": "T023", "description": "Contact config uses custom countQuery for portal users (users.contact_id with user_type='client')", "implemented": true, "featureIds": ["F012"] }, { "id": "T024", "description": "Team config uses table 'team_members' (not 'user_team_members')", "implemented": true, "featureIds": ["F017"] }, { "id": "T025", "description": "User config uses table 'schedule_entry_assignees' (not 'schedule_entries')", "implemented": true, "featureIds": ["F018"] }, { "id": "T026", "description": "Contract line config uses foreignKey 'contract_line_id' on usage_tracking (not 'plan_id')", "implemented": true, "featureIds": ["F019"] }, { "id": "T027", "description": "Tax rate config uses table 'client_tax_rates' (not 'invoices' or 'company_tax_settings')", "implemented": true, "featureIds": ["F021"] }, { "id": "T028", "description": "Board config includes categories.board_id as a dependency", "implemented": true, "featureIds": ["F023"] }, { "id": "T029", "description": "getDeletionConfig returns correct config for known entity types", "implemented": true, "featureIds": ["F024"] }, { "id": "T030", "description": "getDeletionConfig returns undefined for unknown entity type", "implemented": true, "featureIds": ["F024"] }, { "id": "T031", "description": "preCheckDeletion returns PERMISSION_DENIED when user is not authenticated", "implemented": true, "featureIds": ["F026"] }, { "id": "T032", "description": "preCheckDeletion returns PERMISSION_DENIED when user lacks delete permission", "implemented": true, "featureIds": ["F027"] }, { "id": "T033", "description": "preCheckDeletion maps 'client' entity to 'company' permission entity", "implemented": true, "featureIds": ["F027"] }, { "id": "T034", "description": "preCheckDeletion returns canDelete:true for entity with no dependencies", "implemented": true, "featureIds": ["F025", "F028"] }, { "id": "T035", "description": "preCheckDeletion returns dependency list for entity with blocking deps", "implemented": true, "featureIds": ["F025", "F028"] }, { "id": "T036", "description": "preCheckDeletion returns error for unknown entity type", "implemented": true, "featureIds": ["F025"] }, { "id": "T037", "description": "deleteEntityWithValidation validates and deletes in a single transaction (no TOCTOU race)", "implemented": true, "featureIds": ["F029"] }, { "id": "T038", "description": "deleteEntityWithValidation does NOT call performDelete when validation fails", "implemented": true, "featureIds": ["F032"] }, { "id": "T039", "description": "deleteEntityWithValidation calls deleteEntityTags before performDelete when tagEntityType is set", "implemented": true, "featureIds": ["F030"] }, { "id": "T040", "description": "deleteEntityWithValidation does NOT call deleteEntityTags when tagEntityType is not set", "implemented": true, "featureIds": ["F030"] }, { "id": "T041", "description": "deleteEntityWithValidation returns { canDelete: true, deleted: true } on successful deletion", "implemented": true, "featureIds": ["F031"] }, { "id": "T042", "description": "deleteEntityWithValidation returns validation result with canDelete:false if deps found during atomic re-check", "implemented": true, "featureIds": ["F032"] }, { "id": "T043", "description": "deleteEntityWithValidation rolls back entire transaction if performDelete throws", "implemented": true, "featureIds": ["F029"] }, { "id": "T044", "description": "DeleteEntityDialog renders spinner when isValidating=true", "implemented": true, "featureIds": ["F035"] }, { "id": "T045", "description": "DeleteEntityDialog renders confirmation message with entity name when canDelete=true", "implemented": true, "featureIds": ["F036"] }, { "id": "T046", "description": "DeleteEntityDialog renders Delete button when canDelete=true", "implemented": true, "featureIds": ["F036"] }, { "id": "T047", "description": "DeleteEntityDialog renders 'Cannot Delete' title when canDelete=false", "implemented": true, "featureIds": ["F037"] }, { "id": "T048", "description": "DeleteEntityDialog renders itemized dependency list with counts", "implemented": true, "featureIds": ["F037"] }, { "id": "T049", "description": "DeleteEntityDialog renders View links for dependencies that have viewUrl", "implemented": true, "featureIds": ["F038"] }, { "id": "T050", "description": "DeleteEntityDialog does not render View link when viewUrl is undefined", "implemented": true, "featureIds": ["F038"] }, { "id": "T051", "description": "DeleteEntityDialog renders primary alternative action button when alternatives exist", "implemented": true, "featureIds": ["F039"] }, { "id": "T052", "description": "DeleteEntityDialog renders secondary alternative as outline button", "implemented": true, "featureIds": ["F039"] }, { "id": "T053", "description": "DeleteEntityDialog does not render alternative buttons when no alternatives", "implemented": true, "featureIds": ["F039"] }, { "id": "T054", "description": "DeleteEntityDialog shows loading spinner on buttons when isDeleting=true", "implemented": true, "featureIds": ["F040"] }, { "id": "T055", "description": "DeleteEntityDialog disables all buttons when isDeleting=true", "implemented": true, "featureIds": ["F040"] }, { "id": "T056", "description": "DeleteEntityDialog calls onAlternativeAction with action type string on alternative button click", "implemented": true, "featureIds": ["F041"] }, { "id": "T057", "description": "DeleteEntityDialog calls onClose when Cancel is clicked", "implemented": true, "featureIds": ["F034"] }, { "id": "T058", "description": "DeleteEntityDialog calls onConfirmDelete when Delete button is clicked", "implemented": true, "featureIds": ["F034"] }, { "id": "T059", "description": "useDeletionValidation returns isValidating=true during validation", "implemented": true, "featureIds": ["F043"] }, { "id": "T060", "description": "useDeletionValidation returns validationResult after successful validation", "implemented": true, "featureIds": ["F043"] }, { "id": "T061", "description": "useDeletionValidation returns error string when validation throws", "implemented": true, "featureIds": ["F043"] }, { "id": "T062", "description": "useDeletionValidation reset clears all state", "implemented": true, "featureIds": ["F043"] }, { "id": "T063", "description": "validateBulkDeletion validates all entities in a single transaction", "implemented": true, "featureIds": ["F044"] }, { "id": "T064", "description": "validateBulkDeletion returns canDeleteAll=true when all entities pass", "implemented": true, "featureIds": ["F045"] }, { "id": "T065", "description": "validateBulkDeletion returns canDeleteAll=false with cannotDelete list when some fail", "implemented": true, "featureIds": ["F045"] }, { "id": "T066", "description": "validateBulkDeletion returns error for unknown entity type", "implemented": true, "featureIds": ["F044"] }, { "id": "T067", "description": "Client deleteClient uses deleteEntityWithValidation (single transaction)", "implemented": true, "featureIds": ["F046"] }, { "id": "T068", "description": "Client deleteClient returns IS_DEFAULT error for default company before validation", "implemented": true, "featureIds": ["F047"] }, { "id": "T069", "description": "Client deleteClient no longer manually calls deleteEntityTags", "implemented": true, "featureIds": ["F048"] }, { "id": "T070", "description": "ClientDetails.tsx uses DeleteEntityDialog instead of ConfirmationDialog for deletion", "implemented": true, "featureIds": ["F049"] }, { "id": "T071", "description": "ClientDetails.tsx calls validateClientDeletion when delete dialog opens", "implemented": true, "featureIds": ["F050"] }, { "id": "T072", "description": "ClientDetails.tsx passes onAlternativeAction that calls markClientInactiveWithContacts for 'deactivate'", "implemented": true, "featureIds": ["F051"] }, { "id": "T073", "description": "ClientDetails.tsx no longer has inline dependency rendering JSX", "implemented": true, "featureIds": ["F052"] }, { "id": "T074", "description": "Contact deletion uses deleteEntityWithValidation + DeleteEntityDialog", "implemented": true, "featureIds": ["F053"] }, { "id": "T075", "description": "Contact deletion no longer manually calls deleteEntityTags", "implemented": true, "featureIds": ["F076"] }, { "id": "T076", "description": "User deletion uses deleteEntityWithValidation + DeleteEntityDialog", "implemented": true, "featureIds": ["F054"] }, { "id": "T077", "description": "Team deletion uses deleteEntityWithValidation + DeleteEntityDialog", "implemented": true, "featureIds": ["F055"] }, { "id": "T078", "description": "Contract line deletion uses deleteEntityWithValidation + DeleteEntityDialog", "implemented": true, "featureIds": ["F056"] }, { "id": "T079", "description": "Service deletion uses deleteEntityWithValidation + DeleteEntityDialog", "implemented": true, "featureIds": ["F057"] }, { "id": "T080", "description": "Tax rate deletion uses deleteEntityWithValidation + DeleteEntityDialog", "implemented": true, "featureIds": ["F058"] }, { "id": "T081", "description": "Invoice template deletion uses deleteEntityWithValidation + DeleteEntityDialog", "implemented": true, "featureIds": ["F059"] }, { "id": "T082", "description": "Ticket deletion uses deleteEntityWithValidation + DeleteEntityDialog", "implemented": true, "featureIds": ["F060"] }, { "id": "T083", "description": "Ticket deletion no longer manually calls deleteEntityTags", "implemented": true, "featureIds": ["F061"] }, { "id": "T084", "description": "Project deletion uses deleteEntityWithValidation + DeleteEntityDialog", "implemented": true, "featureIds": ["F062"] }, { "id": "T085", "description": "Project deletion calls deleteEntitiesTags for child task tags in performDelete", "implemented": true, "featureIds": ["F063"] }, { "id": "T086", "description": "Project task deletion no longer manually calls deleteEntityTags", "implemented": true, "featureIds": ["F064"] }, { "id": "T087", "description": "Category deletion uses deleteEntityWithValidation + DeleteEntityDialog", "implemented": true, "featureIds": ["F065"] }, { "id": "T088", "description": "Status deletion uses deleteEntityWithValidation + DeleteEntityDialog", "implemented": true, "featureIds": ["F066"] }, { "id": "T089", "description": "Priority deletion uses deleteEntityWithValidation + DeleteEntityDialog", "implemented": true, "featureIds": ["F067"] }, { "id": "T090", "description": "Board deletion uses deleteEntityWithValidation + DeleteEntityDialog", "implemented": true, "featureIds": ["F068"] }, { "id": "T091", "description": "Document deletion uses deleteEntityWithValidation + DeleteEntityDialog", "implemented": true, "featureIds": ["F069"] }, { "id": "T092", "description": "Asset deletion uses deleteEntityWithValidation + DeleteEntityDialog", "implemented": true, "featureIds": ["F070"] }, { "id": "T093", "description": "Schedule entry deletion uses deleteEntityWithValidation + DeleteEntityDialog", "implemented": true, "featureIds": ["F071"] }, { "id": "T094", "description": "Survey template deletion uses deleteEntityWithValidation + DeleteEntityDialog", "implemented": true, "featureIds": ["F072"] }, { "id": "T095", "description": "Workflow deletion uses deleteEntityWithValidation + DeleteEntityDialog", "implemented": true, "featureIds": ["F073"] }, { "id": "T096", "description": "Role deletion uses deleteEntityWithValidation + DeleteEntityDialog", "implemented": true, "featureIds": ["F074"] }, { "id": "T097", "description": "Interaction type deletion uses deleteEntityWithValidation + DeleteEntityDialog", "implemented": true, "featureIds": ["F075"] }, { "id": "T098", "description": "Existing ConfirmationDialog component is unchanged after all migrations", "implemented": true, "featureIds": ["F049"] }, { "id": "T099", "description": "Non-deletion uses of ConfirmationDialog still work (unsaved changes, recurring events, etc.)", "implemented": true, "featureIds": ["F049"] } ]