Ops command view: day counts, money collected, and UniFi health — then the detail boards below.
Arrivals
| Site | Guest | ETA | Party | Out | Deposit |
|---|
Departures
| Site | Guest |
|---|
Deposits due
| Site | Guest | Check-in | Amount |
|---|
Dirty sites
| Site | Last checkout |
|---|
Open work orders
| Site | Title | Priority | Status |
|---|
Camp store
Store sales today $0.00 · 0 transactions
Click an empty cell to book a single night, or click-and-drag across empty cells to select a range and choose New Reservation or Add Block. Drag an upcoming stay (amber) to move dates/site. Drag a checked-in / walk-in bar onto another site to relocate mid-stay (broken pad, etc.) — or use Move to Another Site on the Sites tab. Edge handles shorten/extend upcoming stays only.
Live site status on your uploaded park image. Click a pin for the same details as the Sites tab. Sites without a placed pin don't appear here — place pins under Settings → Park & Branding → Park map.
Anything that needs attention on a site or around the park — guest-reported WiFi issues land here automatically. Use the buttons on a row to start, complete, or reassign it.
| Site | Title | Category | Priority | Status | Assigned to | Created |
|---|
After a guest checks out, the site lands here as Dirty. Walk each site Dirty → Clean → Inspected → Ready before the next guest arrives. Occupied sites are hidden so this stays a turn-over board, not a guest list.
A simple log of park equipment and when it was last serviced — mowers, golf carts, pool pumps, anything worth tracking.
| Name | Category | Location | Status | Last service |
|---|
Park-defined rental catalog — kayaks, golf carts, court time, anything with units, an optional deposit, and a return. To book one for a guest, open that guest's reservation; this tab is catalog admin plus a park-wide view of what's out.
| Name | Category | Unit | Price | Deposit | Units | Available | Active |
|---|
| Guest | Item | Qty | Status | Deposit | Due back |
|---|
Messages
Reach guests who are on site or holding an upcoming reservation — email, text/MMS, or a spoken phone broadcast. Configure SMTP and Twilio under Settings → Guest Communication first.
Compose email
Recipients
| Guest | Site |
|---|
Compose text
MMS needs a publicly reachable https:// image. Leave blank for a plain text.
Recipients
| Guest | Site | Phone |
|---|
Phone broadcast
Places an automated call to each selected guest and speaks your message (Twilio Voice). Use for cancellations, weather, or other time-sensitive alerts. Your Twilio number must support Voice.
Recipients
| Guest | Site | Phone |
|---|
Recent sends
Last bulk emails, texts, and phone broadcasts from this park.
| When | Channel | Summary | Sent | Failed | By |
|---|
Post-stay feedback
Responses from the checkout survey link. Use follow-up filter when a guest asked to be contacted.
| When | Guest | Site | Overall | Arrival | Site | Follow-up | Comments |
|---|
Settings
Grouped by what you're trying to do -- pick a section below. If you're not sure where something lives, Overview is a good place to start.
Selling ice, firewood, or other camp store items? Ring up a sale from the Sites or Today tab's "Camp store" button -- manage products here under Sites & Rates → Camp Store.
System Health
A quick "is everything OK" glance -- useful before calling anyone for help, or when helping remotely.
Setup Wizard
Walks you through business info, guest email, your internet connection, site inventory, and payment details. Runs automatically the first time; use this any time you want to revisit it.
Park
Office passphrase is kept on the guest SSID as Multi-PSK. If you set an Office SSID, that network uses the same passphrase and VLAN (Sync Networks updates it). Leave passphrase blank to keep the saved one; leave VLAN blank to keep office on Default LAN.
Site N uses VLAN base + N when the site has no VLAN set (e.g. base 100 → site 4 = VLAN 104 → subnet 10.81.104.0/24). One SSID; each site password is bound to its VLAN for bandwidth.
Guests can book at /book.html and purchase add-ons (firewood, s'mores, etc.) when reserving. Same-day check-in works into the evening (server local date) unless a site type sets a same-day cutoff hour — keep the Contabo server timezone matched to the park. Off until you're ready.
Only charged when a guest picks an exact site on the map or list — a "site assigned at check-in" booking never gets it. Shown to guests as "Pay to hold this exact site."
Cancellation policy
Embed booking widget
Let guests book straight from your own website via an iframe or script tag — no separate CMS needed. Reuses the same online booking flow as book.html. Requires Enable online reservation portal for guests above.
Leave blank to allow the booking API to be called from any website (simplest; matches how book.html already works today). Listing sites here blocks other sites' own scripts from calling the booking API directly. It does not, by itself, stop a site from putting the widget in an iframe -- that works with no allowlist entry needed, same as any other iframe embed.
Park map
Upload a photo or diagram of your park, then place a pin for each site. Staff get a live status map (Map tab); guests can optionally pick their site on the map when booking online.
Pin editor
Click Place pin next to a site, then click anywhere on the map to drop it there. Drag an existing pin to move it. Each change saves immediately.
Amenities
Optional pins for things guests look for -- restrooms, dump station, playground, laundry, office. Shown with a legend on the same map above (and on the guest booking map, if enabled).
GuestGrounds license
Product site: guestgrounds.com. Leave blank for a full unlock (typical for a single self-hosted park). Paste a plan key to unlock only the modules you bought. Core Desk and WiFi Ops stay available on every plan.
Optional features
Advanced tools stay off until you need them. Turn on a pack for a group, or flip individual switches. Everything below is already built into the app — enabling only shows it.
Packs
Individual
Weather Widget
Shows current conditions and a short forecast on the lobby kiosk (Tablet Kiosk Mode, under Guest Communication). Powered by a free weather service — no account or API key needed. Just tell it what town you're near.
Site Inventory
The park's physical sites — site number, VLAN, bandwidth profile, and rate type. These rarely change (only when a site is built, renumbered, or decommissioned). Day-to-day guest check-in/check-out happens on the Sites tab, not here.
| Site # | VLAN | Profile | Site type | Status |
|---|
Sync Networks creates/updates UniFi VLANs and bandwidth groups from this inventory (and the office VLAN). Guest passphrase sync will not create networks — only bind passwords to VLANs that already exist.
Bandwidth Profiles
Download/upload tiers assigned to sites (e.g. Standard, Premium, Unlimited). Applied to UniFi when you click Sync Networks to UniFi on Site Inventory (one SSID, per-site VLAN + usergroup).
| Name | Download | Upload | Default |
|---|
Wireless Bandwidth Calculator
Enter what your internet plan provides, hold back what the park office needs, and split the rest evenly across your sites to get a suggested per-site speed limit.
Site Types & Rates
Rate categories assigned to sites (e.g. Standard, Premium, Pull-Through) with an optional nightly rate shown when booking a reservation.
| Name | Nightly | Weekly | Monthly | Min Stay | Description | Default |
|---|
Seasonal & Dynamic Rate Rules
Date-range overrides layered on top of a site type's base rates — e.g. a "Summer Season" rule that raises the nightly rate and requires a 3-night minimum stay for June through August. Rules repeat every year automatically and don't need a specific year. When two rules overlap the same date, the one with the higher priority wins.
| Name | Site Type | Dates | Nightly | Weekly | Monthly | Min Stay | Priority | Enabled |
|---|
Add-ons
Extras guests can purchase with a reservation (staff booking or the online portal) — firewood, s'mores kits, and anything else you sell for the stay. Prices are locked onto each reservation when it's booked.
| Name | Price | Description | Enabled |
|---|
Promotion Codes
Offer a percentage or fixed discount with optional date, minimum-stay, site-type, subtotal, and usage limits.
| Code | Discount | Limits | Enabled |
|---|
Camp Store
Simple product catalog for front-desk sales charged to a guest folio (ice, firewood, merchandise). Ring up sales from the Today tab.
| Name | Category | Price | Stock | Active |
|---|
Self-service kiosk
Park Credit / Gift Cards
Stored-value codes guests can redeem against a reservation folio. Not a payment processor — staff issue and redeem codes here.
| Code | Balance | Issued to | Expires | Status |
|---|
Utility Meter Billing
Rates used when billing electric and water meter reads on long-term / seasonal reservations. Record reads on the reservation folio, then bill usage to the folio.
Example: 100 kWh Ă— $0.15 = $15.00
UniFi API Connection
Generate an API key in the UniFi Network app: Settings → Control Plane → Integrations. Live sync and live stats are best-effort — if your firmware's API doesn't match, sites fall back to clear manual instructions.
Newer UniFi consoles need the site’s UUID here. Click Test Connection and we’ll fill it in when there’s only one site.
On-Site Agent
If this dashboard is hosted somewhere off-site (a VPS, not on the park's own network), it can't reach your UniFi controller directly anymore. Switch to "Agent (remote)" and run the small relay agent (agent/ folder, see agent/README.md) on a machine at the park — it opens an outbound connection here so no ports need to be opened on your router.
Sent to the alert email address configured under Network Monitoring below -- also requires background monitoring to be enabled there.
Regenerating invalidates the current token immediately — the on-site agent will need its config updated and restarted with the new value.
Integration API
Read-only API keys for external tools (Zapier, scripts). Use Authorization: Bearer <key> or X-API-Key against /api/open/v1/ endpoints.
API examples (copy & paste)
Replace YOUR_KEY with a key you create below. Keys are shown once at creation.
curl -H "Authorization: Bearer YOUR_KEY" https://your-park.example/api/open/v1/sites
curl "https://your-park.example/api/open/v1/availability?siteTypeId=TYPE_ID&checkIn=2026-07-01&checkOut=2026-07-05" -H "Authorization: Bearer YOUR_KEY"
curl "https://your-park.example/api/open/v1/reservations?from=2026-07-01&to=2026-07-31" -H "Authorization: Bearer YOUR_KEY"
curl "https://your-park.example/api/open/v1/occupancy?date=2026-07-01" -H "Authorization: Bearer YOUR_KEY"
| Label | Prefix | Created | Last used |
|---|
Outbound webhooks
Optional: push events to a URL instead of polling the read-only API above. Each delivery is a signed POST — verify it with the snippet below before trusting the payload.
| Label | URL | Events | Enabled | Last delivery |
|---|
Webhook payload & signature verification
Every delivery is a POST with an X-RV-Park-Event header and an X-RV-Park-Signature header (HMAC-SHA256 of the raw body, hex-encoded, using the secret shown once when you create the webhook).
{
"event": "reservation.checked_in",
"timestamp": "2026-07-01T15:04:00.000Z",
"parkName": "Sunny Pines RV Resort",
"data": {
"id": "…",
"guestName": "Jamie Rivera",
"siteNumber": "14",
"checkIn": "2026-07-01",
"checkOut": "2026-07-05",
"status": "checked_in"
}
}
Verify the signature in Node (or any language with HMAC-SHA256):
const crypto = require('crypto');
const expected = crypto.createHmac('sha256', WEBHOOK_SECRET).update(rawBody).digest('hex');
const valid = expected === req.headers['x-rv-park-signature'];
Use the raw, unparsed request body for the HMAC — not JSON.stringify(req.body), which can reformat whitespace and break the signature.
| Time | Webhook | Event | Result |
|---|
Network Monitoring
Runs in the background while the dashboard is running: checks internet reachability every few minutes, optionally runs a real download speed test, and flags occupied sites showing zero connected devices. Uses the SMTP settings above to send alert emails.
Site-to-AP Coverage Zones
Map campsite ranges to specific outdoor APs (e.g. Sites 7–14 → AP 2 - North Loop) to eliminate sticky clients and balance radio airtime across the park.
| Zone Name | Access Points | Sites | Notes |
|---|
Park & Staff Wi-Fi Aliases
Permanent credentials for facility areas (Clubhouse, Maintenance, Pool) and staff devices. Aliases set to Park-Wide Roaming broadcast across all APs so staff never drop offline while walking the park.
| Alias Name | Passphrase | Scope | VLAN | Profile |
|---|
Access Points & Remote Power-Cycle
View adopted outdoor APs, their switch port connections, and live client loads. If an outdoor AP ever locks up in weather, reboot it or power-cycle its PoE switch port directly from the desk without walking out with a ladder.
| Access Point | Status | IP Address | Uplink Switch & Port | Clients | Channels |
|---|
Receipt Setup
Shown on the printable check-in receipt (Sites tab and Reservations). Business name falls back to the park name above if left blank.
Guest payment apps
Used on printable receipts and the desk “Display … QR” buttons when a guest pays that way. Same idea for both — paste the park’s handle.
Stripe card payments
The Stripe secret key and webhook secret stay in the server's .env file. This only enables Checkout and optionally records the publishable key for a future embedded card form.
Guest Email (SMTP)
Used for the "Email QR to Guest" button. Works with any SMTP provider — Gmail/Workspace (use an app password), Microsoft 365, or a transactional email service.
Guest Emails
Automatic emails sent to guests using the SMTP settings above — separate from the manual "Email QR to Guest" button on a site. Each one no-ops silently if the guest has no email on file or SMTP isn't configured.
When feedback is on, checkout always creates a private survey link. If thank-you email is on and the guest has an email, the link goes in that message; otherwise staff get a Copy link prompt at checkout (text it or show it at the desk).
Edit message templates
Allowed placeholders: {{parkName}}, {{guestName}}, {{firstName}}, {{siteNumber}}, {{checkIn}}, {{checkOut}}, {{manageUrl}}, {{surveyUrl}}.
Booking confirmation
Arrival reminder
Thank-you
Scheduled reports
Email a daily ops + accounting digest to the owner or accountant. Uses the SMTP settings above. Local server clock hour; runs at most once per day.
Guest SMS (Twilio)
Texts and phone broadcasts use the same Twilio account. Enable SMS below, then use the Messages tab to text guests or place a spoken voice call (your Twilio number must support Voice). WiFi credential texts still use the toggles further down.
Guest SMS
Automatic texts sent to guests using the Twilio settings above. Each one no-ops silently if the guest has no phone number on file or SMS isn't configured.
Guest text Inbox (two-way SMS)
Lets guests text your Twilio number back — replies land in Messages → Inbox, matched to the guest's reservation. Uses the same Twilio account configured above.
In your Twilio console: phone number → Messaging → "A message comes in" → Webhook →
Digital Check-In & Waiver
Shown to guests who complete check-in on their own phone via a "Digital Check-In Link" from the Sites or Reservations tab. Since this dashboard is self-hosted, that link only works once the guest is already connected to the park WiFi.
Reservation Forms
Edit the forms staff can attach to a reservation. Each attached form keeps its own copy of this text, so later edits do not change past signed records.
Guest Document Uploads
Let upcoming guests share small ID, insurance, pet vaccination, or other documents through their secure Manage My Stay link. Files lock at check-in.
Allowed categories
Require before check-in
Guest Arrival Hub
Shown securely inside Manage My Stay. New parks get starter text based on common RV-park practices (check-in times, quiet hours, pets, WiFi, safety). Edit everything for your park. Use one short step per line in checklist fields.
Tablet Kiosk Mode
A self-serve, full-screen page for a lobby tablet. Guests can look up their reservation by name to check themselves in, or view rates, vacancy, and WiFi/contact info without any login. Opens in a new tab — leave it running on a mounted tablet connected to the park WiFi.
Staff SOP (desk cheat sheet)
Internal front-desk steps — not shown to guests. Also available from Today → Desk SOP.
Staff Accounts
Admins can manage settings, profiles, and this list. Staff can check guests in/out, sync, and email/print WiFi cards.
| Name | Username | Role |
|---|
Team Members (No Login)
People who help run the park but don't need their own dashboard login — e.g. a part-time cleaner or a contracted handyman. Add them here so they show up in the "Assigned to" list on Work Orders.
| Name | Role | Phone | Active |
|---|
Backup & Restore
Download a full backup of everything in this dashboard — sites, reservations, guest/accounting/site-rental reports, staff accounts, and settings — so you can restore it later or move to a new server. The file includes credentials (UniFi API key, agent token, SMTP password, Twilio auth token, staff password hashes), so store it as securely as you would any other backup.
Restoring replaces everything currently in the dashboard with what's in the chosen file. This cannot be undone.
Scheduled Automatic Backups
Writes a timestamped backup file automatically on an interval, on top of the manual download above. Point this at a second local drive or a mapped network share — not the same disk this app runs on — so a backup actually survives a drive failure.
Browse opens the same style of Windows Explorer folder window used elsewhere on this PC. If that isn’t available, you’ll get an in-page folder list instead.
Danger Zone
Wipes every site, reservation, staff account, report record, and setting back to the application's defaults — as if freshly installed. This cannot be undone; there is no backup made automatically. You will be signed out and returned to initial setup.
Store charges grouped from reservation folios. Product names, categories, and prices are preserved as they were when each sale was posted.
By product
| Product | Category | Quantity | Sales |
|---|
Billed electric and water meter charges from reservation folios (method: meter).
By reservation
| Guest | Site | Electric | Water | Total |
|---|
Formal night audit: operations snapshot, settlement totals, and revenue vs cash variance. Print for shift handoff without recording a daily close.
Payments collected
| Guest | Site | Method | Amount | When |
|---|
Owner view of charged revenue by category (lodging, camp store, add-ons, site-lock fees, utilities, other) for a date range — based on folio charge lines.
| Category | Amount | Share |
|---|
Every guest who has ever completed a stay, for future marketing outreach. Built automatically from stay history at checkout.
| Name | Phone | Address | Opt-in | Visits | Nights | Total spend | First visit | Last visit | Sites |
|---|
| Date | Site | Guest | Nights | Revenue | Payment method |
|---|
Monthly invoices for long-term / seasonal guests. Turn on Monthly billing on an occupied site (or at reservation check-in). Periods generate automatically; record cash/Venmo/check here the same way as a stay receipt.
| Site | Guest | Period | Amount | Status |
|---|
Occupancy rate, average daily rate (ADR), and revenue per available site (RevPAR) for a period, plus how fully booked the calendar already is for the weeks ahead.
| Date | Occupied | Total Sites | Occupancy % |
|---|
Booking Pace
Share of available site-nights already booked, looking forward from today.
Outstanding reservation folio balances and unpaid monthly invoices, grouped by age.
| Bucket | Guest | Site | Due | Days | Balance | Kind |
|---|
Reservations grouped by staff/portal source, campaign, and referrer. No fingerprinting or hidden guest tracking is used.
| Source | Campaign | Referrer | Reservations | Cancelled |
|---|
How often each site has been rented, and for how much.
| Site | Times rented | Total nights | Total revenue |
|---|
Cash-drawer view of folio payments recorded today (card / cash / Venmo / Cash App / check). Open balances and deposits due are listed so you can clear money before close.
Payments this day
| Time | Site | Guest | Method | Amount | Ref | By |
|---|
Deposits still due
| Site | Guest | Check-in | Amount |
|---|
Open folio balances
| Site | Guest | Status | Balance |
|---|
Refunds still owed
Recorded automatically when a reservation with paid money is cancelled. Clears itself once staff post a Refund transaction on that reservation's folio covering the amount.
| Site | Guest | Since | Amount |
|---|
Night audit for multi-shift parks: ops snapshot plus settlement reconciliation (revenue vs collected). Record one close per calendar day.
Arrivals
Departures
Recent closes
| Date | Closed at | By | Variance | Notes |
|---|
Who did what, and when — logins, check-ins/checkouts, payments, and changes to sites, rates, users, and settings. This list is read-only; the newest entries are shown first.
| When | User | Role | Action | Target | Details |
|---|