Three months ago I started with one B&B website and a vague idea that the owners needed more than a booking page. Today I’m running automated digital operations for nine B&Bs across Taiwan — five websites, automated weekly reports landing in owners’ inboxes every Monday, and a Google Ads health check system analyzing keyword performance.
This is a retrospective on how that happened, and what I learned about building at this scale alone.
The Starting Problem
Taiwanese B&Bs compete in a strange market. The big OTA platforms — Booking.com, Agoda — bring traffic, but collect commission rates that are higher than most people realize. Most small B&B owners knew this was a problem, but the trap is deeper than it looks: OTAs don’t just have a website — they have three compounding advantages. Massive advertising budgets running across every channel. Years of accumulated brand trust with travelers. Professional digital and marketing teams working full-time to optimize everything.
Even if an owner pays a web agency for a brochure site, that site goes nowhere without ads, without SEO, without any way to track what’s working. It exists, but nobody finds it.
The real problem wasn’t the absence of a website. It was the absence of an entire digital operation: a site that actually ranks in search, reports the owners can act on without learning new tools, and ad spend they can justify — without hiring a marketing team they couldn’t afford.
That’s the stack I ended up building.
Five Websites, Nine B&Bs
The first thing I had to solve was deployment. Some properties are single-location, some are small chains with two or three units under one brand. Five repositories ended up covering nine properties.
One property — Firebase Hosting, static output. A single-location property that didn’t need any server-side logic. Fast, zero maintenance cost, Cloudflare in front for CDN.
The other four — Railway with SSR. Properties that needed room availability, dynamic pricing display, or other content that couldn’t be pre-rendered. Railway handles the Node.js runtime; Cloudflare sits in front for caching and DDoS protection.
The tech choice was Astro 6 + Tailwind v4 across the board. Astro’s island architecture meant I could ship mostly-static pages with interactive components only where needed. Tailwind v4 was a significant rewrite from v3 — no more tailwind.config.js, everything in CSS. It took a day to internalize, then it was faster than v3 for actual development.
The other thing I built was a content admin panel backed by GitHub’s REST API. B&B owners needed to update room descriptions, pricing, and photos without calling me. A CMS like Contentful or Sanity would have meant teaching them a new tool. The GitHub API approach gave them a custom form that wrote directly to the repo — commit history became the audit log, CI handled the rebuild.
Layer Two: Making GA4 Actually Useful
Every one of these properties had GA4 installed. None of the owners actually used it.
This is a common pattern with small businesses and analytics tools. The data is there. The dashboard is there. But opening GA4, navigating to the right report, remembering what last week’s numbers were, and translating that into a decision — that’s too much friction for someone whose job is running a B&B, not reading analytics.
The fix was an automated TypeScript analytics system that runs every Monday morning, pulls GA4 data via the Data API, normalizes it with week-over-week and month-over-month deltas already computed, then sends it to Claude with the property’s business context.
The business context is the key part. Each property has a business-context.md file that describes the property’s peak seasons, key conversion events, what the owner actually cares about, and local context (nearby festivals, holiday patterns specific to that region). Claude reads this alongside the normalized numbers and produces a report that says things like: “Organic search is down 15% this week, which is consistent with the Dragon Boat Festival weekend — paid traffic held steady, so this isn’t a campaign problem.”
The owners receive this as a formatted Chinese report every Monday. No login required. No dashboard to interpret. The question shifts from “what happened?” to “what do I do about it?” — which is a much easier conversation.
Layer Three: Google Ads Without a Marketing Team
The ads problem was different. Owners were running Google Ads — some spending NT$30,000–50,000 a month — with no systematic way to evaluate what was working. Keyword decisions were made by gut feel or not made at all.
The ads health check system is a Python system that pulls keyword performance data from the Google Ads API weekly, sends it to Claude for analysis, and produces structured output: which keywords to add, which to remove, which to monitor. The output goes to a Google Sheets inventory — each keyword has a row with its status (Active or Removed), the date it was added, and the reason for any decision.
The Sheets choice was deliberate. I could have used a database. But a database means the data lives somewhere only I can see. Sheets means the owner can open it, scroll through, understand the history of every keyword decision. The system feels like theirs, not a black box Wayne controls.
One rule I built in: a 14-day protection period on newly added keywords. If a keyword has been running for less than two weeks, there’s not enough data to evaluate it — Claude would be making noise into a recommendation. The protection period filters that out.
What This Required
The obvious answer is “good tools and AI.” But that undersells the actual challenge.
The engineering problems — API integrations, automation pipelines, deployment configurations — those took days, maybe a week total. What took longer was calibrating the outputs for each property’s specific situation. A report that works for a Hengchun beachfront property doesn’t work for a mountain guesthouse in Nantou. The business context files are still evolving as I learn what each owner actually pays attention to.
The other thing that took time: getting owners to trust the outputs enough to act on them. An accurate report that owners file away and don’t use is just expensive automation. The goal was systems they’d actually rely on — which meant iterating on the format, the language, the level of detail, based on what generated real conversations about decisions.
Why One Developer Can Do This Now
Three months, five codebases, nine clients, three automated systems running weekly. A few years ago this work probably wouldn’t have happened at all — not because nobody wanted to do it, but because these clients couldn’t afford the cost of making it happen. Engineering, data analysis, ad optimization, weekly reporting — each piece used to require dedicated headcount, and together they add up to a budget that’s simply out of reach for a small B&B.
AI tooling changed what’s possible alone. Claude handles the analysis layer that would otherwise require either a specialized analyst or extremely rigid rule-based logic. GitHub Actions handles the orchestration that would otherwise require standing infrastructure. Astro’s architecture handles the performance optimization that would otherwise require careful manual tuning.
What AI didn’t do: decide what the businesses actually needed, design the system architecture, figure out why owners weren’t looking at GA4, or notice that the Sheets approach would make the ads system feel more trustworthy than a database. Those were judgment calls.
The pattern I keep finding: AI handles execution at a pace I couldn’t match alone; the decisions about what to execute still require someone who understands the problem. The combination is what made this scale of work possible in three months.
What’s Running Now
Five sites. Automated deploys on every commit. Nine B&Bs receiving automated weekly reports. Ads health checks for the properties running Google campaigns. Owners with admin panels they can use without calling me.
The system keeps running. When a new property comes on, I add a site config and a business-context.md. The automation picks it up automatically.
The work isn’t done — it never is. But the foundation is there, and it’s running without me watching it every day. That was always the goal.