feat: add safe owner-only migration reset (#1682)

* feat: add safe company migration reset

* fix: harden company reset eligibility

* fix: close company reset compliance gaps

* test: fix migration reset pg-real probes

* fix: preserve migration archive access

* docs: explain migration numbering continuity

* fix: block reset with VAT workflow state

* fix: block externally staged reset data

* fix: address migration reset review findings

* fix: clear stale migration archive estimate

* fix: retry migration archive estimates
This commit is contained in:
Mattsson
2026-08-19 12:04:24 +02:00
committed by GitHub
parent b07a4a4bca
commit 3a1b842e4a
24 changed files with 5017 additions and 57 deletions
+63 -4
View File
@@ -1811,10 +1811,69 @@
"fp_blocked_first_year": "First fiscal year:",
"fp_blocked_calendar_year": " (calendar year)",
"fp_blocked_broken_year": " (broken fiscal year)",
"fp_blocked_explainer": "If you have to start over you can delete the company at the bottom of this page and create a new one. Bookkeeping data is retained for 7 years per BFL 7 kap. 2§.",
"fp_year_label_single": "Räkenskapsår {year}",
"fp_year_label_range": "Räkenskapsår {startYear}/{endYear}",
"danger_heading": "Delete company",
"fp_blocked_explainer": "If this is a recent failed migration, the company owner can use Redo migration under Danger zone. The previous bookkeeping copy is archived and retained under BFL.",
"fp_year_label_single": "Fiscal year {year}",
"fp_year_label_range": "Fiscal year {startYear}/{endYear}",
"danger_heading": "Danger zone",
"reset_row_label": "Redo migration",
"reset_row_note": "Archive the current data and start in an empty company copy.",
"reset_row_action": "Start over",
"reset_dialog_title": "Redo the migration for {companyName}",
"reset_dialog_description": "The current company will be archived and an empty company copy will be created for the new migration. This cannot be undone through self-service.",
"reset_checking": "Checking whether the company can be reset...",
"reset_load_failed": "Could not check whether the company can be reset.",
"reset_archive_title": "Nothing is deleted",
"reset_archive_description": "Imported transactions, documents, periods, and import history remain unchanged in the archived company. Self-service is blocked if a voucher, voucher sequence, or invoice already exists.",
"reset_blocked_title": "Self-service is blocked",
"reset_blocker_window": "The self-service reset window ended on {date}.",
"reset_blocker_sandbox": "Sandbox companies use their separate automatic cleanup and cannot be reset here.",
"reset_blocker_periods": "{count, plural, =1 {One bookkeeping lock or closed fiscal year exists.} other {# bookkeeping locks or closed fiscal years exist.}}",
"reset_blocker_entries": "{count, plural, =1 {One voucher already exists; drafts and migrated vouchers also block reset.} other {# vouchers already exist; drafts and migrated vouchers also block reset.}}",
"reset_blocker_sequences": "{count, plural, =1 {One voucher sequence has already been created.} other {# voucher sequences have already been created.}}",
"reset_blocker_invoices": "{count, plural, =1 {One customer or supplier invoice already exists.} other {# customer or supplier invoices already exist.}}",
"reset_blocker_filings": "{count, plural, =1 {One known submission to Skatteverket or Bolagsverket exists.} other {# known submissions to Skatteverket or Bolagsverket exist.}}",
"reset_blocker_bank_connections": "{count, plural, =1 {One bank connection is still active or being connected. Disconnect it first.} other {# bank connections are still active or being connected. Disconnect them first.}}",
"reset_blocker_imports": "{count, plural, =1 {One import is still in progress. Wait for it to finish or fail before retrying.} other {# imports are still in progress. Wait for them to finish or fail before retrying.}}",
"reset_blocker_automations": "{count, plural, =1 {One integration or automatic schedule can still create data. Disable it first.} other {# integrations or automatic schedules can still create data. Disable them first.}}",
"reset_blocker_background_work": "{count, plural, =1 {One background task is still running. Wait for it to finish or fail.} other {# background tasks are still running. Wait for them to finish or fail.}}",
"reset_blocker_other": "The company status does not allow a reset.",
"reset_retained_heading": "Data retained in the archived company",
"reset_count_journal_entries": "Vouchers",
"reset_count_journal_entry_lines": "Voucher lines",
"reset_count_committed_import_entries": "Committed import vouchers",
"reset_count_transactions": "Transactions",
"reset_count_fiscal_periods": "Fiscal years",
"reset_count_documents": "Documents",
"reset_count_voucher_sequences": "Voucher sequences",
"reset_count_sie_imports": "SIE imports",
"reset_count_bank_file_imports": "Bank file imports",
"reset_count_skattekonto_file_imports": "Tax account file imports",
"reset_count_bank_connections": "Bank connections",
"reset_count_customers": "Customers",
"reset_count_suppliers": "Suppliers",
"reset_count_invoices": "Customer invoices",
"reset_count_supplier_invoices": "Supplier invoices",
"reset_reason_label": "Why does the migration need to be redone?",
"reset_reason_placeholder": "Describe what went wrong in the previous migration...",
"reset_reason_help": "{count}/1,000 characters, minimum 20",
"reset_confirm_no_filings": "I confirm that no tax returns, control statements, ROT/RUT requests, or annual reports have been filed for this company, through {appName} or otherwise.",
"reset_confirm_archive": "I understand that the old company copy is retained as a locked archive for traceability and statutory retention, and is not deleted.",
"reset_confirm_name": "Type <strong>{companyName}</strong> to confirm",
"reset_submit": "Archive and start over",
"reset_resetting": "Creating a new company copy...",
"reset_success_title": "The migration can be redone",
"reset_success_description": "The old company copy is archived. You can now start the new import.",
"reset_failed_title": "Could not redo the migration",
"reset_failed_default": "No changes were saved. Try again.",
"reset_archive_group_label": "Previous migration",
"reset_archive_row_label": "Archived company copy",
"reset_archive_row_note": "Locked and retained, including {count, plural, =1 {one document} other {# documents}}.",
"reset_archive_row_action": "Download archive",
"reset_archive_download_title": "Download the previous migration",
"reset_archive_download_description": "Creates a read-only ZIP from the locked company copy. The archived data stays unchanged and the copy is not reopened.",
"reset_archive_over_limit": "The retained archive is larger than {limit}. Turn off documents to download the structured data now, then contact support for the complete document package.",
"reset_archive_too_large_with_size": "The retained archive is about {size} MB. Turn off documents for a structured-data ZIP, then contact support for the complete document package.",
"reset_archive_too_large": "Turn off documents for a structured-data ZIP, then contact support for the complete document package.",
"danger_button": "Delete company",
"danger_dialog_title": "Delete {companyName}",
"danger_dialog_description": "The company is hidden from {appName}. The bookkeeping is retained securely for 7 years per BFL. Type the company name exactly to confirm.",
+61 -2
View File
@@ -1811,10 +1811,69 @@
"fp_blocked_first_year": "Första räkenskapsåret:",
"fp_blocked_calendar_year": " (kalenderår)",
"fp_blocked_broken_year": " (brutet räkenskapsår)",
"fp_blocked_explainer": "Om du måste börja om kan du radera företaget längst ner på sidan och skapa ett nytt. Bokföringsdata behålls i 7 år enligt BFL 7 kap. 2§.",
"fp_blocked_explainer": "Om detta är en nyligen misslyckad migrering kan företagets ägare använda Gör om migrering under Riskzon. Den tidigare bokföringskopian arkiveras och behålls enligt BFL.",
"fp_year_label_single": "Räkenskapsår {year}",
"fp_year_label_range": "Räkenskapsår {startYear}/{endYear}",
"danger_heading": "Radera företag",
"danger_heading": "Riskzon",
"reset_row_label": "Gör om migrering",
"reset_row_note": "Arkivera nuvarande data och börja i en tom företagskopia.",
"reset_row_action": "Starta om",
"reset_dialog_title": "Gör om migreringen för {companyName}",
"reset_dialog_description": "Det nuvarande företaget arkiveras och en tom företagskopia skapas för den nya migreringen. Åtgärden kan inte ångras med självservice.",
"reset_checking": "Kontrollerar om företaget kan återställas...",
"reset_load_failed": "Kunde inte kontrollera om företaget kan återställas.",
"reset_archive_title": "Ingenting raderas",
"reset_archive_description": "Importerade transaktioner, dokument, perioder och importhistorik stannar oförändrade i det arkiverade företaget. Självservice blockeras om en verifikation, nummerserie eller faktura redan finns.",
"reset_blocked_title": "Självservice är blockerad",
"reset_blocker_window": "Tidsgränsen för återställning med självservice gick ut {date}.",
"reset_blocker_sandbox": "Testföretag använder sin separata automatiska rensning och kan inte återställas här.",
"reset_blocker_periods": "{count, plural, =1 {Ett bokföringslås eller stängt räkenskapsår finns.} other {# bokföringslås eller stängda räkenskapsår finns.}}",
"reset_blocker_entries": "{count, plural, =1 {En verifikation finns redan, även utkast och migrerade verifikationer blockerar återställning.} other {# verifikationer finns redan, även utkast och migrerade verifikationer blockerar återställning.}}",
"reset_blocker_sequences": "{count, plural, =1 {En verifikationsserie har redan skapats.} other {# verifikationsserier har redan skapats.}}",
"reset_blocker_invoices": "{count, plural, =1 {En kund- eller leverantörsfaktura finns redan.} other {# kund- eller leverantörsfakturor finns redan.}}",
"reset_blocker_filings": "{count, plural, =1 {En känd inlämning till Skatteverket eller Bolagsverket finns.} other {# kända inlämningar till Skatteverket eller Bolagsverket finns.}}",
"reset_blocker_bank_connections": "{count, plural, =1 {En bankkoppling är fortfarande aktiv eller håller på att anslutas. Koppla från den först.} other {# bankkopplingar är fortfarande aktiva eller håller på att anslutas. Koppla från dem först.}}",
"reset_blocker_imports": "{count, plural, =1 {En import pågår fortfarande. Vänta tills den är klar eller har misslyckats innan du försöker igen.} other {# importer pågår fortfarande. Vänta tills de är klara eller har misslyckats innan du försöker igen.}}",
"reset_blocker_automations": "{count, plural, =1 {En integration eller automatisk körning kan fortfarande skapa data. Inaktivera den först.} other {# integrationer eller automatiska körningar kan fortfarande skapa data. Inaktivera dem först.}}",
"reset_blocker_background_work": "{count, plural, =1 {Ett bakgrundsjobb pågår fortfarande. Vänta tills det är klart eller har misslyckats.} other {# bakgrundsjobb pågår fortfarande. Vänta tills de är klara eller har misslyckats.}}",
"reset_blocker_other": "Företagets status tillåter inte återställning.",
"reset_retained_heading": "Data som sparas i det arkiverade företaget",
"reset_count_journal_entries": "Verifikationer",
"reset_count_journal_entry_lines": "Verifikationsrader",
"reset_count_committed_import_entries": "Bokförda importverifikationer",
"reset_count_transactions": "Transaktioner",
"reset_count_fiscal_periods": "Räkenskapsår",
"reset_count_documents": "Dokument",
"reset_count_voucher_sequences": "Verifikationsserier",
"reset_count_sie_imports": "SIE-importer",
"reset_count_bank_file_imports": "Bankfilsimporter",
"reset_count_skattekonto_file_imports": "Skattekontofilsimporter",
"reset_count_bank_connections": "Bankkopplingar",
"reset_count_customers": "Kunder",
"reset_count_suppliers": "Leverantörer",
"reset_count_invoices": "Kundfakturor",
"reset_count_supplier_invoices": "Leverantörsfakturor",
"reset_reason_label": "Varför behöver migreringen göras om?",
"reset_reason_placeholder": "Beskriv felet i den tidigare migreringen...",
"reset_reason_help": "{count}/1 000 tecken, minst 20",
"reset_confirm_no_filings": "Jag bekräftar att inga deklarationer, kontrolluppgifter, ROT/RUT-begäranden eller årsredovisningar har lämnats in från företaget, varken via {appName} eller på annat sätt.",
"reset_confirm_archive": "Jag förstår att den gamla företagskopian sparas som ett låst arkiv för spårbarhet och lagstadgad bevaring, och att den inte raderas.",
"reset_confirm_name": "Skriv <strong>{companyName}</strong> för att bekräfta",
"reset_submit": "Arkivera och börja om",
"reset_resetting": "Skapar ny företagskopia...",
"reset_success_title": "Migreringen kan göras om",
"reset_success_description": "Den gamla företagskopian är arkiverad. Du kan nu starta den nya importen.",
"reset_failed_title": "Kunde inte göra om migreringen",
"reset_failed_default": "Inga ändringar sparades. Försök igen.",
"reset_archive_group_label": "Föregående migrering",
"reset_archive_row_label": "Arkiverad företagskopia",
"reset_archive_row_note": "Låst och bevarad, inklusive {count, plural, =1 {ett dokument} other {# dokument}}.",
"reset_archive_row_action": "Ladda ner arkiv",
"reset_archive_download_title": "Ladda ner föregående migrering",
"reset_archive_download_description": "Skapar en skrivskyddad ZIP från den låsta företagskopian. Arkivuppgifterna ändras inte och kopian öppnas inte igen.",
"reset_archive_over_limit": "Det bevarade arkivet är större än {limit}. Stäng av dokument för att ladda ner strukturerade uppgifter nu och kontakta sedan support för hela dokumentpaketet.",
"reset_archive_too_large_with_size": "Det bevarade arkivet är cirka {size} MB. Stäng av dokument för en ZIP med strukturerade uppgifter och kontakta sedan support för hela dokumentpaketet.",
"reset_archive_too_large": "Stäng av dokument för en ZIP med strukturerade uppgifter och kontakta sedan support för hela dokumentpaketet.",
"danger_button": "Radera företag",
"danger_dialog_title": "Radera {companyName}",
"danger_dialog_description": "Företaget döljs från {appName}. Bokföringen behålls säkert i 7 år enligt BFL. Skriv företagets namn exakt för att bekräfta.",