# Moss Home USA: How Three Connected Automations Gave Three Key Employees Their Week Back

- Source: https://www.asgardtechnologiescompany.com/blog/moss-home-usa-operations-automation
- Publisher: Asgard Technologies (https://www.asgardtechnologiescompany.com)
- Author: Douglas Schwartz, Founder, Asgard Technologies
- Published: 2026-09-24
- Updated: 2026-09-25
- Topics: Automation, AI, Case Study, Operations

Case study: how Asgard Technologies built three connected production systems for Moss Home USA, a Los Angeles furniture manufacturer. The systems automated away a full week of work for three key employees. The CEO reassigned them, and that is letting the company grow the brand.

*TL;DR — Moss Home USA, a custom upholstery manufacturer in Los Angeles, runs three production systems built by Asgard Technologies: an hourly importer for genuine orders, an annual log of the quote-to-order lifecycle, and an AI-assisted decision engine on the support inbox. Together they automated away a full week of work for three key employees, who stayed and were reassigned to grow the brand. The language model interprets and drafts. Ordinary code still controls orders, inventory, pricing, and whether a reply is allowed to send.*

## Case study at a glance

| Item | Detail |
| --- | --- |
| **Client** | Moss Home USA, a custom upholstered furniture manufacturer in Los Angeles, California |
| **Engagement** | Asgard Technologies as the embedded engineering team for four-plus years, including the website |
| **Systems in this article** | 1. Master Open Order importer. 2. AMP Order Review Log sync. 3. Customer-service decision engine |
| **Data flow** | AMPtab ERP export to Smartsheet for orders and quotes. Gmail to n8n to a Next.js decision app, with Smartsheet lookups, for support email |
| **Schedule** | Hourly on Vercel Cron. The importer runs around the clock. The review log runs weekdays, 8:00 a.m. to 8:00 p.m. Pacific |
| **What AI does** | Classifies intent, extracts order numbers and fabric names from messy email, drafts replies from retrieved facts |
| **What code does** | Matching, deduplication, archive checks, field mapping, status rewriting, and every send permission |
| **What people do** | Cancellations, refunds, complaints, claims, fabric holds, shortages, and any case where the records conflict |
| **Outcome** | A full week of work automated away for three key employees. They stayed. The CEO reassigned them, which is letting the company grow the brand |
| **Stack** | Python 3, Smartsheet SDK, n8n, Next.js, Zod, Claude, Vercel |

## Who this case study is for

This write-up is for operators and owners of made-to-order businesses, and for the technical people who support them. It will be most useful if:

- Orders originate in an ERP or order system, but the working list the team actually uses lives in Smartsheet, Google Sheets, Airtable, or Excel.
- The same order can appear more than once over its life, as a quote, a confirmed order, and an archived order.
- A shared support inbox fields questions about status, stock, fabric, damage, and paperwork, and the answers live in three or four different places.
- You want AI to carry real work, but you are not willing to let it invent a ship date, a price, or a yardage number.

If that describes your operation, the three systems below are a pattern you can copy, with or without the same tools.

## The operating problem

Moss Home makes configurable upholstered furniture. A single order can carry a dealer, a purchase order, a discount, a territory manager, and several line items, each with its own SKU, price, and quantity. Quotes become genuine orders. Completed work moves into yearly archives. Customers write the support inbox about shipping, fabric, damage, and paperwork, often without a clean order number.

Staff were spending their days on the transfer itself. New orders had to be copied onto the operations sheet. Quotes had to be reconciled when they became confirmed orders. Support had to search several sheets before anyone could answer a routine question.

![A designer living room with a tailored sofa, the kind of configured piece behind each Moss Home order](https://images.unsplash.com/photo-1567016376408-0226e4d0c1ea?w=1400 "Configurable upholstery is the product. The operating problem is everything that has to stay attached to each order.")

Three facts made a simple point-to-point sync the wrong design.

1. The same order can show up as a quote, then as a genuine order, across more than one annual sheet. A naive import creates duplicates and stale rows.
2. A partial export or a missing archive can look like a healthy run and then reimport work that was already finished.
3. Customer email mixes easy questions with commitments. A fluent reply that invents a ship date, a dye lot, or a price is worse than a slow one.

The build had to get faster and get more conservative at the same time.

## What we refused to automate away

The rule for the whole engagement is simple. A language model may interpret a request and draft language. It may not be the source of truth for an order, a price, a yardage number, or a customer record.

| Kind of work | Who owns it |
| --- | --- |
| Matching records, deduplicating, mapping fields, checking archives, enforcing send permissions | Ordinary code |
| Classifying intent, pulling order numbers and fabric names out of messy email, drafting a reply from those facts | A language model |
| Cancellations, refunds, complaints, holds, shortages, and anything the records do not cleanly support | A person |

That split is why this is an AI-assisted operations layer, not an autonomous one. The sections below are the three systems in production. They are the ones that carry the day-to-day load.

## How the three systems connect

Each system has one trigger, reads from a defined set of sources, writes to one destination, and has a named point where a person takes over. None of them writes back to the ERP.

| System | Trigger | Reads | Writes | Where a person takes over |
| --- | --- | --- | --- | --- |
| Master Open Order importer | Vercel Cron, hourly, 24/7 | AMPtab CSV export, Master sheet, 2025 and 2026 archives | New rows on the Master Open Order sheet | When an archive cannot be verified, the run aborts and waits |
| Order Review Log sync | Vercel Cron, hourly, weekdays 8 a.m. to 8 p.m. Pacific | AMPtab quotes-and-orders export, yearly review sheets | Updated or inserted rows on the year's AMP Order Review Log | Never deletes, so a person can audit any row |
| Customer-service decision engine | New message in the support inbox, via n8n | Open orders, Basics sheet, yearly archives, BarCloud inventory, Fabric Master | A decision returned to n8n, an optional review queue, an optional audit table | Draft only, human review, and any closed send gate |

## 1. Master Open Order importer

This is the hourly order importer. It pulls orders from the AMPtab CMS and appends new line items to the Master Open Order sheet in Smartsheet. Anything already on that sheet, or on the 2025 or 2026 archive sheets, is skipped. Existing Master rows are not updated.

### What the importer does every hour

Each run follows the same path.

1. **Fetch.** Download the CSV export from AMPtab.
2. **Filter.** Keep only header rows whose status is Genuine Order. Quotes and other statuses are dropped, along with their line items.
3. **Combine.** Join each line item to its order header on order id, so one sheet row holds both the order (customer, PO, date, discount, rep) and the line (SKU, name, price, quantity).
4. **Sort.** Oldest first, by the source timestamp.
5. **Deduplicate.** The unique key is the AMP order number. If that number is already on the Master sheet or either archive, skip it.
6. **Write.** Append new rows to the bottom of the Master sheet in batches through the Smartsheet API.

### How the importer avoids reimporting completed orders

The safety control is the part worth copying. If either archive fails to load, is missing the order-number column, or returns zero keys, the sync aborts. A bad read must not reimport completed orders. The importer would rather wait an hour than invent a duplicate.

![A sculpted designer armchair, one configured piece among the line items the importer writes](https://images.unsplash.com/photo-1567538096630-e0c55bd6374c?w=1400 "Each line item stays tied to its order header. The importer does not update rows it has already written.")

Field mapping is fixed, not inferred:

- Order id, order date, dealer name, AMP order number, and customer PO
- Customer email and rep email, written as Smartsheet contact values rather than plain text
- SKU, item name, unit price, and quantity
- Discount percent, territory manager, and the manager's email

### How the importer runs

Vercel Cron calls the Python function every hour. The function can require a bearer secret. It is allowed up to 300 seconds. An optional business-hours gate can limit runs to weekday daytime in Los Angeles. That gate is off, so the job runs around the clock. The same core function can run locally in batches of 50 if the cloud path is down, with a written fallback runbook. Both paths share one sync function, so recovery is not a second product.

The stack is small on purpose: Python 3, requests for the CSV, the standard csv parser, and the Smartsheet Python SDK. Secrets and sheet ids live in environment variables. There is no database in this service.

## 2. Order review log

The second system is also a one-way sync from AMPtab into Smartsheet, with a different job. It maintains the quote-to-order lifecycle on sheets named AMP Order Review Log, one sheet per year.

### How a quote and its confirmed order become one row

On each run it:

1. Downloads the quotes-and-orders export.
2. Maps source columns onto the review schema: order number, dealer, PO, total, status, contact, and rep.
3. Drops rows with no AMP order number.
4. Deduplicates on that number, keeping the row with the most recent sales-order date. A later genuine order replaces an earlier quote instead of becoming a second entry.
5. Routes the row to the sheet for its sales-order year. A year without a mapping goes to a default sheet.
6. Looks up existing rows by AMP order number and either updates them or inserts new ones at the bottom.

Status labels are rewritten into Moss Home's operating terms: a quote becomes HFC, and a genuine order becomes Confirmed. Numeric order numbers are normalized so a leading zero does not create a second row for the same order.

### How the review log runs

The same shape as the importer: an hourly Vercel Cron job, a bearer check, and a weekday window from 8:00 a.m. to 8:00 p.m. Los Angeles time. The local fallback uses a file lock so two runs cannot overlap, and a lock older than 45 minutes is treated as stale so a hung process cannot block the next day. Older documentation describes a daily 9:00 a.m. job. The live path is the hourly function.

Runtime dependencies are requests, the Smartsheet SDK, and timezone data. There is no web UI.

## 3. The customer-service decision engine

The third system is the support inbox at Moss Home. An n8n workflow named Moss Home - CS Auto-Reply watches Gmail, labels a message immediately so it is not processed twice, and posts it to a Next.js app. The app does not send mail. Sending, labeling, and inbox polling stay in n8n. The app returns a decision. n8n routes on that decision: send a reply, forward a quote, label the thread for a person, or do nothing.

![An emerald velvet sofa, the kind of fabric decision the inbox has to answer from inventory records rather than from a guess](https://images.unsplash.com/photo-1555041469-a586c61ea9bc?w=1400 "Fabric answers come from inventory and the fabric master. Holds, care, and unresolved stock stay with a person.")

### How a support email becomes a decision

Inside the app, each message goes through a fixed sequence.

1. Clean the body, using HTML only as a fallback, and isolate the newest text from quoted history.
2. Skip mail that should not be answered: Moss system mailboxes, no-reply senders, thank-you-only follow-ups, threads a teammate is already handling, and mail where Moss is only copied.
3. Classify the sender from a contact-role registry: sales rep, employee, vendor, showroom or designer, end customer, or unknown.
4. Ask a language model for intent, order numbers, fabric names, and risk signals. Deterministic guards can override that classification.
5. Look up facts in Smartsheet and apply hard rules before any reply is allowed.
6. Return one decision.

### The six possible decisions

| Decision | What it means |
| --- | --- |
| Auto reply | Safe to send, and only if every send gate is open |
| Draft only | A draft exists, and a person must send it |
| Human review | Risky, incomplete, or outside the approved boundary |
| No reply | An acknowledgment, spam, or a thread the automation should stay out of |
| Ignore | A duplicate, a skip-list sender, or Moss Home's own outbound mail |
| Error | Processing failed. Nothing customer-facing happens |

### What the engine will and will not answer

**Order status.** Lookup is an exact match on AMP order number, customer PO, or invoice number, across open orders, the Basics sheet, and the yearly archives. Customer wording uses estimated shipping and estimated completion. Pending materials, cancelled orders, multiple matches, and missing tracking go to a person. When an order is found, the system does not ask for an order number it already has.

**New quotes.** A furniture quote request can be forwarded internally and acknowledged. A question about fabric price per yard is not treated as a furniture quote.

**Fabric.** Stock and availability can draw on BarCloud inventory and the Fabric Master, along with width, repeat, content, and care codes when those facts are actually on record. Holds, reservations, specifications, care, shortages, split dye lots, and unresolved stock stay with a person. The system will not email a mill or a warehouse on its own.

**Claims.** Product damage, freight damage, freight price, vendor quality, and general complaints are separated. A claims-form link is only for actual damage, and that URL comes from configuration, never from the body of the customer's email.

**Documents and changes.** A request to resend a receipt or invoice is checked against prior sent mail and held for review. The system does not invent a document. Cancellations, returns, refunds, and address changes are always human review.

### Why sending is fail-closed

A reply can leave only when dry-run is exactly off, automatic sending is exactly on, external sending is exactly on, and the intent is on the allowlist. The intended auto-send set is narrow: where-is-my-order, and new furniture quote requests. Closing any gate stops external mail. That is the shutdown switch.

Wording is linted before anything can be sent. Replies cannot say "scheduled to ship," cannot use em dashes, and cannot name the internal systems. Held cases can be written to a review queue, and each decision can be written to an audit table. If that database is not configured, the app still runs and simply skips the durable log.

The application is Next.js on Vercel, with Zod for validation. Extraction and drafting use Claude when an Anthropic key is set, and can fall back to another model by environment variable. Orders and fabric facts come from the Smartsheet API. Tests mock the model and Smartsheet.

The first version of this app was dry-run and order-status only. The current code classifies many more intents. It still refuses to send most of them.

## What changed for the team

Moss Home is not a three-person company, and this is not a story about replacing people.

The result is narrower than that. These three systems automated away the entire week's work of three key employees. The week they got back had been spent on the recurring administration the systems now cover: moving genuine orders and line items onto the operations sheet, reconciling quotes into confirmed orders, and searching several sources before answering routine support email.

Nobody was let go. With that week gone, the CEO had to find different work for those three people. That reassignment is what is letting Moss Home grow the brand. This write-up does not convert "a full week" into a guessed hours figure, and it does not claim a headcount reduction.

The quality of the record changed with it.

- New genuine orders land on a schedule, filtered, mapped, and skipped when they are already known.
- Quotes and confirmed orders keep a single latest row, routed to the right year, instead of a second entry every time the status changes.
- Support decisions are tied to current sheets. Unsupported or consequential requests become a visible review item instead of an improvised reply.
- Cloud schedules are the live path, and a written local fallback uses the same core logic if the cloud job is down.

![A finished high-end interior, which is the point of the operating layer: tracking the order should not compete with making the piece](https://images.unsplash.com/photo-1616486338812-3dadae4b4ace?w=1400 "The staffing result is a full week back for three key employees, reassigned to grow the brand. The control result is that sensitive cases still stop.")

## What we are not claiming yet

A case study is only useful if a reader can tell what was verified. These items are real production behavior, described above. These items are not in this article, because we will not publish a number we cannot defend:

- A monthly count of orders or support emails processed
- A precise hours-saved number beyond a full week for each of three key employees
- A claim that Moss Home is a three-person company, or that anyone was replaced
- A single go-live date for each system
- A claim that every supported intent sends with no human in the loop
- A claim that every adjacent tool in the broader Moss Home stack, including visual configuration, is in the same production state as these three

Duplicate protection and archive aborts are how the importer is built. They are controls, not a slogan that nothing has ever gone wrong. Fabric answers are grounded in inventory records and held when the facts are not clean. They are not advertised here as a universal under-a-minute promise.

## Glossary

Terms used in this case study, in the sense Moss Home and Asgard use them.

- **AMPtab.** The ERP and CMS where Moss Home orders and quotes originate. Both sync jobs read its CSV exports. Nothing in this article writes back to it.
- **Genuine Order.** AMPtab's status for a confirmed order. The importer keeps only header rows with this status.
- **HFC.** Moss Home's operating label for a quote on the review log. AMPtab quotes are rewritten to HFC, and genuine orders to Confirmed.
- **Master Open Order sheet.** The Smartsheet the operations team works from. One row per order line item. The importer appends to it and never edits existing rows.
- **AMP Order Review Log.** One Smartsheet per year holding the quote-to-order lifecycle, one row per AMP order number, kept current by the second sync.
- **Archive sheets.** Yearly Smartsheets of completed orders. The importer checks them before writing so finished work is never reimported.
- **Deduplication key.** The single field that decides whether a record is new. For both syncs it is the AMP order number.
- **Fail-closed.** A design where the system stops when it cannot verify an input, rather than proceeding on a guess. The importer aborts on a bad archive read. The inbox refuses to send when any gate is off.
- **Dry-run.** A mode where the decision engine does everything except send. It must be explicitly off before any customer email can leave.
- **Allowlist.** The short list of message intents that are permitted to auto-send. Today: where-is-my-order and new furniture quote requests.
- **Decision engine.** The Next.js application that receives a support email from n8n and returns exactly one decision. It never sends mail itself.
- **n8n.** The workflow tool that watches the Gmail inbox, labels messages, calls the decision engine, and performs the send, forward, or label that the decision calls for.
- **Dye lot.** A single production batch of a fabric. Yardage from two lots may not match in color, which is why split lots are held for a person.

## Why this pattern transfers

Most growing manufacturers already have the same shape of problem. Orders live in one system, the working list lives in a sheet, and the customer writes an inbox that knows neither. The work looks clerical until a duplicate ships, an archive gets reimported, or a confident email invents a dye lot.

The Moss Home build is a pattern for that shape. Deterministic jobs keep the operating record. A model reads unstructured language and drafts from retrieved facts. People keep the decisions that change money, commitments, inventory, or a customer's outcome. Each new intent has to earn a place on the allowlist. Until it does, the system drafts or stays quiet.

## Is this pattern a fit for your operation?

You do not need the same tools. You need the same shape of problem. The pattern is likely to fit if most of these are true:

- Your order system can export a CSV or expose an API, even if nobody on the team has ever used it.
- Someone keys orders, quotes, or line items into a sheet by hand, and the sheet is the list the team actually trusts.
- The same order changes status over its life, and today that creates a second row, a stale row, or a hunt through last year's tab.
- Completed work moves to an archive, and reimporting it would be costly or embarrassing.
- A shared inbox receives the same five questions in fifty different wordings, and the answers live in more than one system.
- You want a person, not a model, to keep the final word on cancellations, refunds, complaints, and inventory commitments.

The pattern is a poor fit if the working record and the source system are already the same thing, or if the volume is low enough that a human transfer costs a few minutes a week.

Asgard Technologies has been the engineering team on this engagement for four years, including the website. You can see the broader Moss Home work, including the design side, on our [flagship clients page](https://www.asgardtechnologiescompany.com/flagship-clients), and the service behind it on [automated systems](https://www.asgardtechnologiescompany.com/automated-systems). If you run a furniture or made-to-order business and the same three workloads are still manual, [tell us which one hurts](https://www.asgardtechnologiescompany.com/contact) and we will say honestly whether this pattern fits.

---

*Moss Home USA is a client of Asgard Technologies. This article describes production systems at the architecture level. It omits credentials, export URLs, sheet identifiers, and customer data.*

## Key takeaways

- Three production systems now cover genuine-order import, quote-to-order review, and support-email decisions
- The systems automated away a full week of work for three key employees. They stayed, and the CEO reassigned them to grow the brand
- Language models classify and draft. They do not own order, inventory, pricing, or customer records
- If an archive cannot be verified, the order importer aborts rather than risk reimporting completed work
- A customer reply can leave only when dry-run is off, send gates are open, and the intent is on an allowlist
- Complaints, holds, cancellations, refunds, and uncertain fabric facts stay with a person

## Frequently asked questions

### Is the Moss Home support inbox fully autonomous?

No. It is AI-assisted. The application classifies a message, looks up order and fabric facts, and returns a decision. n8n still polls the inbox and sends mail. A reply can leave only when dry-run is off, automatic sending is on, external sending is on, and the intent is on a short allowlist. Everything else is drafted for a person, held for review, or left unanswered.

### What happens if the order archive cannot be read?

The Master Open Order importer stops. If an archive sheet fails to load, is missing the order-number column, or returns no keys, the run aborts. Delaying new rows is safer than appending orders that may already have been completed.

### What happened to the three employees whose week was automated?

They stayed. Moss Home is not a three-person company, and nobody was replaced. The systems took the entire week those three key employees had been spending on recurring administration: moving genuine orders and line items onto the operations sheet, reconciling quotes into confirmed orders, and searching several sources before answering routine support email. With that week gone, the CEO had to find different work for them. That reassignment is what is letting the company grow the brand.

### Which decisions still require a person?

Cancellations, returns, refunds, and address changes. Complaints, claims, and freight issues. Fabric holds, reservations, specifications, care instructions, shortages, split dye lots, and unresolved availability. Multiple order matches, missing tracking, and any case where the records are incomplete or in conflict.

### What tools does the Moss Home automation stack use?

The two sync jobs are Python 3 functions on Vercel Cron using the requests library and the Smartsheet Python SDK, reading a CSV export from the AMPtab ERP and writing through the Smartsheet API. The support inbox is an n8n workflow watching Gmail plus a Next.js application on Vercel, validated with Zod, that calls Claude for classification and drafting and reads order and fabric facts from Smartsheet. Secrets and sheet identifiers live in environment variables.

### Does this pattern require AMPtab and Smartsheet?

No. The importer consumes a CSV export and writes rows through an API, so the source can be any ERP that exports orders and the destination can be any sheet or database with an API. What transfers is the set of controls: a single deduplication key, a check against completed work before writing, a fixed field mapping, and a job that aborts when it cannot verify its inputs.

### What is a fail-closed send gate?

A rule that a customer-facing email can only leave when every permission is explicitly on. At Moss Home a reply sends only when dry-run is off, automatic sending is on, external sending is on, and the message intent is on a short allowlist. If any one of those is missing, the system drafts for a person or stays silent. Turning off any single gate stops all outbound mail, which makes it the shutdown switch.

### How long has Asgard Technologies worked with Moss Home USA?

Asgard has been the embedded engineering team for Moss Home USA for more than four years. The engagement covers the website, brand and design work, the order-flow automations described here, and the AI-assisted customer-service layer. The three systems in this article are the ones that carry the daily operational load.


---

Canonical HTML version: https://www.asgardtechnologiescompany.com/blog/moss-home-usa-operations-automation
Contact Asgard Technologies: https://www.asgardtechnologiescompany.com/contact