Best approach for creating an attachment for a new record?

I want to allow my app to accept file attachments for records that I save in my db.

For currently existing records, I use Uppy + Transloadit and I set custom fields on the Transloadit plugin to associate the upload with my record. Then I can either use Transloadit’s async notifications API or a client callback to modify the record in my db with a reference to the uploaded file.

But what’s a good approach for new records?

If you imagine a form for creating a new record and a button for attaching files, with Uppy’s design, the user will end up uploading a file before the new record is created. How can I associate the uploaded file with the record that has yet to be created?

One idea would be to use a callback to add the uploaded file’s URL or some other reference to the form as a hidden field. But what happens if the user abandons the form? Then I’ve got a random orphaned file sitting on S3.

Another idea would be to have Transloadit send a notification to my app and also have Uppy add the file id in a callback to my form. My app stores the file id received from the notification and marks it as pending and waits for the form to submit the same file id. If it receives the file id in the form, it associates the file with the new record and removes the “pending” designation. If after a while (maybe using a cron job) the app doesn’t see any submission with that file id, it deletes it from S3. This sounds…painful to set up for an MVP, although it might be the most robust solution.

I looked in the docs for some way to delay the upload and manually trigger it later, but I wasn’t able to find it. Not to mention that the idea of posting a form with my record’s info then doing a separate upload to a third-party service at the same time all inside of the user’s browser feels…icky. There’s no guarantee of atomicity, one could fail and the other could succeed, again leading to either an orphaned record or an orphaned attachment.

How would you approach this?