DEV Community

Miran
Miran

Posted on

The Moment an Email Template Needs Its Own Data Model

A document request stops being reusable copy once the next reminder depends on which files were uploaded, reviewed, rejected, or marked not applicable.

A static email requesting five client documents beside a tracked request system showing each document with a different status: missing, pending review, rejected, received elsewhere, or not applicable

A reminder email can be perfectly written and still be wrong.

Imagine asking a client for five files. One is still missing, one is waiting for review, one was rejected, one was received elsewhere, and one was marked not applicable.

Sending the original request again would ask for all five.

The wording did not fail. The email simply has no memory of what happened after it was sent.

A template stores language, not progress

An email template is useful because it keeps the request clear and consistent. It can include the client name, reporting period, document list, due date, and upload instructions.

For a small one-off request, that may be all the structure needed.

Someone sends the message, the client replies with a file, and the same person closes the loop. There is little value in building a separate request record when one person can understand the situation by opening the thread.

The limitation appears when the next message depends on events that happened after the first one.

The template still contains the original document list. It does not know that a bank statement arrived yesterday, that a payroll report was rejected because it covered the wrong period, or that a sales export does not apply to this client.

That information may exist somewhere in the inbox, but it does not exist in a form the application can reliably use.

The requested items need to become records

Once each document can move independently, the request cannot be represented by one email-level status.

A single label such as open is not enough when the items inside the request are in different conditions:

  • The bank statement is still missing.
  • The receipt archive has been uploaded but not reviewed.
  • The payroll report was rejected and needs another file.
  • The sales report was received through another channel.
  • The inventory document does not apply.

For a first version, I would not start with a large rules engine. I would start with enough item-level data to answer one practical question:

What still requires action from the client?

A simplified item might look like this:

{
  "name": "June bank statement",
  "status": "client_action_required",
  "due_date": "2026-07-25"
}
Enter fullscreen mode Exit fullscreen mode

Another uploaded item might use pending_review. A rejected file could return to a client-action status while also keeping the rejection note. An item marked received_elsewhere or not_applicable should no longer appear in the next reminder.

The exact labels can change. The important part is that each requested item has its own durable result instead of relying on someone to reconstruct the result from an email thread.

Reminder text should be an output

This changes the role of the email template.

The template still controls the tone and structure of the message. It can decide how the greeting works, how the deadline is explained, and whether the reminder sounds firm or friendly.

But the document list should come from the current request data.

In rough terms, the reminder becomes something like:

const reminderItems = items.filter(
  (item) => item.requiresClientAction
);
Enter fullscreen mode Exit fullscreen mode

That filter should exclude an upload that is waiting for internal review. It should also exclude an item the team already accepted or marked not applicable.

A rejected upload is different. The client may need to act again, but the reminder should explain what was wrong rather than quietly placing the document back into the original list.

This is why “send another reminder” is not just an email action. It is a query against the current request.

The message is generated from the record. The message is no longer the record itself.

The handoff test makes the boundary clearer

There is a simple way to decide whether the extra data model is justified.

Could another team member take over the request without reading the entire email thread?

For a request involving one missing file, the answer may not matter. The same person can send, follow up, review the attachment, and finish the work.

For a recurring monthly request with statements, receipts, payroll reports, sales exports, and review questions, the answer matters much more. A reviewer should be able to see what arrived. A preparer should know which files are still missing. A manager should not have to compare several email replies before deciding whether another reminder is appropriate.

That became the dividing line in the client document requests vs email templates decision guide I added.

Templates improve the request itself. A tracked request preserves what happened after the request left the inbox.

Use the lightest structure that survives the next action

Not every client document request needs software.

When the next action is simply sending one clear message, a reusable email template may be the better choice. It is faster, familiar, and does not create another place for the team to maintain.

The threshold changes when the next action depends on previous events.

If a reminder must include only unresolved files, if an upload needs review before it counts as received, or if another person may take over the follow-up, the application needs something more durable than the last email.

At that point, the useful question is no longer “How should this message be written?”

It is “What does the system currently know about each requested item?”

Once the next reminder must ask for only the remaining bank statement, the request record—not the original email—should decide what gets sent.

Top comments (0)