How Soft Delete vs Hard Delete Works for Invoices
Source: invoice.rb:8, invoice.rb:583-596, invoices_controller.rb:287
- Deleted and voided invoices are hidden by default across the entire system via a default_scope that excludes deleted=true and voided=true records
- When WS API integration is active, invoices are soft-deleted (deleted=true) instead of hard-deleted from the database
- When WS API is not active, invoices are fully destroyed (hard delete)
- To query soft-deleted or voided records, the code must explicitly use unscoped -- normal queries never return them
- Archived customers can still appear on existing invoices because the customer relationship uses unscope(where: :archived) to bypass the archived filter
- Invoice items also have a separate default_scope hiding deleted items
Support scenarios
- "Why can't I see a voided invoice in my invoice list?" -> voided invoices are hidden by default; they exist in the database but are filtered out of all queries
- "I archived a customer but their old invoices still show up" -> this is by design; the invoice-customer link bypasses the archived scope
- "The invoice is gone from the list but a developer says it's in the database" -> WS API integration causes soft-delete instead of hard-delete