← All tools
Operations guide

How the admin works.

The cheat-sheet for running Perthlivin. Hand this to anyone you bring on — they should be productive in 30 minutes.

01All tools at a glance

Each card maps to one tile on /admin. "When to use" answers the only question that matters: which screen do I open for this task?

📥 Review queue /admin-vetting

When to use

Something arrived on its own — a business application, suggested spot, event submission, or problem report. Triage from one screen.

  • Approve → row promoted to Live in spots (or events etc.).
  • Reject → row removed.
  • "Open spot editor" → tweak before approving.

⚡ Quick add a spot /admin-quick-add

When to use

You found a cool place. Paste one URL (Instagram, TikTok, website, Google Maps link). Google Places auto-fills address, hours, photos, rating. You then jump to "Add & edit" to polish.

  • Fastest path from "saw a cool spot" to "it's in the system".
  • Lands in spots as Status='Pending' — won't show on the public site until you flip it to Live.

✏️ Add & edit spots /admin-add-spot

When to use

The main workhorse. Create a spot from scratch, or load an existing one and edit any field — opening hours, photos (upload to Cloudflare), tags, who-for, tier, booking link, the lot.

  • Status dropdown controls visibility: Pending · Draft · Live · Needs Review · Hidden.
  • First photo is the hero (used for cards, map thumbnails, share previews).

🤝 Partners /admin-partners

When to use

A business owner wants to manage their own spot. Approve their claim, link spots to their account, suspend or reissue logins.

  • Pending claims — review requests from /partner/claim.
  • Approved partners — see who owns what, add/remove spots, send fresh login emails.

🗺️ Itinerary planner /admin-add-trip

When to use

Build a curated multi-day trip ("Mount Lawley brunch crawl", "Perfect day in Fremantle"). Stitches existing spots into a route with time-of-day suggestions. Visible on the homepage Trips row + at /best-days.

🎉 Add an event /admin-add-event

When to use

Something time-limited is on — gig, market, festival. Goes onto the homepage "This weekend" row + the dedicated What's On page. Type the venue's address; the form auto-links it to your existing spot if there's a match.

📊 Analytics /admin-dashboard

When to use

Weekly check: traffic, top spots, quiz funnel, conversion funnel — pulled from Google Analytics. Not real-time — GA has a ~24h delay.

🔍 Spot inspector /admin-spot

When to use

Debug. Shows the raw Supabase row for any spot, exactly as the public site sees it. Useful when something looks wrong on the live site and you want to know what's actually stored.

02Flow · Adding a new spot

When you discover a place worth featuring.

From "saw a great café" to live on the map

YOU · SYSTEM · ~5 MINUTES
You
Find the place. Get any one URL — their Instagram, Google Maps link, website. Doesn't matter which.
You
Open Quick Add — /admin-quick-add. Paste the URL. Click "Look up". Auto-fills name, address, hours, rating, photos from Google Places.
System
Creates a row in spots with status='Pending'. The spot is now in the DB but invisible to the public.
You
Polish the listing. Click "Open spot editor". Add a description, why-you'll-love-it line, pro tip, who-for tags. Reorder photos so the hero is right.
You
Flip status → Live. Save. Public site shows it within a minute (the /spots endpoint has a 60s cache).
Shortcut: If a business owner already submitted the listing themselves via /list-your-business, skip Quick Add. Go to /admin-vetting and approve from there — same outcome, less typing.

03Flow · Vetting a submission

Someone applied to list, suggested a spot, or reported a problem. Where it lands and how to clear it.

The vetting queue

PUBLIC · YOU · ~2 MIN PER ITEM
Public
Someone submits a form on /list-your-business, /suggest-a-spot, /submit-an-event or /report-a-problem.
System
Row inserted into Supabase with status='Pending' (or the equivalent for events / problem reports). Admin home counter increments.
You
Open the review queue — /admin-vetting. The "Pending review" stat on the admin home goes red if there's anything waiting.
You
Three options on each card:
  • Approve → status flips to Live (or equivalent), goes public.
  • Reject → row deleted. Optional reason for your own notes.
  • Open spot editor → tweak fields before approving (most common — submissions are usually thin on copy).
Editorial bar: Perthlivin is curated. Reject anything that isn't a real, locally-loved Perth business — even if it's well-intentioned. Quality > quantity. A 5-line description + photo isn't enough; you'd usually polish in the spot editor before approving.

04Flow · Partner claim

A business owner wants to manage their own listing. End-to-end, from their first click to logged-in.

