Skip to content
Case study · 2of 05
All work

Hemijska čistiona Elegant

Dry cleaningNovi Sad, Serbia

A 207-item Excel price list became a live estimate with a ready date, before the customer books a pickup.

Status

Pre-launch · in final fixes

Services

  • Website · Pricing & internal tools · Booking & orders · Lead pipeline & CRM

Year

2026

Results

Not measured yet.

Elegant dry cleaning website, home page with the pickup call to action
01Before

The problem

Every order started as a DM or a phone call. Customers couldn't learn a price or a ready date without asking a person, and pickups were arranged one message at a time. The price list lived in Excel, with turnaround times hidden in cell colours.

02Build

What we built

    1. A one-page site with the order form as the second section, so Instagram visitors reach it at once.
    2. The full price list, 207 items in 19 categories, as searchable HTML with an Add button on every row.
    3. A 4-step order: items, pickup, contact, review, with a live estimate and ready date as you go.
    4. Pickup days limited to valid working days, with three time windows to choose from.
    5. A request number on every order, and an email that says received, never confirmed.
    6. A Google Sheet with six tabs: orders, order lines, prices, settings, error log and live statistics.
    7. The owner edits prices, turnaround, holidays and time windows in the sheet. No developer.
    8. The driver filters tomorrow's pickups straight from the sheet: address, floor, window, items.
    03Flow

    How it works

    The flow end to end, as the system is built to run. Sheet and status names are the client's own.

    10 steps · 1 sheet

      1. Instagram link
      2. Pick items from 207
      3. Live estimate + ready date
      4. Pickup day and window
      5. Contact and consent
      6. Server re-prices the order
      7. ORDERS · NOVO
      8. Shop and customer email
      9. Shop confirms by phone
      10. Driver's round
      04Engineering

      Under the hood

      The details a developer checks first. Most of them exist so an inquiry is never lost or sent twice.

        1. One engine computes the customer's estimate and the stored total, so they can't drift apart.
        2. The browser never sends prices. The server re-prices every order from its own price sheet.
        3. Turnaround was hidden in Excel cell colours. The build decodes them and refuses to run on an unknown colour.
        4. All 207 items reconciled against the client's PDF: codes, names and prices, zero conflicts.
        5. The daily cutoff runs on the shop's clock in Belgrade time, not the customer's phone.
        6. Duplicate check, five orders per phone per hour, one write lock and a formula-injection guard on every cell.
        7. Orders are posted as plain text on purpose, to skip a CORS preflight Apps Script can't answer.
        8. A one-line switch moves orders to the shop's own software later. The API contract is already written.

        Stack

        What it runs on.

        • HTML · CSS · ES modules · Google Apps Script · Google Sheets · MailApp · Python · Node test runner
        05QA

        Build QA

        From our own test runs before launch. These are build numbers, not business results.

          • 128 automated tests passing, 0 failing. Backend tests run the real Apps Script code.
          • 27 of 28 cases from the brief pass. The 28th needs an API that doesn't exist yet.
          • Browser estimate and server total identical on an end-to-end test order.
          • WCAG AA contrast across 1,178 elements, 0 failures, in light and dark mode.
          • 0 horizontal overflow at 12 widths, from 320 to 1920 px.
          • Local page metrics: CLS 0.0000, 0 long tasks, 17 requests.
          • Six independent reviewers raised 25 candidate defects, including critical timezone and colour-decoding bugs, which were fixed.
          06Scope

          What we didn't build, on purpose

          Scope is a decision. Every line here was decided, not forgotten.

            • No second operational system. The shop already runs its own software, so the site is an intake layer that plugs into it later.
            • No confirmed appointments online. The customer sends a request, and the shop confirms by phone.
            • No stock photos. The shop had none of its own, and stock would mislead.
            • No guessed facts. Hours, branches and numbers stay hidden until the client confirms them.
            • No cookie banner. Analytics is wired in and switched off.
            07Screens

            The build

            Captured from our local pre-launch build. Phone numbers, email addresses, prices and photos of people from the client's site are blurred wherever they appear.

            →Next step

            Let's map your system.