
• Personal / Self initiated • vibe coding •
Scotland Getaways is a personal deal discovery platform built to solve a real, recurring frustration: missing luxury spa breaks and hotel offers that disappear before I notice them. Most travel sites are built for booking. This was built for monitoring.
Scotland Getaways is a personal deal discovery platform built to solve a real, recurring frustration: missing luxury spa breaks and hotel offers that disappear before I notice them. Most travel sites are built for booking. This was built for monitoring.
A deliberately experimental approach to product-building. I owned the product direction, UX decisions, and quality — and used AI as the engineering partner throughout.
I regularly save travel ideas — spa hotels, getaway venues, places I want to visit — but consistently miss the moments when good offers appear. The existing deal landscape had real gaps:
The first version built a deal database that scraped multiple travel sources, normalised offers into a common structure, scored deals by value, and displayed them in a searchable grid. Data was stored in SQLite. Functionally, it looked like a working product.
The product looked complete but was fundamentally failing its own brief. It wasn't a scout — it was just a searchable list I had to remember to update. This became the immediate highest priority.
Implemented a launchd-based monitoring system that runs automatically, survives Mac restarts, and requires no manual interaction. Four daily scans were scheduled:


Source Status — live scan log showing all sources checked automatically, deal counts, and timestamps. No browser required
The notification system was built but completely silent. After investigation, the root cause was a date format mismatch between SQLite and JavaScript that meant the query never matched newly inserted deals.
SQLite stored: 2026-06-05 16:30:00
JS compared: 2026-06-05T16:30:00Z
Query never matched. Notifications had effectively never fired.
Moved all date filtering into SQLite datetime functions
Added permanent deduplication — each deal notifies once only
Three tiers: watchlist · high-value · standard

Preferences — scan schedule, macOS notification status, and adjustable score threshold for what triggers an alert
A full audit of all data sources revealed that several were placeholder or mock implementations contributing no real deals. These were removed and replaced with genuine Scottish luxury venue integrations.
Secret Escapes (mock)
Groupon (placeholder)
VisitScotland (placeholder)
Archerfield House
Crieff Hydro
Greywalls
RiverBeds Lodges
SpaSeekers
Added venue and location-level tracking so the system could prioritise the places I genuinely care about — boosting their scores, surfacing them first, and triggering priority notifications the moment a matching deal appears.
Watchlist Venues — tracks both specific venues (Archerfield, Cameron House, Crieff Hydro) and locations (Glencoe, Isle of Skye). Shows active match counts and score boosts per entry
Over time, expired deals accumulated permanently. Old Black Friday offers, winter promotions, and seasonal packages remained visible long after they'd gone. A source reconciliation process was added to every scan.

Each scan now reconciles live source data against the database — only currently active deals remain visible
The initial interface had grown organically and it showed. Filters were oversized, navigation was inconsistent, and the preferences panel still referenced features that had never shipped. A full redesign addressed all of it.
Oversized filter chip rows dominating the page
Poor use of vertical space
Inconsistent navigation patterns
Preferences full of orphaned settings
Compact dropdown filters in a unified toolbar
Toolbar: filters · scan status · nav · refresh
Refined wordmark & botanical icon
Preferences rebuilt around real behaviour
The biggest breakthrough came from stepping back and questioning whether the product was actually doing what I thought it was. It wasn't. Building the habit of auditing before iterating changed how I approached every subsequent phase.
Placeholder sources made the database look full and the product feel functional. Replacing them with real venue data immediately exposed what was actually valuable — and what wasn't.
Users don't want another place to look. They want the system to do the looking and tell them when it matters. That insight is transferable to almost any product where the user has recurring intent but limited attention.
The AI could implement anything I described. But it couldn't tell me what to prioritise, what to cut, or when something was fundamentally broken. That judgment is still the designer's job.
The platform now runs autonomously. It scans four times daily, survives restarts, removes expired deals automatically, tracks a watchlist of venues and locations, and sends macOS notifications when something worth seeing appears — all without any manual input.

This project was genuinely different from client work. There was no brief handed to me, no stakeholder to align with, no pre-existing system to design around. Every decision — what to build, what to cut, what to fix first — was mine.
What surprised me most was how much the work still came back to classic product thinking: understanding what the product actually needed to do, auditing against that goal, prioritising ruthlessly, and redesigning when the interface stopped serving the user. AI-assisted development changed the speed and method of execution — not the thinking that made it worth building.
The vibe-coding approach taught me that designers who can work this close to the product — making real product decisions, testing assumptions, and iterating in real time — have a different kind of leverage. I intend to keep exploring that.