From claim form to dashboard

PARTNER · YOU · SYSTEM · <24 HOURS
Partner
Fills the form at /partner/claim. Submits.
System
Inserts a row into spot_claims with status='pending'. Auto-matches the business name against Live spots and pre-fills the matched spot if exactly one matched.
You
Open /admin-partners — "Pending claims" badge shows the count. Review the claim card.
You
Verify they actually run the place. Check their email domain, their business's own social, or call the number on file. Reject if dodgy — write the reason so future you remembers.
You
Pick the spots they manage (search box + checkboxes). Click ✓ Approve & assign. A chain owner can be linked to multiple spots — that's expected.
System
Creates a business_owners row (status=approved), inserts owner_spots links, marks the claim approved, audits the action.
System
Sends an automatic magic-link email to the partner via Supabase Auth. Subject & body live in Supabase → Authentication → Email Templates.
Partner
Clicks the email link → lands on /partner/login → already signed in → redirected to /partner/ dashboard. Sees their spot(s).
If the email doesn't arrive: use the ✉ Resend login email button on the approved partner card. Same magic-link API. Spam folder is the usual culprit on first send.
Suspending vs deleting:
  • Suspend — blocks login but keeps their data + spot links. Reversible.
  • Delete — permanent. Removes the owner row + all their owner_spots links via cascade. The auth.users row stays so they can re-claim later if you change your mind.

05Flow · Approving an event

Time-limited things — gigs, markets, festivals.

Event submission → on the homepage

PUBLIC · YOU · ~5 MIN
Public
Submits via /submit-an-event. Row lands in events as Pending.
You
Open /admin-add-event. The pending submissions show in the same screen as the create-event form, so you can edit then save.
You
Check venue match. If the address matches a Live spot, the form auto-links it — that powers "more like this at [Venue]" cross-links.
You
Flip status → Live. Shows on homepage This weekend row and the dedicated /whats-on page.

06Flow · Building a trip

Editorial multi-stop itineraries — the highest-engagement content on the site.

Curated trip → public

YOU · ~15 MIN
You
Open the planner at /admin-add-trip. Set a title (e.g. "Mount Lawley brunch crawl"), duration, optional hero image.
You
Pick the stops. Search Live spots, drag to reorder, set time-of-day for each (Morning / Arvo / Sunset / Evening). Stops must exist in spots — create them first if not.
You
Set Editorial=true to feature it. Save. Lands in shared_days table.
System
Public homepage shows it in the Trips carousel, sorted editorial-first. Clicking a trip on the homepage now replaces the user's My Trip — that's the default behaviour shipped this week.

07Where things live

Quick map of which Supabase tables back which features.

spots
All places. Source of truth for the map, search, top-spots, day-trips.
shared_days
Curated & user-submitted trips. editorial=true = featured.
events
What's on. Time-limited.
shared_trips
Per-user shareable day plans (created via "Share my trip").
spot_claims
Inbox of "I own this business" requests from /partner/claim.
business_owners
Approved partner accounts (one row = one login).
owner_spots
Many-to-many: which spots each owner manages.
spot_overrides
Partner-submitted edits awaiting your approval (slice 2 — coming).
pl_events
Analytics event log. plTrack() on the public site writes here.
audit_log
Every admin mutation. "Did someone change my hours?" → check here.
auth.users
Supabase Auth. Partner logins land here on first magic-link click.

08All URLs in one place

Bookmark or screenshot this. Every URL the admin or a partner ever needs.

Admin

Public-facing partner entry points

External dashboards

09Emergencies

When something's on fire.

The site is down

  1. Check Netlify deploys — bad commit? app.netlify.com → site → Deploys → "Publish deploy" on the last green one to roll back.
  2. Check Supabase status — outage? status.supabase.com.
  3. If neither, check Cloudflare DNS.

A partner can't log in

  1. /admin-partners → find the partner → confirm claim_status='approved' (not suspended).
  2. Click ✉ Resend login email. Ask them to check spam.
  3. Still stuck? In Supabase → Authentication → Users → search by email → "Send magic link" manually.

Wrong data on the public site

  1. Open /admin-spot → find the spot. Confirm the raw DB row.
  2. If DB looks right but public site shows old data, the /spots endpoint caches for 60s. Wait or trigger a deploy.
  3. If DB is wrong, edit in /admin-add-spot.

"Someone broke my listing!"

Check audit_log in Supabase. Every admin action and partner override is recorded with timestamp, actor and payload. Filter by target_id = '<spot_id>'.