Doors.city
Doors marketplace + cost-controlled ad automation.
A Drupal commerce site for armoured and interior doors with a custom configurator, paired with a Symfony 7 Google Ads automation that runs cost-controlled Search campaigns against a single Ukrainian region. Target: CPC < 3 UAH, CPA < 120 UAH, zero wasted spend.
- Sector
- Commerce · Ukraine
- Stack
- Drupal 10 · React constructor · /sklad-export.json · Symfony 7.1 · PostgreSQL 16 · google-ads-php v18+ · Claude API · gtag.js · Hetzner CX22 · Ukrainian UI

- Door models
- 109
- Target CPC
- < 3 ₴
- Target CPA
- < 120 ₴
- Wasted spend
- 0
Marketplace + ad engine, wired together
Doors.city is a Drupal commerce site for armoured and interior doors with a custom configurator, delivery price grid, and a constructor (React) that lets buyers design a door before ordering. The catalogue exposes a `/sklad-export.json` feed for downstream tools.
On top of that catalogue sits a Symfony 7 Google Ads automation app that ingests the JSON feed, runs `KeywordPlanIdeaService` against the product names, generates campaign + ad-group + ad-copy candidates, and runs a nightly bid optimiser that pauses any keyword with ≥ 30 clicks and 0 conversions.
The goal isn't 'publish ads' — it's the lowest CPA achievable for one operator running one Ukrainian region. Manual CPC with a negative-keyword library beats PMax until you have ≥ 30 conversions/month to feed Target CPA.
Run profitable Google Search Ads for 109 product SKUs against one Ukrainian region without a paid marketer — and keep wasted spend (≥30 clicks, 0 conversions) at zero, automatically.
Drupal commerce + JSON product feed + Symfony 7 Google Ads orchestrator. Keyword Planner via google-ads-php, negative-keyword library, RSA ad copy generated by Claude API (operator confirms before publish), nightly bid optimiser, and gtag.js conversion tracking on the storefront.
Nine pieces holding it together
- 01
Drupal commerce catalogue
109 door models with full taxonomy (material, series, dimensions, price tiers, photos). PHP 8.3, MariaDB, multi-language ready.
- 02
Door configurator
React SPA mounted on the Drupal site lets buyers configure dimensions, finish, glass, and hardware before quoting. Shares Drupal taxonomy.
- 03
/sklad-export.json feed
Single endpoint exposes the full catalogue with incremental `?since=` deltas. Used by the Symfony orchestrator and Google Merchant Center (phase 3).
- 04
Symfony 7 ads orchestrator
PHP 8.3 + PostgreSQL 16 service running on a separate €4 Hetzner box. Multi-tenant data model: arbitrary Google Ads accounts × source feeds.
- 05
Keyword Analyzer UI
KeywordPlanIdeaService + GenerateKeywordHistoricalMetrics wrapped in an admin UI showing volume / CPC range / competition / trend per keyword, with curated list saves.
- 06
Negative-keyword library
Curated negatives ("дешево", "б/у", "ремонт", "фурнітура") + per-campaign overrides + auto-suggestions from wasted-spend search-term reports.
- 07
AI ad copy assistant
Claude API generates RSA headline/description candidates from product metadata. Operator picks from a shortlist; nothing publishes without confirmation.
- 08
Bid optimisation engine
Nightly rule runner: raise / lower / pause bids by CPA, ROAS, CTR, quality score. Wasted-spend killer: 30 clicks 0 conversions → auto-pause.
- 09
Conversion tracking
gtag.js on doors.city tracks phone clicks, form submits, and thank-you page views. Feeds back into Target CPA once volume crosses 30 conversions/mo.
Two boxes, one feed
doors.city runs on the existing Drupal host. The Google Ads automation is isolated on its own €4 Hetzner CX22 box so a Symfony deploy can't take the storefront down. PostgreSQL 16, gRPC via php-grpc to the Google Ads API v18+.
- Drupal 10
- Commerce catalogue · taxonomy · PHP 8.3
- React constructor
- Door configurator mounted on Drupal
- /sklad-export.json
- Incremental catalogue feed
- Symfony 7.1
- Google Ads orchestrator · Doctrine ORM
- PostgreSQL 16
- Campaign + product mirror
- google-ads-php v18+
- gRPC · Keyword Planner · Search Ads
- Claude API
- RSA copy candidate generation
- gtag.js
- Phone + form + thank-you conversions
- Hetzner CX22
- Dedicated €4/mo box · isolated from Drupal
- Ukrainian UI
- uk_UA everywhere · English in logs only
Need profitable ads on a tight catalogue?
Most Google Ads tooling assumes you have a marketing team and PMax-scale budgets. This stack is built for one operator and one region — the cheapest controllable format, automated where it doesn't break attribution.
Window Calculator Builder
Window price calculator and order builder

Let’s talk.
Tell us what you’re building. You’ll get a reply and a first estimate within 24 hours.
Fill in the brief →