Skip to content

Integrations and shared platform · Asana-to-Teamwork migration and data preservation

Moving work history while protecting manual edits

Source-reviewed technical draft. Diagrams and walkthroughs use abstract or invented inputs. Implementation, reported use and measured outcomes remain separate.

I contributed to the Asana-to-Teamwork migration in three stages: preparing import workbooks, repairing historical comment handling, and filling missing custom fields without overwriting populated destination values. Each stage answers a different operational question. Can the work be imported? Can its history remain readable? Can a later repair respect changes made after the original migration?

The last question is the strongest part of this story.

An import is a transformation. A repair operates against a system people may already be editing. I needed the latter workflow to distinguish missing data from a deliberate destination value.

Make the transformation inspectable

The formatter in the authored change prepares task and comment worksheets, builds titles from the available client/request/submitter fields, removes selected Asana boilerplate from descriptions and writes an audit of non-Google links. That creates concrete artifacts an operator can inspect before an import.

I keep the file-transfer boundary explicit. The inspected formatter flags links for transfer; it does not perform the Drive transfer or conversion described in the broader PR narrative. Its link checks use string matching rather than complete origin validation. Its description-based field extraction also expects a same-line label and value. Those details matter when assessing what this stage can preserve automatically.

The authored change records a larger workbook-generation pass. I do not treat its reported source counts as verified destination imports, complete history preservation or an operational outcome.

The historical backfill in the authored change includes comment-normalization work. The selected comment code distinguishes source text from delivery text, normalizes line endings and handles non-breaking spaces for the destination. I would explain this as preserving readable history through a particular representation change. The inspected excerpts do not establish that every historical comment was recovered or that every formatting edge case was tested.

Preserve a populated destination

The field comparator in the authored change maps source fields to destination fields and classifies each comparison. Empty source values are held. Existing equivalent values are already matching. Different populated values are marked as manual edits to preserve. A valid source value can become an eligible mutation when its destination is empty; an oversized integer-like value is held as an ambiguous type.

I can show why these categories are more useful than a blanket overwrite.

They let the operator inspect intended changes before running a batch. The comparison uses the source and live destination; it does not have a historical common baseline. I would not describe it as a complete three-way merge simply because a source comment uses that term.

Inspect the system diagram
Conceptual selected FIELD-01 repair. Source-versus-live comparison preserves populated destination values; a fresh read and snapshot precede eligible writes. Provider acceptance and local receipts are separate. Readback checks receipt-listed fields and can omit unread tasks; stored-value rollback lacks a fresh human-edit guard. No migration or mutation was executed.
Migration field repair, receipts and incomplete readback boundaries

The batch updater reads the live task again, saves a local snapshot and withholds the task's update if any targeted destination field has become nonempty. Otherwise it sends the eligible custom-field values, then appends a success receipt after the provider accepts the request. Rate-limit handling includes a bounded retry, and the batch spaces accepted writes.

That second read narrows the stale-plan problem. It does not eliminate it.

A human can edit between the fresh read and the patch. The provider mutation and local receipt also remain separate operations. A crash after acceptance but before receipt persistence leaves uncertain progress. Existing success receipts cause task-level skips, without binding those skips to a particular manifest or mapping version. Dry run still performs live reads and local snapshot writes, and its successful planning count is not a count of provider mutations.

I also avoid claiming webhook suppression: the inspected patch URL does not include the suppression parameter mentioned in the updater's comments.

Readback needs a denominator

The readback auditor checks fields listed in the latest success receipt for each task. It compares normalized strings or numeric values against freshly returned destination fields. This is stronger evidence than accepting the write response alone.

But a report needs to account for what it could not read.

The inspected auditor logs a failed task read without adding it to the field-check denominator. Zero checked fields can produce a reported parity rate of 100%. It also does not implement all the broader unchanged-field checks described in its header. I would present it as selected-field readback, with a coverage gap, rather than complete task preservation.

The rollback script sends stored original custom-field values. It does not reread and compare the current task before restoring them. I cannot claim that this rollback preserves later human edits.

My next iteration would bind receipts to a manifest version, separate planned and accepted counts, report unread tasks explicitly and require a current-value check before rollback. Those are proposed improvements. They are not features delivered by the inspected version.

Invented repair walkthrough

  1. Show fictional Harbor task H-101 with an empty destination campaign field and a valid source campaign code.
  2. Show H-102 with a different populated destination value. The comparator preserves it and excludes that mutation.
  3. Populate H-101 after planning but before the updater's fresh read. The updater withholds that task's write.
  4. Reconstruct acceptance followed by a missing receipt. Explain why task-level receipts alone cannot prove exactly-once progress.
  5. Give the auditor one matching field and one unread task. Show the difference between checked-field parity and full-batch coverage.
  6. Inspect a snapshot after a later manual edit and explain the guard a safe rollback still needs.

This walkthrough uses reconstructed branches and toy identifiers. It performs no provider write, migration or rollback.

Contribution and result

The authored PRs establish migration preparation, historical repair and field-preservation work. Selected implementation establishes workbook outputs, conservative comparison categories, a fresh-read guard, snapshots, receipts and selected-field readback. I do not claim a verified number of migrated tasks, recovered comments, avoided overwrites or saved hours.

My interview story is about repair in a changing system. A customer integration rarely ends after the first import. The system also needs a way to reconcile incomplete data with ongoing human work and explain the remaining uncertainty.

Discussion notes

Three-minute outline. explain the migration-to-repair shift; show preserved versus eligible fields; walk through the fresh read, snapshot and receipt; finish with the readback denominator and rollback limit.

Questions to prepare. What identifies a repair run? What happens after acceptance but before a receipt? How should unread tasks affect a parity report? What conditions authorize rollback? How would a destination API with conditional writes change the design?

Application summary. I contributed migration and repair workflows that turn source data into inspectable import artifacts and distinguish missing destination fields from manual edits. I can explain the provider boundary, recovery records and incomplete readback evidence, including the controls needed before treating a repair report as complete. That is useful when deploying automation into a customer's existing operational system.

This contribution narrative is supported by privately held source and authorship records. It contains original explanations and abstract diagrams, without employer code, customer records or runtime telemetry. Missing outcome evidence stays explicit.