Project 7 — Staybnb / Airbnb lite: the specswift-6.4/ios-26
Lesson 1 / 6
Unit 27 · Staybnb

Project 7 — Staybnb / Airbnb lite: the spec

Note

Unit 27 · Project 7 (Staybnb, an Airbnb clone). Backend Tier 2 (Supabase + edge functions). AI stage: Professional — you plan first, delegate broader chunks, and gate the result through a review pass. A real stays app: a category explore, a rich listing detail (photo gallery, host, amenities, reviews), a booking flow with a price breakdown, wishlists, and a map.

Staybnb is a stays app: browse listings by category, open a place to a full detail with a swipeable photo gallery, host, amenities, reviews, and a where-you'll-be map, save favorites to a wishlist, and run a booking flow that totals the trip. Underneath is a map of results you can pan and a filter panel, and on iPad the same content becomes a three-pane layout — the theme is composition at scale: many listings, many surfaces, two form factors, one coherent app.

What you build

  • Explore — a search header, a scrollable category row, and a feed of listing cards (a paging photo gallery, a heart, location, rating, price) — with a map you can pop into.
  • Listing detail — a photo gallery, title + rating, the host, the room specs, an amenities list, a reviews section, and a "where you'll be" map, with a sticky reserve bar.
  • Booking — pick nights and guests and see the price breakdown (nightly × nights, cleaning, service, total) with a confirm button.
  • Wishlists — the places you hearted, saved and shown in their own tab.
  • Filters + map — compose price/guests/amenities; a MapKit map with custom price pins.

The screens

Screen Shows Key interaction
Explore category row + listing cards, search tap a category/card; open the map
Listing detail gallery, host, amenities, reviews, map scroll, save, reserve
Booking nights/guests + price breakdown confirm and pay
Reviews rating summary + review list scroll
Map price pins over MapKit pan/zoom, tap a pin

What it looks like finished

Staybnb explore — category row and listing cards with photo galleries Staybnb listing detail — gallery, host, amenities, reviews, and a map Staybnb booking — nights/guests and a price breakdown Staybnb reviews — a rating summary and review cards Staybnb map — listings as custom price pins over MapKit
The finished build in the simulator: the category explore, a listing detail, the booking price breakdown, the reviews, and the MapKit map with custom price pins. The same content rearranges into a three-pane NavigationSplitView on iPad. Listings are sample data — a real build fetches them through the Supabase edge function.

Concepts this locks in

  • MapKit in SwiftUI — the Map view, custom price-pin annotations, camera framing.
  • A paging photo gallery — a TabView(.page) of images with a heart and page dots.
  • Complex filtering + categories — a filter model composing pure predicates, off the render path.
  • A booking flow — derived price math (nights × price + fees) with a confirm sheet.
  • Wishlists — an @Observable store in the environment; several screens read it.
  • NavigationSplitView — a three-column iPad layout that collapses to a stack on iPhone.
  • Supabase edge functions — moving search and pricing to a server-side function.
  • Render discipline — the AI checkpoint targets a view that re-renders pathologically.

Backend tier: 2 (Supabase + edge functions)

Listings live in Supabase. Simple reads use the client directly, but the search — apply the filters, compute a nightly price for the date range, return a ranked page — runs in a TypeScript edge function you deploy. The app calls it like any API. This is the first project where you write server code, and it is deliberately small: one function, one clear job.

AI stage: Professional

In Professional mode you get broader autonomy — the model can take a whole milestone as a task — but the workflow around it tightens: plan first (review the plan, not just the diff), CLAUDE.md conventions bind, and a code-review pass (/swift-review) checks each chunk against them.

Tip

Professional does not mean "unsupervised." The review moves earlier and higher: you review the plan and the architecture, and a review pass catches the line-level issues. You are accountable for every line the model wrote as if you wrote it — because in the rubric, you did.

In scope

  • A category explore with listing cards (paging gallery, heart, rating, price) and a map.
  • A rich listing detail: gallery, host, specs, amenities, reviews, a where-you'll-be map.
  • A booking flow with a derived price breakdown and a confirm step.
  • A wishlist store several screens read; a filter model with a visible result count.
  • A NavigationSplitView iPad layout; one Supabase edge function for server-side search.
  • Light/dark correct; Dynamic Type and VoiceOver on the cards, filters, and detail.

Out of scope

  • Real payments and real availability calendars — the booking flow totals a trip and confirms, but doesn't charge a card or check live availability.
  • Host dashboards, messaging hosts, and account management beyond a stub profile.
  • Offline caching of map tiles or listings beyond the current results.
  • Real geocoding of free-text locations — a fixed set of listings/regions.

Definition of done

On iPhone you can browse by category, open a listing to its full detail, save it to your wishlist, run the booking sheet and see a correct total, and read its reviews — with the map and filters working. On iPad the same content shows as a three-pane split. The search runs through your edge function, and the filters don't cause the whole list to re-render pathologically. Then the checkpoint, then the rubric.

Knowledge check

Q: What changes about your workflow moving from Pair to Professional? The review moves earlier: you agree a plan before code, the model may take a larger chunk, and a code-review pass checks the result against the repo conventions. Autonomy goes up, but so does the rigor of the gate — and you own every line in the rubric.

Q: The wishlist heart appears on a card, on the detail, and drives a whole tab. How is that one piece of state? It's an @Observable Wishlist in the environment. The card's heart, the detail's heart, and the Wishlists tab all read and toggle the same store, so saving anywhere updates everywhere with no syncing — the same "one source of truth, many readers" pattern the backend tiers keep teaching.