Skip to content
Timesheet Systems

All notes  /  05 · Implementation

Migrating the History

Statutory retention means old records must stay accessible for years. What to move, what to archive, and the export test that decides which.

Procedure

Time records carry a retention obligation measured in years. A migration therefore has to answer a question most migrations do not: can the old data still be produced on demand?

Test the export before deciding anything

Export a known period from the current system.

Check the edit history survives. Many exports carry the current state only, and the history is the part that matters in a dispute.

Check created-at timestamps are preserved rather than stamped with the import date. An import that restamps everything destroys the contemporaneity that made the record credible.

Reconcile totals against a report from the old system.

If the export is inadequate, do not migrate a degraded copy and call it the record. Keep the old system readable instead.

Three options, and how to choose

Full migration. Everything moves. Only viable when the export is complete and the data models are compatible.

Summary migration plus archive. Aggregates move for reporting; the detailed record stays in a frozen archive with its own retention and access route.

Archive only. Nothing moves; the old system or an export of it remains readable for the retention period.

The second is the usual right answer and the one least often chosen, because it feels like an incomplete migration. It is not: it separates the operational need from the legal one, which have different shapes.

The frozen archive

Exported as-is, unaltered.

With its own retention, deletion schedule and access route.

Not corrected. Its value is that it is what was recorded at the time.

Readable by someone who is not you, which means a documented format and a documented procedure rather than a database nobody can start.

Tested once: produce one person's record for one month from the archive, and time it.

What breaks in a migration

Reference data that no longer exists. Entries pointing at projects and people the new system does not know.

Rule differences, so recalculated totals disagree with what was paid. Never recalculate migrated history; import the figures as recorded.

Approval states that have no equivalent.

Rounding applied at capture in the old system, which means the raw values are already gone and cannot be recovered.

Character encoding, which corrupts names and is discovered by someone finding their own name wrong.

Verification after

Totals reconcile for a sample of periods.

A named person's record is producible end to end.

The audit trail is intact for anything inside the dispute window.

Retention is configured on the archive, not only on the new system.

Someone other than the implementer can follow the procedure, which is the test that matters in three years.

Never recalculate history

A rule that prevents a specific and confusing failure.

Import migrated figures as recorded, not as recalculated under the new rules.

Recalculating produces totals that disagree with what was actually paid, and the discrepancy is unexplainable years later.

Where the new system insists on calculating, import as adjustments or keep the history in the archive instead.

State which approach was used in the migration record, because someone will ask.

What breaks

Five failures that recur across migrations in this category.

Reference data that no longer exists, so entries point at people and projects the new system does not know.

Rule differences, producing recalculated totals that disagree with what was paid.

Approval states with no equivalent.

Rounding applied at capture in the old system, meaning the raw values are already gone.

Character encoding, discovered by someone finding their own name wrong.

Migrate references with the hours

Historical time is less useful when its task hierarchy disappears. Use this project connection to frame tests for IDs, closed work and archived users.