We just launched a new feature in Basecamp that allows you to move messages, to-do lists, milestones and files from one Basecamp project to another. You can read the full announcement on our product blog.

The UI we designed makes it simple to do. Just edit any message, milestone, to-do list or file in Basecamp, select the project you want to move it to, and click a button. Done.

It’s so simple that it’s easy to assume that adding the feature would be simple, too. Customers make this assumption and so do developers.

To put things in perspective here’s what you see after you click Move

…and here’s what is happening behind the scenes:

  • Is the item being moved a message? We’ll need to move any attached files with it. Does it have any comments? Move those, too.
  • Do any of the comments being moved have their own attachments? Better move those as well.
  • Are any of the files images? If so, we’ll need to move the image’s thumbnail, too.
  • Are there multiple versions of the file? Bring those along.
  • Does the message or any of the files have a category? Create the category if it doesn’t exist in the destination project.
  • Is the moved file backed up on S3? We need to rename it there. If it’s not, we need to make sure it doesn’t get backed up with its old filename.
  • Is the item being moved a milestone? Moving a milestone needs to move any associated to-do lists and messages. And of course those to-do lists can have to-do items with comments, and attached files, and multiple versions of those files. Move all of that.
  • Is it a to-do list? It may contain to-do items that have associated time tracking entries. Move those time entries to the destination project too.
  • Was anyone subscribed to email notification for the message? We’ll need to make sure they still get them on the new project.
  • Similarly we need to make sure that when you follow a URL in an email notification for a moved message, comment or files, you are redirected to its new location.
  • Ok, we gathered everything up and it’s moving. Is it done yet? Did it fail? We’ll need to roll it back if somthing goes wrong.

Oh and we need to show the user what’s going on…