The first seven movements answered "what to do." The eighth answers "how it runs day to day." The lead workflow, a Google Sheets report, and the unit economics of a four-studio network — on one continuous quarter of data. Every number in the report ties to a decision; numbers that move nothing are not here.
Process, report structure and four findings. Enough to see the approach
Twelve sections, four "analysis & growth points" blocks, the month read
The .xlsx (16 formula-driven sheets), 4 CSV extracts, an n8n workflow, a Dify prompt
All parameters from the LUMÉ Bible, not fitted. One source of truth across movements
A network of aesthetic-medicine studios in Kyiv. Fictional — like "Kontur" in movements I–VII, but operational projects need an organisation with an operational surface: several locations, contractors, ad accounts, a stream of enquiries worth systematising. A single studio doesn't need a CRM system — a network does.
_bible/model/params.py), not fittedEight stages. Each has a definition, an owner, an SLA and a metric it produces. Without this a "report" is just numbers with no meaning.
Contact from any channel: site form, Instagram Direct, comment, phone call, Telegram, lead-form ad. Source, UTM, campaign, studio and service of interest are captured.
metric: enquiry count, CPL by channelThe admin replied. SLA: ≤ 15 minutes in business hours. Movement III's benchmark — the ideal reply time is under ten minutes; the chance of contact falls a hundredfold at half an hour versus five minutes.
metric: first-response speed, % of enquiries inside SLAReal need established, budget in range, service exists in the network, client is target audience. Disqualification reasons are logged: out of geo · wrong service · price expectations out of range · spam / barter · "just asking" · contraindications → route to a doctor.
metric: contact→qualified, reason breakdownThe visit is in the booking system's calendar (EasyWeek). This is where the lead layer joins it by phone number.
metric: qualified→booked, time to bookingThe client showed up and paid. The opposite is a no-show or a cancellation with no reschedule.
metric: booked→showed, no-show, first-visit ticket, CACA second paid visit. The key churn point across the whole beauty industry.
metric: first-visit retention (target ≥ 45%), 1→2 intervalThree or more visits, or activity over 6+ months. Course packages, loyalty programme.
metric: repeat retention, frequency, LTV, share of revenueNo visit for 90+ days. A separate win-back campaign, a separate (low) CAC.
metric: dormant share, reactivation conversion1 · baseline
Keep everything in the booking system: bookings, client card, visit history all in one place.
2 · what's wrong
The booking system is a scheduler, not a lead CRM. An Instagram Direct enquiry that didn't turn into a booking doesn't exist in the scheduler — and that's more than half of all contacts. The whole top of the funnel is lost: reply speed, disqualification reasons, CPL by channel. "Where the client came from" is weak in a scheduler too — the "source" field is filled in by hand, by eye.
3 · senior level
A separate lead layer (a Google Sheet or a light CRM) that catches every contact with a full field set and UTMs. Joined to the booking system by phone number in a calculation layer. Reply speed is not "when someone remembered to ask" — it's a timer in n8n with auto-escalation. The client's source comes from the first enquiry's UTM, not the admin's memory.
4 · outcome
Two layers: a lead layer (contacts, separate) + the booking system (bookings and visits, separate), joined by phone. The report reads both. That's exactly how LUMÉ's dataset is built.
On the left — the whole funnel (including walk-ins and referrals). On the right — paid traffic only: that's how ad performance is judged.
2,395 enquiries in the quarter. Numbers from raw_leads.csv, recomputed by formulas in DASH_funnel.
The main leak is at the entrance, not inside. 6.6% of enquiries (159 of 2,395) were never answered at all; more were handled past SLA. Every stage after that works fine: contact→qualification 75%, booking→visit 86%. The cheapest thing to fix is not the salesperson's conversion — it's the admin's speed.
Paid traffic converts worse than the blended figure — 31.4% vs 40.4%. The difference is that the overall funnel includes walk-ins and referrals: they arrive with ready intent and book almost immediately. Mixing them with ad leads means flattering the ads.
1 · baseline
One funnel across all sources, one lead→client conversion.
2 · what's wrong
Walk-ins and referrals artificially raise the overall conversion and hide the paid-channel problem. A budget decision made on the blended figure will be systematically wrong.
3 · senior level
Two slices: the full funnel — for operational management of the studios; the paid slice — for ad decisions. In LUMÉ's report these are separate blocks in DASH_funnel. Plus a third cut — by studio, to localise the drop.
4 · outcome
Paid-traffic conversion of 31.4% is the number CAC is tied to. Blended 40.4% shows next to it but plays no part in channel decisions.
contact→qualified by studio
| Studio | contact→qual | What it means |
|---|---|---|
| Pechersk | 77.3% | normal |
| Podil | 80.8% | normal |
| Pozniaky | 78.4% | normal |
| Obolon | 64.0% | new admin since April → script review and training |
The network loses ≈ 80 qualified enquiries per quarter on this gap alone. At an average ticket of ₴4,031 that's ≈ ₴200K of missed revenue per quarter at one studio. Not a "metric" — an address: studio, month, person.
A professional Google Sheets report is not "a pretty dashboard" — it's the separation of input, calculation and display. lume_q2_2026.xlsx is built exactly this way.
| Layer | Sheets | What it does |
|---|---|---|
| RAW | raw_leads · raw_spend · raw_bookings · raw_calls · dict_* | Data as it comes from sources. Append-only. Never edited by hand — replaced wholesale by a new extract. |
| CALC | lead ↔ visit join by phone, helper columns | All the "magic" of joining sources. Separated from the display so it can be checked. |
| DASH | daily · funnel · unit · channels · cohorts · speed | Dashboards on SUMIFS/COUNTIFS formulas over RAW. Substituting a new extract recomputes everything. |
| META | metrics · data_quality | Metric dictionary and data-quality checks. Run before every stand-up. |
1 · baseline
One "Report" tab: summary on top, the data typed into it by hand below.
2 · what's wrong
Input is mixed with display. Any format edit breaks the formulas. History can't be recovered. Two people can't work at once. Replacing a month means rewriting everything — and the errors aren't visible.
3 · senior level
RAW only accepts data (one row = one lead / one spend day / one visit). CALC joins. DASH only displays and never stores. Every metric in DASH is a formula referencing RAW, not a hand-typed number. Checkability over prettiness.
4 · outcome
A new month = replace three CSVs in RAW. The whole report rebuilds itself. A data error surfaces on the data_quality sheet, not a quarter later in the conclusions.
A metric with no decision attached is decoration, and it doesn't go into the report. Full version — the META_metrics sheet (16 metrics with formulas, sources and owners). Eight key ones here.
| Metric | Formula | Target | Which decision it moves |
|---|---|---|---|
| Reply speed | med(contacted − created) | < 10 min | admin headcount, shifts, auto-reply, routing |
| contact→qualified | qual / contacted | 78–82% | traffic quality, qualification script, training |
| CAC (paid) | paid_spend / new_paid | < ₴1,500 | budget split between channels and retention |
| LTV (gross profit) | (ticket₁ + ticket₂·Σ)·margin | > ₴15,000 | retention, average ticket, course upsell |
| LTV / CAC | LTV_gp / CAC_paid | ≥ 4 | scale acquisition or invest in retention |
| payback on 1st visit | (ticket₁·margin) / CAC | > 100% | composition and price of the first-visit offer |
| first-visit retention | 2nd visit ≤ 90d / cohort | ≥ 45% | follow-up, "book in the chair", welcome sequence |
| schedule utilisation | visits_mo / capacity | 65–80% | hiring practitioners, hours, flow distribution |
A typical LUMÉ client's path: saw an Instagram ad → followed → came six weeks later on a promo in the Telegram channel. Who gets credit for the client?
1 · baseline
Last-touch, as GA4 defaults: the client goes to the last touch.
2 · what's wrong
On a six-week cycle, last-touch hands almost all clients to retargeting and the promo blast, and top-of-funnel acquisition looks unprofitable. The logical next step is to cut the Instagram budget — i.e. cut off your own oxygen.
3 · senior level
First-touch by acquisition channel — the channel that first brought the client into view gets the new client. Repeat visits are attributed to advertising nowhere: retention earned them. Promos are measured separately — by increment to the base, not by "clients from the mailout."
4 · outcome
In LUMÉ's dataset source_channel = the first enquiry's channel. This makes Instagram's CAC honestly high rather than artificially low, and stops acquisition cost from hiding in "free" repeat visits.
CAC is computed here — from raw_spend and raw_leads. LTV and LTV/CAC come from the LUMÉ Bible (_bible/figures.json) — a two-segment cohort model on real Slim prices and retention.
The first visit's gross profit (~₴1,040) is less than the acquisition cost (₴1,817). The first visit is for a consultation and light procedures, a lower ticket. The client has to come back at least once for acquisition to break even. LUMÉ's economics rest not on the first visit but on retention.
LTV/CAC of 9.8× (Bible v0.6) says acquisition is efficient — but it's not permission to pour in budget. Network utilisation is 76% (Section X): the chairs are nearly full. Growth now needs either capacity (the fifth studio is opening) or a higher ticket — upsell into courses, a shift toward injectables.
₴1,817 is the ad-account figure, ₴1,806 is the accountant's figure. The gap is small: the reverse-charge VAT on non-resident advertising is neutral for a VAT payer (output = input). The model used to keep a "non-resident advertising tax" of +20% here, but it was repealed back in 2022 (Law No. 1525-IX) — see movement XII.
1 · baseline
Compute LTV right in the metrics report: ticket × number of visits in the quarter.
2 · what's wrong
A quarterly slice has no full client history, no retention, no horizon. LTV from a quarter isn't LTV — it's "revenue over 90 days." CAC decisions on that number are wrong.
3 · senior level
LTV lives in the company Bible — a two-segment cohort model there (42% of new clients → regulars, 70%/yr retention, 5-year horizon), cross-checked against the source "regular client ₴30–100K/yr." The operational report takes LTV as a constant and computes CAC, payback, ROMI from it. One source of truth.
4 · outcome
CAC ₴1,817 (account) ≈ ₴1,806 (P&L) ÷ LTV ₴17,742 (Bible) = LTV/CAC 9.8×. Payback on the first visit ~57% (on the lower first-visit ticket) → retention isn't "nice to have," it's a required condition.
ROMI here is on an LTV projection: gross profit of the cohort acquired in the quarter over an 18-month horizon, divided by spend. Not a monthly ROAS.
| Channel | Spend ₴ | Leads | CPL ₴ | Clients | CAC ₴ | ROMI |
|---|---|---|---|---|---|---|
| Meta (paid social) | 405,600 | 653 | 621 | 201 | 2,018 | 7.8× |
| Google Ads | 148,700 | 310 | 480 | 107 | 1,390 | 11.8× |
| Influencers / seeding | 121,894 | 221 | 552 | 64 | 1,905 | 8.3× |
| Referrals | 60,300 | 403 | — | 201 | 300 | 58.3× |
| Instagram organic | 0* | 389 | — | 137 | ≈ 0 | — |
| Offline / direct | 0 | 419 | — | 257 | ≈ 0 | — |
* content spend is booked to movement VI (content system), not this channel's CAC. Referrals: a ₴300 reward per referred client. CPL and CAC here are on ad-account spend; the reverse-charge VAT on non-resident advertising is neutral for a VAT payer; the "non-resident advertising tax" no longer exists (repealed 2022, Law No. 1525-IX) — see movement XII.
Meta takes 60% of the paid budget at the worst ROMI among paid channels. That doesn't mean "switch it off" — Meta delivers volume (201 clients, the most of any paid channel) and top-of-funnel for the rest. But the ratio can be improved.
Google works better on efficiency (CAC ₴1,390 vs ₴2,018 on Meta, ROMI 11.8×), but Google Trends shows category search for cosmetology falling 40–60% over five years (see Bible). Google can only be scaled on brand and specific procedures ("botox kyiv" +10%), not on generic queries.
Referrals are the cheapest client in the network (₴300), 201 clients per quarter, 58× ROMI. And no one manages them: there's no "refer a friend" programme, the reward is paid ad hoc. This is a channel that deserves a product, not handouts.
Instagram organic — 137 clients for free. For the competitors (Lazerhouse 207K, Lumenis 245K followers) it's the main channel. LUMÉ, at ~20K followers, under-invests in content.
From 1 June — a ₴300 prepayment when booking from a paid channel (credited toward the visit price). The DASH_deposit sheet computes no-show before and after.
Every no-show on a paid-channel booking is a paid lead (₴550 on average), carried all the way to the chair and lost at the last step. At 17% no-show and ~300 paid bookings a month the network loses ~50 visits, ~₴180K of revenue.
The ₴300 deposit cut no-show to 10.5% — below the source corridor (Ukrainian beauty salons: 18–20% with no prepayment, ~15% with a non-refundable one). Not "to zero" — some clients still don't come and forfeit the deposit. But −6.5 pp in a month on one mechanic pays for itself many times over.
Stand-up decision: roll the deposit out to all paid channels from July. Not for organic and referrals: no-show there is already lower and a deposit would kill booking conversion.
The 11-minute median looks tolerable, but it hides the tail: 37% of enquiries wait longer than 15 minutes, 6.7% never get an answer. Per movement III's research, at half an hour versus five minutes the chance of contact falls a hundredfold. Every unanswered enquiry is a paid lead (₴550 on average on paid channels) thrown away in silence.
This isn't a motivation problem, it's a system problem. The fix is not "ask the admins to reply faster" but: an auto-reply in the first minute with qualifying questions, routing the enquiry to the right studio, a timer that escalates to the manager after 15 minutes. All of this is the n8n workflow from Section XII, which on LUMÉ's data takes SLA compliance from 62% to a target 85%+.
| Studio | Utilisation | What it means |
|---|---|---|
| Pechersk | 79% | at the ceiling |
| Podil | 78% | at the ceiling |
| Pozniaky | 76% | at the ceiling |
| Obolon | 70% | the only slack in the network — but partly from weak qualification (Section II) |
| Network | 76% | physical capacity 1,920 visits/mo, ~1,454 flow through |
This echoes movement VII (the calculator): there the chair was the growth ceiling for a single clinic. Here a four-studio network has reached the same ceiling — 76%. The healthy utilisation band is 65–80%, and three of four studios sit in its top third (76–79%). The only slack left is Obolon, and part of that comes from weak qualification.
Conclusion for the stand-up: there's almost nowhere to raise the ad budget on the existing 4 studios — new bookings crowd out repeats, and no-show rises from an overfull schedule. Growth comes from: the fifth studio (opening, will absorb some demand), upsell into courses (higher ticket on the same slot), fixing Obolon (69% → 76% = +₴1.7M/yr).
The one channel still worth pouring budget into at full utilisation is referrals: they bring clients who book a specific time and barely no-show.
The META_data_quality sheet — seven checks run before every stand-up. A red result blocks conclusions on that channel until the cause is found.
A real incident from the dataset
2.0% of the quarter's enquiries (47 of 2,395) — with a broken UTM tag. All Google Ads, the "services" and PMax campaigns, from 1 to 24 June. On a campaign relaunch a space got into utm_campaign (kyiv smas instead of lume_net_services_lead_2026q2). GA4 split the tag, 50 leads fell into the "(not set)" source.
Consequence if unnoticed: Google looks worse for June than it is; the stand-up hears "Google dropped, cut the budget" — and the best channel by ROMI gets cut.
What worked: the "utm_campaign not to standard" check on data_quality showed 47 instead of 0. The tag was fixed, 47 leads re-attributed by hand via gclid, a UTM template added in the ad account. The naming rule lives in dict_utm_rules. The spec grew into movement XI.
An honest column. The infrastructure (n8n, Dify) is up; the workflows are written and import-ready; connecting to live ad accounts and the booking system needs the owner's access. n8n_lead_intake.json — 26 nodes.
| Automation | What it does | Status |
|---|---|---|
| n8n · lead intake | enquiry webhook → instant acknowledgement → normalisation: E.164 phone, all click IDs (gclid/fbclid/…), channel by rules, value_tier, dedupe key → per-client history → first/last-touch attribution, SLA deadline on Kyiv business hours → append with dedupe → card to the admin → escalation to the manager on a timer | JSON import-ready |
| n8n · dead-letter + doctor + data control | same workflow: write failed → dead_letter + alert; hot lead → to the doctor; broken UTM → to the data-control chat before the lead spoils the stats | part of the workflow |
| n8n · lead digest | Mon–Sat 09:00: yesterday + week-to-date + pace against plan, top channels/campaigns, "not contacted: N" — only what needs action | part of the workflow |
| Dify · weekly narrative | input — JSON from DASH_funnel and DASH_channels; output — text: "what changed, where the bottleneck is, three recommendations" | prompt ready |
| EasyWeek → Google Sheets | daily export of visits into raw_bookings | needs an EasyWeek API key |
| Ad accounts → Google Sheets | daily spend by campaign into raw_spend | needs Meta / Google Ads access |
The n8n workflow is written so a non-developer can explain it: each node does one clear thing. The "what this is, why, what to watch" walkthrough is in automation/SETUP.md. Anything requiring someone else's keys is flagged red and not passed off as done. An overview of all five workflows (107 nodes) is on a separate page.
The report isn't there to "keep you informed" — it's there so a concrete action comes out every week. Full version — worked_month.md.
1 · Deposit on paid-channel bookings. No-show on paid traffic held at 16.8%. From 1 June — a ₴300 prepayment, credited toward the visit price. By month's end no-show on those bookings — 10.5% (within the source corridor for beauty with prepayment). Decision: roll the deposit out to all paid channels from July.
2 · Broken UTM in Google (Section XI). Caught 24 June, fixed, channel re-attributed. Decision: a UTM template in the ad account + the data_quality check is mandatory before the stand-up.
3 · Obolon. contact→qualified 64% vs 77–81% at the other studios, the whole quarter. Cause — a new admin without a settled script. Plus studio utilisation below the network (70% vs 76–79%). Decision: review ten call recordings, a qualification script, re-measure in a month.
4 · Utilisation at the ceiling. The network at 76%, three of four studios at 76–79%. There's nowhere to raise the ad budget: new bookings crowd out repeats. Decision: priority — upsell into courses (higher ticket on the same slot) and preparing the fifth studio, not raising CPL budget.
5 · The split and referrals. Google ROMI 11.8× vs Meta 7.8×, but category search is falling (Trends) — grow only on brand. Referrals: 201 clients per quarter at a CAC of ₴300, no one manages them. Decision: formalise the referral programme (₴300 bonus to both sides, a promo code) — it's the one channel worth growing at full utilisation.
The data is synthetic, the parameters are real. The dataset is generated by a deterministic model (build_dataset.py, seed 2026), but all economic parameters are imported from the LUMÉ Bible (_bible/model/params.py): prices from Slim, Ukrainian advertising 2026, no-show, retention. There is no separate "fitting" to corridors any more — there's one source of truth. No real LUMÉ entity exists.
CPL is the weakest point (grade C). Meta CPL ₴620 — the one UA anchor is Rabbit Marketing "beauty/health 200–600 ₴/lead" (09.2026); the exact ad-account number is unconfirmed. CAC ₴1,817 (account) ≈ ₴1,806 (P&L), LTV/CAC 9.8×. At a conservative CPL of $18–22 — ~6–7×.
Attribution is simplified to one-touch. The real path is multi-channel; first-touch by channel is a deliberate trade in favour of checkability over precision.
LTV isn't computed here. It's in the Bible — a two-segment cohort model on a 5-year horizon, cross-checked against a source. The operational report takes it as a constant. That's correct: LTV from a quarterly slice isn't LTV.
The .xlsx formulas are a working pattern, not production. Dashboards on SUMIFS/COUNTIFS over RAW; substituting a new extract recomputes them. Some data-quality checks need manual setup in Google Sheets.