Most content written about "AI automation" stays abstract — the flow diagram is generic, the node names are made up. In this post we do the opposite: we show the real node structure, the real field names and the real connections of a system we built ourselves. Customer data and credentials have been removed; everything else is taken as-is from the exported workflow JSON.

What Problem Does This Automation Solve?

If you want to manage a product catalog consistently across more than one interface — an admin panel, a chat interface, later on a mobile app — you need a single data source and standard endpoints that read from and write to it. In this system those endpoints were built as two separate n8n workflows; the data source is a Google Sheets table.

Overall Architecture of the System

The system consists of three separate n8n workflows:

  • Products Read Workflow — reads the product list.
  • Products Write Workflow — carries out adding, updating, changing stock, and deleting products.
  • AdminPanel Serve Workflow — serves the HTML interface of the admin panel.

All three use the same Products sheet in the same Google Sheets table; each product row has the fields product_id, product_name, category, skin_type, concern, ingredients, texture, usage_time, usage_order, price, url, stock, warning, variant_id. This is a representative cosmetics product set — not real customer data.

The Product-Reading Flow

The read side consists of three nodes: a Webhook (POST /products-read) receives the request, Get All Products — a Google Sheets node — reads the table, and a Respond node returns the result as JSON.

There's a point here worth being technically honest about: the Respond to Webhook node is configured with responseBody: {{ $json }}, and there is no Aggregate node in between. In n8n, Respond to Webhook returns whatever item reaches it first. So as it stands, this flow — despite the node being named "Get All Products" — in practice returns only the first row; if the intent is to return the whole list, an Aggregate node needs to be added in between. We're stating this as the current system's actual behavior, not as a flaw we're hiding.

Routing Operations With the Switch Node

The write side starts with a Switch node that looks at the action field in the body of the incoming request: {{ $json.body.action }}. This node has four outputs: add, update, update_stock, delete. What matters here: this is not an AI classification — there is no system "understanding" the incoming text. The Switch node simply compares the incoming value against four predefined strings and routes to the matching branch.

Adding, Updating, Changing Stock, and Deleting Products

The Switch node's four outputs connect to four separate Google Sheets nodes:

action valueNodeGoogle Sheets operation
addAdd Productappend (adds a new row)
updateUpdate Productupdate (updates all product fields)
update_stockUpdate Stockupdate, only the stock field, matched by product_id
deleteDelete Productdelete, removes the row filtered by product_id

What sets the update_stock branch apart from the others: it doesn't take the whole product object, only the product_id and stock fields — a deliberate design choice so that stock changes don't accidentally overwrite the rest of the product's information.

How the Admin Panel Connects

The admin panel interface is served through a separate webhook: the AdminPanel Serve Workflow is nothing more than a Webhook → Respond pair that responds to the incoming request with HTML content only; it doesn't perform any data operations itself.

Once the panel loads in the browser, its JavaScript sends fetch() requests directly to the /products-read and /products-write endpoints — we confirmed this from the request URLs inside the panel's HTML file. So the panel interface and the CRUD logic are two different layers: one serves the interface, the other two (the read/write workflows) carry out the actual data operations.

HTTP Responses and Operation Results

All four operation branches — add, update, change stock, delete — connect to the same Respond OK node. This node returns a fixed JSON that also includes the type of operation: {"success": true, "action": "..."} and an HTTP 200 status.

Read:
  Webhook (POST /products-read)
       ↓
  Get All Products (Google Sheets)
       ↓
  Respond (JSON — first item only)

Write:
  Webhook (POST /products-write)
       ↓
  Switch — body.action
       ├─ add          → Add Product (append)
       ├─ update       → Update Product (update)
       ├─ update_stock → Update Stock (update, stock field)
       └─ delete       → Delete Product (delete)
                                  ↓
                          Respond OK (JSON, HTTP 200)

There's an important limit here too: the Respond node only returns "the operation was triggered and didn't throw" — it isn't an error-handling mechanism on its own. If the Google Sheets operation fails, n8n's own error behavior kicks in — there's no separate error branch defined inside the flow.

Validation, Security and Error Handling for Production

It's worth not conflating what the current system does with what's recommended for a production environment:

  • What the current flow does: receives requests via webhook, routes conditionally by the action field, performs Google Sheets CRUD operations, returns a fixed JSON response.
  • What's recommended for production (not present in this system today): schema validation of incoming data, authentication/authorization checks, separate error branches for failed operations, operation logging, and a retry mechanism for transient failures.

Making this distinction clear when moving a prototype toward production matters for seeing the difference between "it works" and "it's reliable."

Adapting the Same Architecture to CRM, Booking, and Order Processes

The pattern here isn't specific to products: receive a request via webhook, split the operation type by a field (Switch), write to the relevant data source, and return a response from a single point. The same skeleton can be set up the same way for many record-based processes — updating a customer record, creating/cancelling an appointment, or changing an order status. What changes is the data source and field names, not the architecture.

If manual data transfer between products, stock, or different systems is happening in your business, we can look together at how to automate that process with n8n — see our n8n consulting page. For the bigger picture, you can also check our AI automation services.

Frequently Asked Questions

What does a Switch node do in n8n?
A Switch node routes incoming data to different outputs based on conditions you define. In this system it looks at the action field of the incoming request (add, update, update_stock, delete) and routes to one of four Google Sheets operations. This is not an AI classification — it is a conditional branch.
Does the Respond to Webhook node handle errors?
No. Respond to Webhook's job is to return a response to the incoming HTTP call; it does not perform validation, authorization or error handling on its own. In a production environment these functions need to be added with separate nodes (IF, Error Trigger, validation steps).
Can the same architecture be adapted to other processes?
Yes. The pattern of receiving a request via webhook, routing by an action field, and writing to a data source can be set up the same way for many record-based processes — CRM entries, appointment updates, or order status changes.