← The complete build

BUILD 01 / LESSON 02 OF 06

Save the enquiry before calling AI

Learn server validation, persistent storage, concurrent writes, and safe retries in a small Node app.

OPEN THESE FILES

model.mjs · store.mjs · test.mjs

A success screen needs evidence behind it.

The browser sends name, email, message, and a request identifier to POST /api/enquiries. The server checks their types and lengths. The browser’s required fields help a person fill in the form, but the server must validate requests that bypass that form.

In this reference, the route waits for store.add before returning a receipt. The enquiry is saved before anyone asks for AI. A model timeout therefore cannot erase the original message.

Prove that storage survives a restart.

Submit a fictional enquiry and note its ID. Stop Node with Ctrl+C, start it again, sign in, and find that same ID. The default file is data/enquiries.json. Refreshing a page alone is a weaker check because an in-memory server could still be running.

npm test

The storage test also submits ten requests concurrently and reopens the file. Read how createStore serializes each complete update. It copies current records, changes the copy, writes a temporary file, and renames it before replacing the in-memory state. Serializing only the last write would still permit two updates to start from the same old records.

Retries should not duplicate the work.

The browser keeps the same requestId until a submission succeeds. A retry with the same ID and same content returns the original receipt. Reusing an ID with different content is rejected. Try this in a test rather than clicking quickly and assuming that no duplicates means the problem is solved.

This design supports one process and a small inbox. A shared production system needs a transactional database and a defined ownership model. Moving a JSON file into an ephemeral serverless function does not make the data durable.

Prove it before moving on.

  • The same receipt ID exists after a server restart.
  • Ten concurrent submissions produce ten records.
  • Retrying the same request returns the same receipt.

Use these as checks in your own app. This page does not store course progress.