π GuestXP Developer Guide
Everything you need to understand, extend, and maintain the GuestXP Hotel Network Management Platform. This guide covers architecture decisions, the API data layer, UI patterns, database design, and deployment.
Vanilla JS Β· No Framework
11 Database Tables
13 API Namespaces
Light Enterprise Theme
Responsive Design
Audit Logged
System Architecture
GuestXP is a fully client-side, API-driven static web application. There is no server-side rendering or backend logic β all state lives in the browser and is persisted via the RESTful Table API.
Platform Architecture
Super Admin
β
Property IT Mgr
β
MSP Engineer
Users authenticate via Login Screen
index.html Β· super-admin.html
HTML pages load JS modules
data.js
+
app.js
+
api.js
+
super-admin.js
All data operations flow through api.js β RESTful Table API
RESTful Table API Β· tables/{resource}
11 persistent database tables
properties
access_points
guest_sessions
support_tickets
users
alerts
ssids Β· vlans
speed_tests
audit_log
Tech Stack
| Layer | Technology | Version | Notes |
|---|---|---|---|
| Language | Vanilla JavaScript (ES2020+) | β | No framework β zero runtime dependencies |
| Markup | HTML5 (semantic) | β | ARIA labels, landmark roles, proper heading hierarchy |
| Styling | CSS3 (Custom Properties) | β | CSS variables for theming; no preprocessor |
| Charts | Chart.js | 4.4.0 | Line, bar, area charts via CDN |
| Icons | Font Awesome Free | 6.4.0 | Solid/Regular icon set via CDN |
| Fonts | Google Fonts β Inter | β | 300β900 weight range |
| Code Font | JetBrains Mono | β | Used in docs pages |
| Topology | SVG (native DOM API) | β | Pure JS SVG generation, no library |
| Canvas | HTML5 Canvas API | β | Score gauge + WiFi heatmap |
| Data Storage | RESTful Table API | v2 | Relative URL tables/{resource} |
Quick Start
Get up and running with local development in under 5 minutes.
-
1Clone / Download the projectAll files are committed to the static site git repo. No build step required.Shell
# Clone from git git clone <repo-url> guestxp cd guestxp # Serve locally (any static server will do) npx serve . # Or: python3 -m http.server 3000
-
2Open index.html in browserNavigate to
http://localhost:3000. The login screen will appear. Use demo credentials:Credentials# Super Admin Email: admin@macrotech.com | Password: admin123 # MSP Engineer Email: engineer@cloudext.in | Password: eng123 # Property IT Manager Email: manager@hotel.in | Password: mgr123
-
3Explore the API in browser consoleThe
GuestXPandDBglobals are available in the browser console after login.Browser Console// In browser developer console after page loads: const props = await GuestXP.PropertiesAPI.list(); console.log(props.data); // Array of hotel properties const summary = await DB.DashboardAPI.getSummary(); console.log(summary); // Full dashboard KPIs
-
4Verify API loadedLook for the blue banner in the browser console:
GuestXP API v2.0.0 loaded
No build step: GuestXP is pure HTML/CSS/JS. Any static file server works β no Node.js, no bundler, no compilation required. Just serve the directory.
File Structure
Project Tree
guestxp/ βββ index.html # Main app β login + property manager view βββ super-admin.html # Super Admin portal (MSP/SA view) βββ api-docs.html # Interactive API documentation βββ docs.html # Developer guide (this page) βββ login-preview.html # Login screen preview β βββ css/ β βββ style.css # Main stylesheet β design tokens, components, topology β βββ super-admin.css # Super Admin portal styles β GD tab, SA tabs β βββ js/ β βββ api.js # β REST API data access layer (13 namespaces) β βββ data.js # In-memory seed data β properties, APs, guests, SSIDs, VLANs β βββ app.js # Main app logic β tabs, topology, modals, floor plan β βββ sa-data.js # Super Admin seed data β hotel groups, tickets, users β βββ super-admin.js # Super Admin UI logic β GD charts, gauges, SA tabs β βββ images/ # Static assets β βββ .tables/ # Database schema definitions (managed by platform) βββ schema.json
Load order matters: Scripts must load in this order β
data.js before app.js (data referenced immediately), api.js first (globals needed by both). In super-admin.html: sa-data.js β super-admin.js. Using the API Layer
The
js/api.js file exposes all data operations as async functions on the global window.GuestXP (aliased as window.DB) object.Global access: After
api.js loads, use GuestXP.PropertiesAPI.list() or the shorthand DB.PropertiesAPI.list() anywhere in the codebase.JavaScript β Common Patterns
// βββ 1. LIST with pagination βββββββββββββββββββββββββββββ const { data, total } = await GuestXP.PropertiesAPI.list({ page: 1, limit: 20, search: 'mumbai' }); // βββ 2. GET single ββββββββββββββββββββββββββββββββββββββββ const prop = await GuestXP.PropertiesAPI.get('prop-001'); // βββ 3. CREATE with audit log βββββββββββββββββββββββββββββ const ticket = await GuestXP.TicketsAPI.create({ property_id: 'prop-001', title: 'AP down on floor 3', priority: 'high', category: 'hardware', reporter_name: 'Rahul', reporter_role: 'it_manager' }); // βββ 4. UPDATE (partial) ββββββββββββββββββββββββββββββββββ await GuestXP.PropertiesAPI.update('prop-001', { status: 'warning' }); // β Automatically writes to audit_log (fire-and-forget) // βββ 5. Dashboard parallel query βββββββββββββββββββββββββ const summary = await GuestXP.DashboardAPI.getSummary(); // Runs: PropertiesAPI.getKPIs() + AlertsAPI.getUnreadCount() // + TicketsAPI.getKPIs() β all in Promise.all // βββ 6. Error handling ββββββββββββββββββββββββββββββββββββ try { await GuestXP.PropertiesAPI.get('prop-999'); } catch (err) { console.error(err.message); // "GET tables/properties/prop-999 β 404 Not Found" showToast('Property not found', 'error'); }
Audit Logging is Automatic
Every UPDATE, CREATE, and DELETE call in
api.js internally calls _writeAuditLog() as a fire-and-forget Promise. You don't need to log anything manually. The audit log entry captures: action, resource type, resource name, changed fields, user name, user role, timestamp, and user agent. User Roles & Access Levels
GuestXP has a 4-tier role hierarchy. The login screen determines which portal loads.
Super Admin
Full platform access. Manages all hotel groups, properties, and MSP staff. Loads
super_admin
super-admin.html.MSP Engineer
Network operations team. Manages APs, topology, support tickets across all properties.
msp_engineer
IT Manager
Property-scoped admin. Manages APs, SSIDs, VLANs, and guests for their hotel only.
it_manager
View Only
Read-only access to dashboards and reports. Cannot modify any configuration.
viewer
Role Routing Logic
JavaScript β Login Router (data.js)
// In doLogin() β after credential check: if (user.role === 'super_admin' || user.role === 'msp_engineer') { window.location.href = 'super-admin.html'; } else { showApp(user); // property view in index.html }
Tab System
Both portals use a lazy-rendered tab system. Content is only rendered when a tab is first activated, preventing unnecessary DOM work.
Property Portal Tabs (
index.html / app.js)JavaScript
// Tab IDs (from TABS array in app.js) 'dashboard' β Property overview KPIs + live stats 'topology' β SVG network topology builder 'aps' β Access points table + management 'guests' β Active guest sessions 'ssids' β SSID configuration 'vlans' β VLAN management 'alerts' β Alert feed + notification prefs 'speedtest' β WAN speed test + history 'floorplan' β Interactive floor plan with AP placement 'reports' β Network reports + exports
Super Admin Tabs (
super-admin.html / super-admin.js)JavaScript
// _SA_TABS array β lazy render via saShowTab(tab, btn) 'gd' β Group Dashboard (KPIs, India map, charts, AI insights) 'props' β All Properties grid 'tickets' β Support ticket portal (Kanban + table) 'users' β User management (all roles) 'reports' β Cross-property reports
Lazy rendering: Tab content renders once on first activation and is cached. A tab's render function is called only if
_SA_RENDERED[tabId] is false. This keeps initial page load fast. Design Tokens (CSS Custom Properties)
All colors, spacing, and shadow values are driven by CSS custom properties defined in
css/style.css. Use these tokens throughout β never hardcode hex values.CSS β Token Reference
:root { /* Brand */ --primary: #1a73e8; /* Google Blue β buttons, links, accents */ --primary-dark: #0d5bc7; /* Hover state */ --primary-light: #e8f0fe; /* Backgrounds, chips */ /* Status */ --success: #16a34a; --success-bg: #f0fdf4; --warning: #d97706; --warning-bg: #fffbeb; --danger: #dc2626; --danger-bg: #fff5f5; /* Surface */ --body-bg: #f0f4f8; /* Page background */ --card-bg: #ffffff; /* Card / panel background */ --border: #e5e7eb; /* All borders */ /* Typography */ --text: #1a1f36; /* Primary text */ --text-muted: #6b7280; /* Secondary / label text */ /* Component */ --card-radius: 14px; --card-shadow: 0 2px 10px rgba(0,0,0,0.06); }
Database Tables
11 tables power the entire platform. All schemas are defined in
.tables/schema.json and seeded with realistic Indian hotel network data.properties
27 fields β name, city, state, rooms, floors, status, total_aps, online_aps, active_guests, guest_score, bandwidth_mbps, group_id, isp_name, wan_ip, contact_*
access_points
23 fields β property_id, name, model, mac, ip_address, status, floor, location, clients, rssi, uptime, channel, band, firmware, config_*
guest_sessions
21 fields β property_id, ap_id, device_name, mac, ip, room, ssid, status, connected_at, duration, download_mb, upload_mb
support_tickets
21 fields β property_id, title, description, priority, category, status, reporter_*, assignee_*, resolution, opened_at, resolved_at
users
14 fields β name, email, phone, role, property_id, group_id, status, last_login, permissions
alerts
14 fields β property_id, type, title, message, source_device, source_ip, read, resolved, acknowledged_by, occurred_at
network_topology
15 fields β property_id, type, label, x, y, status, ip, mac, extra_data (JSON), parent_id
speed_tests
12 fields β property_id, download_mbps, upload_mbps, ping_ms, jitter_ms, packet_loss_pct, rating, triggered_by, tested_at
ssids
15 fields β property_id, name, type, vlan_number, security, band, status, clients, captive_portal, rate_limit_*
vlans
17 fields β property_id, vid, name, subnet, gateway, dns_primary, purpose, internet_access, client_isolation, pci_scope
audit_log
15 fields β property_id, user_id, user_name, user_role, action, resource_type, resource_id, resource_name, changes, ip_address, occurred_at, status
System fields: Every table record automatically gets:
id (UUID), gs_project_id, gs_table_name, created_at (ms), updated_at (ms). Do not manually set these β they are managed by the Table API. Audit Trail
Every mutating API call automatically writes an entry to the
audit_log table using the internal _writeAuditLog() helper. This is fire-and-forget β failures are caught and logged to console but never block the main operation.JavaScript β Audit Log Entry Structure
{
"id": "log-1716130800000-x9k2", // timestamp + random suffix
"property_id": "prop-001", // from window._SA_ACTIVE_PROP
"user_id": "usr-001",
"user_name": "V. Patel", // from window._SA_CURRENT_USER
"user_role": "super_admin",
"action": "UPDATE", // CREATE | UPDATE | DELETE
"resource_type": "property",
"resource_id": "prop-001",
"resource_name": "The Grand Mewar Palace",
"description": "UPDATE property \"The Grand Mewar Palace\"",
"changes": "{\"status\":\"warning\"}", // JSON string of changes
"ip_address": "", // client IP (not available in browser)
"user_agent": "Mozilla/5.0 ...", // first 100 chars
"occurred_at": "2025-05-19T10:00:00.000Z",
"status": "success"
}Methods that auto-write audit logs
PropertiesAPI.update() Β· PropertiesAPI.delete() Β· AccessPointsAPI.update() Β· AccessPointsAPI.reboot() Β· AccessPointsAPI.delete() Β· TicketsAPI.create() Β· TicketsAPI.assign() Β· TicketsAPI.resolve() Β· TicketsAPI.close() Β· UsersAPI.create() Β· UsersAPI.update() Β· UsersAPI.suspend() Β· UsersAPI.activate() Β· SSIDsAPI.create() Β· SSIDsAPI.update() Β· SSIDsAPI.delete() Β· VLANsAPI.create() Β· VLANsAPI.update() Β· VLANsAPI.delete() Β· TopologyAPI.updateNode() Β· TopologyAPI.deleteNode()
Seeded Production Data
All tables are pre-seeded with realistic Indian hotel network data to simulate a live production environment.
| Table | Seeded Rows | Sample Data |
|---|---|---|
properties | 6 hotels | Grand Mewar Palace (Udaipur), Taj Mahal Mumbai, ITC Bangalore, Oberoi Delhi, Leela Goa, Hyatt Pune |
users | 8 users | V. Patel (super_admin), Arjun Mehta (msp_engineer), Priya Nair (msp_engineer), Rahul Sharma (it_manager)β¦ |
support_tickets | 6 tickets | AP offline, captive portal issue, VLAN misconfiguration, WiFi dead zone, firmware upgrade, bandwidth alert |
alerts | 7 alerts | AP offline (critical), high bandwidth (warning), firmware outdated (info), WAN latency spike⦠|
ssids | 4 SSIDs | GuestWiFi (captive portal), StaffSecure (WPA2-Enterprise), IoTNet (open/isolated), Management (WPA3) |
vlans | 5 VLANs | VLAN 10 (Guests), 20 (Staff), 30 (Management), 40 (IoT), 50 (Security CCTV) |
speed_tests | 6 results | Ranging from 487 Mbps down / 211 up (Excellent) to 23 Mbps (Poor) |
audit_log | 5 entries | Property update, AP reboot, SSID toggle, user create, ticket assign |
Network Topology Module
The network topology builder is a pure SVG-based interactive diagram tool. It renders in
#topo-svg and uses vanilla DOM SVG API β no external library.Key Constants & Variables (
app.js)JavaScript
// Node dimensions const AW = 130, AH = 46, AR = 8; // AP node width/height/radius const NW = 140, NH = 52, NR = 10; // Standard node width/height/radius // Node type metadata const TOPO_TYPE_META = { isp: { icon: 'π', color: '#0277bd', bg: '#e1f5fe', label: 'ISP' }, router: { icon: 'π', color: '#c62828', bg: '#ffebee', label: 'Router' }, firewall:{ icon: 'π‘', color: '#e65100', bg: '#fff3e0', label: 'Firewall' }, switch: { icon: 'π', color: '#1565c0', bg: '#e3f2fd', label: 'Switch' }, ap: { icon: 'ap', color: '#2e7d32', bg: '#f1f8e9', label: 'Access Point' } }; // icon:'ap' triggers custom SVG drawing (router body + antenna + wifi arcs) // State let topoNodes = []; // All node objects let topoLinks = []; // Connections between nodes let topoSelected = null; // Currently selected node ID let topoNextId = 1; // Auto-incrementing node ID
ISP Node Extra Data Structure
ISP nodes carry a rich
extra object with all ISP account details. This is displayed as a 5-section detail panel on click.JavaScript
node.extra = {
ispName: 'FiberNet Broadband Pvt. Ltd.',
accountId: 'FBR-2024-001',
amName: 'Rajesh Sharma', // Account Manager
amEmail: 'rajesh.sharma@fibernet.in',
amMobile: '+91 98765 43210',
supportPhone: '1800-103-9999',
supportEmail: 'support@fibernet.in',
subnetIp: '203.0.113.0/24',
staticIp: '203.0.113.50',
gatewayIp: '203.0.113.1',
dnsPrimary: '8.8.8.8',
dnsSecondary: '8.8.4.4',
authPerson: 'Vikram Patel',
notes: ''
}; Charts & Canvas Rendering
GuestXP uses Chart.js 4.4.0 for line/bar/area charts and the native HTML5 Canvas API for custom gauge and heatmap rendering.
Chart.js β Light Theme Configuration
All charts use a consistent light enterprise theme. Key colors:
JavaScript
plugins: {
tooltip: {
backgroundColor: '#fff',
titleColor: '#1a1f36',
bodyColor: '#6b7280',
borderColor: '#e5e7eb',
borderWidth: 1
}
},
scales: {
x: { grid: { color: 'rgba(0,0,0,0.05)' }, ticks: { color: '#6b7280' } },
y: { grid: { color: 'rgba(0,0,0,0.05)' }, ticks: { color: '#6b7280' } }
}Canvas Gauge (
_gdDrawGauge)Draws a circular score gauge with gradient arc, center score text, and grade badge. Track color:
#e5e7eb. Arc gradient: #dc2626 β #1a73e8 β #16a34a based on score range.WiFi Heatmap (
gdRenderHeatmap)Renders a floor plan WiFi coverage heatmap on a canvas. Floor background:
#f8fafc. Grid lines: rgba(148,163,184,0.35). Coverage blobs: radial gradients from rgba(26,115,232,0.40) to transparent. Alerts & Toast Notifications
Toast API
JavaScript
// Property portal (app.js) showToast('AP rebooted successfully', 'success'); showToast('Connection failed', 'error'); showToast('Changes saved', 'info'); // Super Admin portal (super-admin.js) showSAToast('User invitation sent', 'success'); showSAToast('Ticket escalated', 'warning'); // GD tab toast (super-admin.js) gdShowToast('ISP details saved', 'success'); // Types: 'success' | 'error' | 'warning' | 'info' // Toasts auto-dismiss after 3β4 seconds
Naming Conventions
| Category | Pattern | Examples |
|---|---|---|
| CSS classes | kebab-case | .gd-kpi-card, .tfd-node, .sa-btn |
| CSS variables | --kebab-case | --primary, --card-shadow, --gd-kpi-accent |
| JS functions | camelCase | showToast(), topoClickNode(), gdRenderHeatmap() |
| JS private/internal | _camelCase | _gdDrawGauge(), _topoDrawNode(), _writeAuditLog() |
| JS state vars (SA) | _SA_UPPER_SNAKE | _SA_TABS, _SA_CURRENT_USER, _SA_ACTIVE_PROP |
| API namespaces | PascalCaseAPI | PropertiesAPI, AccessPointsAPI, TicketsAPI |
| DB table names | snake_case | access_points, support_tickets, guest_sessions |
| Record IDs | prefix-NNN | prop-001, ap-001, tkt-001, usr-001 |
| HTML element IDs | kebab-case | topo-svg, toast-container, sa-toast-container |
Error Handling Strategy
API Error Pattern
All API methods throw on non-OK HTTP responses. The calling code should use try/catch:
JavaScript
async function loadProperty(id) { try { const prop = await GuestXP.PropertiesAPI.get(id); renderProperty(prop); } catch (err) { console.error('[GuestXP] Load failed:', err.message); showToast('Failed to load property data', 'error'); // Don't rethrow β handle gracefully in UI } }
Audit log failures are silent:
_writeAuditLog() catches all errors internally and logs only to console with warn. It never blocks the main operation or surfaces errors to the user. This is intentional β audit logging should never degrade UX. Deployment
GuestXP is a static website β deploy to any static hosting platform.
-
1Use the Publish TabIn the Genspark platform, click the Publish tab to deploy your project instantly. No configuration needed β the platform handles CDN, HTTPS, and domain assignment automatically.
-
2Verify after deploymentOpen the published URL. Login with any test credential. Open browser DevTools console and run:
await GuestXP.DashboardAPI.getSummary()β should return live KPI data. -
3Alternative: Any static hostUpload all files to Netlify, Vercel, GitHub Pages, AWS S3 + CloudFront, or any web server. The Table API uses relative URLs so it only works within the Genspark platform environment.
No build step required: Commit β auto-pushed β deployed. The project has zero build dependencies. Every file is served as-is. Cache-busting headers are already set in
index.html meta tags.