← 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.

Download source kit ↓

Run the app on a computer with Node.js 22.22+.

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.

CHECK YOUR UNDERSTANDING / LESSON 02

Can you explain the choice?

The AI request times out. Which result shows the save-first design worked?

Now prove it in your app.

Check these only after doing the work. The page cannot inspect your local app.

Pass the concept check and confirm all three hands-on checks to save your progress.