Developer Documentation

HospitalityNet MSP Platform

Complete technical reference for developers building on, extending, or maintaining the HospitalityNet Managed Service Provider platform. Covers architecture, data model, component system, and deployment.

What is HospitalityNet?

HospitalityNet is a Managed Service Provider (MSP) platform purpose-built for the hospitality industry. It provides hotel groups, resorts, clubs, and convention centres with enterprise-grade WiFi network management, real-time monitoring, guest experience tracking, and support ticketing β€” all from a single, multi-tenant web dashboard.

🏨
Property Portal
Hotel staff dashboard, guest WiFi management, vouchers, tickets
βš™οΈ
Super Admin
MSP operations, NOC, group dashboard, topology, audit
πŸ“‘
Network Layer
AP monitoring, switch telemetry, ISP contracts, topology
πŸ—„οΈ
Data / API Layer
15 REST tables, full CRUD, audit logs, bandwidth history
Architecture

System Architecture

HospitalityNet is a 100% client-side static web application with no server-side backend. All data persistence is via the Genspark RESTful Table API.

Request / Response Flow

1
Browser loads static HTML/CSS/JS
No build step required. Files are served directly from the static hosting CDN. The browser parses index.html (Property Portal) or super-admin.html (MSP Dashboard).
2
JavaScript modules initialise
Inline <script> tags and external JS files (js/app.js, js/data.js, js/sa-data.js, js/super-admin.js) execute on DOMContentLoaded.
3
Seed data / synthetic data generated
A seeded PRNG (saRand()) generates 734 deterministic property records for the property list. The NOC/MSP view uses pre-seeded real DB data via the Table API.
4
Table API calls for persistent data
All CRUD operations use fetch('tables/{table}'). Responses are consumed directly in the browser. The API is CORS-enabled and project-scoped.
5
DOM rendered, charts drawn
Chart.js renders bandwidth/stream graphs. Native Canvas API draws the score gauge and WiFi heatmap. SVG canvas renders the interactive network topology diagram.

Key principle β€” No Backend: There is no Node.js server, Python backend, or database server to manage. The entire platform runs as static files. The Genspark Table API handles all data persistence. This means zero DevOps, instant deployment, and no server maintenance.

Stack

Technology Stack

Intentionally minimal. No build tools, no frameworks, no package.json. Pure vanilla web technologies with selective CDN libraries.

LayerTechnologyPurposeVersion
StructureHTML5Semantic markup, accessibility, SVG topology canvasHTML5
StylingCSS3 / Custom PropertiesLight enterprise theme, CSS vars for theming, responsive layoutsCSS3
LogicVanilla JavaScript (ES2022)All interactivity, data rendering, API calls, SVG manipulationES2022
ChartsChart.jsBandwidth, stream, WAN line charts4.x (CDN)
CanvasCanvas APIScore gauge, WiFi floor heatmapNative
IconsFont Awesome 6 FreeAll UI icons, device type icons, status indicators6.4.0 (CDN)
FontsGoogle Fonts β€” Inter + JetBrains MonoUI typography, code blocksCDN
DataGenspark Table APIRESTful data persistence for all 15 tablesv1
HostingGenspark Static HostingAutomatic git-based deploymentβ€”
Project

File Structure

A flat, well-organised project with clear separation between entry points, stylesheets, scripts, and assets.

hospitality-msp-platform/ β”œβ”€β”€ index.html ← Property Portal (main entry for hotel staff) β”œβ”€β”€ super-admin.html ← MSP Super Admin Dashboard β”œβ”€β”€ api-docs.html ← API Reference documentation β”œβ”€β”€ developer-docs.html ← Developer documentation (this file) β”œβ”€β”€ login-preview.html ← Login screen preview/mockup β”œβ”€β”€ README.md ← Project overview & production docs β”‚ β”œβ”€β”€ css/ β”‚ β”œβ”€β”€ style.css ← Global styles, network topology, ISP panel β”‚ β”œβ”€β”€ super-admin.css ← All super-admin & group dashboard styles β”‚ └── login.css ← Login page styles β”‚ β”œβ”€β”€ js/ β”‚ β”œβ”€β”€ app.js ← Property Portal JS (topology, guests, tickets) β”‚ β”œβ”€β”€ data.js ← Property Portal seed data (APs, guests, sessions) β”‚ β”œβ”€β”€ sa-data.js ← Super Admin seed data (734 props via PRNG) β”‚ └── super-admin.js ← Super Admin JS (Group Dashboard, charts, gauges) β”‚ β”œβ”€β”€ images/ β”‚ └── logo.png ← Platform logo β”‚ └── .tables/ ← Genspark table schema definitions (auto-managed) └── schema.json ← All 15 table schemas
JavaScript

JavaScript Modules

Four JavaScript files handle all platform functionality. Each has a distinct responsibility boundary.

js/data.js β€” Property Portal Seed Data

Defines all static demo data for the property portal: access points, switches, network events, guest sessions, support tickets, SSID profiles, bandwidth snapshots, and vouchers. Data is structured as JavaScript arrays/objects and imported inline by index.html.

// Key exports from js/data.js
const accessPoints = [ /* AP objects */ ];
const switches     = [ /* switch objects */ ];
const guestSessions = [ /* session objects */ ];
const tickets       = [ /* support ticket objects */ ];

js/sa-data.js β€” Super Admin Seed Data

Generates 734 property records deterministically via a seeded PRNG function saRand(seed). This ensures the same data is generated on every page load without network calls. Hotel groups, property metadata, health scores, and MSP staff are defined here.

// Seeded PRNG β€” deterministic random
function saRand(seed) {
  let s = seed % 2147483647;
  if (s <= 0) s += 2147483646;
  return () => { s = s * 16807 % 2147483647; return (s - 1) / 2147483646; };
}
// Generates 734 unique property records with same values every run
const _SA_PROPS = generateProperties(734);

js/app.js β€” Property Portal Logic

Handles all interactivity for the property portal: tab switching, AP list rendering, guest session table, ticket management, SSID configuration, bandwidth charts, the SVG network topology builder, and the ISP detail panel.

Key Functions

FunctionDescription
renderTopologyDiagram()Builds the static SVG topology for non-interactive card view
_topoDrawNode(svg, node, x, y)Draws individual AP/switch/router nodes on the SVG canvas
topoClickNode(nodeId)Shows the slide-in detail panel for a clicked topology node
topoISPEdit(nodeId)Renders the ISP detail editing form in the panel
topoISPSave(nodeId)Saves ISP detail edits back to node.extra, shows toast
showToast(msg, type)Shows a toast notification (success/error/info)

js/super-admin.js β€” MSP Dashboard Logic

Powers the entire super-admin dashboard: the SA tab system, property list with 734 entries, ticket management, the Group Dashboard with Chart.js charts, and the interactive network topology builder.

Key Functions

FunctionDescription
saShowTab(tab, btn)Lazy-renders each SA tab on first click, then shows/hides
_gdDrawGauge(canvas, score)Canvas API: draws animated score gauge for group health
gdRenderHeatmap()Canvas API: draws WiFi floor heatmap with AP markers
_gdBuildStreamChart()Chart.js: multi-line bandwidth stream chart
_gdBuildWANChart()Chart.js: WAN utilisation chart
gdTopoClickNode(nodeId)Group Dashboard topology node click handler
CSS

CSS Architecture & Theme System

The platform uses a light enterprise theme defined by CSS custom properties. No preprocessors required.

Core Design Tokens (CSS Variables)

/* Defined in css/style.css :root */
:root {
  /* Brand colours */
  --primary:        #1a73e8;   /* Google Blue β€” buttons, links, accents */
  --primary-dark:   #0d5bc7;   /* Hover state */
  --primary-light:  #e8f0fe;   /* Backgrounds, badges */
  --success:        #00c853;   /* Online status, positive */
  --warning:        #f59e0b;   /* Warning status, alerts */
  --danger:         #ef4444;   /* Offline, error, critical */

  /* Layout */
  --bg:             #f0f4f8;   /* Page background */
  --card-bg:        #ffffff;   /* Card background */
  --border:         #e5e7eb;   /* All borders */
  --shadow:         0 2px 10px rgba(0,0,0,0.06);

  /* Typography */
  --text-primary:   #1a1f36;   /* Headlines, labels */
  --text-secondary: #6b7280;   /* Body text, subtext */
  --text-muted:     #9ca3af;   /* Placeholder, disabled */
  --font-sans:      'Inter', system-ui, sans-serif;
  --font-mono:      'JetBrains Mono', monospace;
}

CSS File Organisation

FileScopeKey Blocks
css/style.css Property Portal + Global Reset, layout, header/nav, AP cards, guest table, network topology nodes (.tfd-node), ISP panel, toast, charts
css/super-admin.css Super Admin only SA sidebar, property list, ticket views, Group Dashboard (.gd-* prefix), topology canvas, badge/status styles
css/login.css Login page only Login card, animation, gradient background

Group Dashboard uses scoped CSS: All GD styles use the .gd-root scope class and .gd-* BEM-style naming to prevent collision with the rest of the SA dashboard. KPI cards use per-card CSS custom properties (--gd-kpi-accent, --gd-kpi-bg) for colour variation.

Database

Database Schema

All 15 tables, their field counts, primary key conventions, and foreign key relationships. Data is persisted via the Genspark Table API.

properties
idtext PK
group_idFK→groups
name, type, citytext
ap_count, health_pctnumber
contract_start/enddatetime
pms_integratedbool
tagsarray
hotel_groups
idtext PK
name, contact_nametext
property_countnumber
group_health_scorenumber
contract_tiertext
access_points
idtext PK
property_idFK→props
name, model, vendortext
statusonline|warning|off
clients, rssinumber
poe_switchFK→switches
switches
idtext PK
property_idFK→props
name, model, iptext
total_ports, poe_portsnumber
temperature_c, cpu_loadnumber
vlansarray
guest_sessions
idtext PK
property_idFK→props
ap_idFK→aps
mac, device_type, ostext
status, auth_methodtext
download_mb, rssinumber
support_tickets
idtext PK
property_idFK→props
assigned_toFK→msp_staff
status, prioritytext enum
category, subjecttext
sla_breachbool
msp_staff
idtext PK
name, email, roletext
dept, designationtext
is_activebool
tickets_assignednumber
vouchers
idtext PK
property_idFK→props
code, type, statustext
duration_minnumber
valid_from, valid_untildatetime
audit_logs
idtext PK
actor_idFK→staff/user
action, resource_typetext
changesrich_text JSON
occurred_atdatetime

ID conventions: All IDs are prefixed by entity type: prop-, grp-, ap-, sw-, tkt-, msp-, usr-p, vch-, ssid-, bw-, alog-, topo-. Use the prefix to identify entity type without a DB lookup.

Data Flow

Data Flow Diagram

How data moves through the platform from network devices to the management dashboard.

Real-Time Monitoring Flow

WiFi AP
PoE Switch
ISP / WAN
Monitoring Agent β†’ POST tables/bandwidth_snapshots every 5 min
Genspark Table API β€” persists data, returns JSON
Dashboard Charts
KPI Cards
Topology SVG
Feature

SA Tab System

The Super Admin dashboard uses a lazy-rendering tab system. Tabs are only initialised when first clicked, preventing unnecessary API calls and DOM manipulation on page load.

How It Works

// Each tab has an entry in _SA_TABS array
const _SA_TABS = [
  { id: 'overview',    init: initOverview,    rendered: false },
  { id: 'properties',  init: initProperties,  rendered: false },
  { id: 'group-dash',  init: initGroupDash,  rendered: false },
  // ...
];

// Tab click handler β€” lazy renders on first call
function saShowTab(tabId, btn) {
  const tab = _SA_TABS.find(t => t.id === tabId);
  if (!tab.rendered) {
    tab.init();         // only runs once
    tab.rendered = true;
  }
  // Show this tab's panel, hide all others
  hideAllTabs();
  document.getElementById(`sa-tab-${tabId}`).style.display = 'block';
}

To add a new tab: (1) Add an HTML panel <div id="sa-tab-newtab"></div> in super-admin.html. (2) Add a button to .sa-page-tabs. (3) Add entry to _SA_TABS array in js/super-admin.js. (4) Write the init function. See the Adding a Tab guide.

Feature

Network Topology Engine

The interactive network topology is built on SVG with a custom node rendering engine and a slide-in detail panel for each device type.

Node Drawing Architecture

// Node size constants β€” APs use compact size
const AW = 130, AH = 46, AR = 8;   // AP width/height/radius
const NW = 130, NH = 58, NR = 10;  // General node size

// TOPO_TYPE_META defines icon, colour, and bg per device type
const TOPO_TYPE_META = {
  isp:     { icon: '🌐', color: '#1a73e8', bg: '#e8f0fe', label: 'ISP' },
  router:  { icon: 'πŸ”€', color: '#0ea5e9', bg: '#e0f2fe', label: 'Router' },
  switch:  { icon: 'πŸ”Œ', color: '#8b5cf6', bg: '#ede9fe', label: 'Switch' },
  ap:      { icon: 'πŸ“‘', color: '#00c853', bg: '#dcfce7', label: 'AP' },
};

// _topoDrawNode renders foreignObject HTML inside SVG
function _topoDrawNode(svg, node, x, y) {
  const fo = createSVGElement('foreignObject');
  fo.setAttribute('x', x - NW/2);
  fo.setAttribute('y', y - NH/2);
  // AP nodes use inline SVG WiFi-AP icon
  // Upper-tier nodes use emoji icon in icon box
}

ISP Detail Panel β€” topoClickNode Type Branch

When a node is clicked, topoClickNode(nodeId) checks node.type and renders type-specific HTML. The ISP branch renders 4 sections: Account, Account Manager, Support, and Subnet/IP Details. Edit mode uses topoISPEdit() + topoISPSave().

Security

Roles & Permissions

The platform has two distinct user tiers with 5 role types. Permissions are enforced at the UI layer and should be enforced at the API layer in production.

Super Admin (MSP)
Platform-wide access
  • View all properties & groups
  • Edit any property config
  • Manage MSP staff accounts
  • View & manage all tickets
  • View full audit logs
  • Group dashboard & analytics
NOC Engineer
Network operations
  • View all properties
  • Manage & resolve tickets
  • Reboot APs remotely
  • View bandwidth & telemetry
  • Cannot create users
  • Cannot delete properties
Property Admin
Single-property owner
  • Full access to own property
  • Create & manage vouchers
  • View guest sessions
  • Create support tickets
  • Cannot access other properties
  • Cannot edit network topology
Front Desk / IT Manager
Operational access
  • View own property dashboard
  • View guest sessions
  • Create support tickets
  • Cannot edit SSID config
  • Cannot manage users
  • Cannot view billing
Security

Audit Trail

Every significant action in the platform must create an audit_logs record. The audit trail is immutable β€” records are append-only and should never be updated or deleted.

Auditable Action Types

Action CodeWhen to Use
LOGIN / LOGOUTUser authentication events
CREATENew record created (property, ticket, voucher, user)
UPDATERecord fields modified
DELETERecord soft-deleted
CONFIG_CHANGESSID, AP, or switch configuration modified
AP_REBOOTRemote AP reboot triggered
TICKET_CLOSESupport ticket resolved/closed
EXPORTData export performed
// Standard audit log entry pattern
async function writeAuditLog({ actor, action, resource, changes }) {
  return fetch('tables/audit_logs', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      id:            `alog-${Date.now()}-${Math.random().toString(36).slice(2,6)}`,
      actor_id:      actor.id,
      actor_name:    actor.name,
      actor_role:    actor.role,
      property_id:   resource.property_id || null,
      action,
      resource_type: resource.type,
      resource_id:   resource.id,
      resource_name: resource.name,
      changes:       JSON.stringify(changes),  // {field: [old, new]}
      ip_address:    'client-side',
      occurred_at:   new Date().toISOString()
    })
  });
}
Extending

Adding a New Table

Follow these steps to add a new data entity to the platform with full CRUD support.

1
Define the schema
Use TableSchemaUpdate tool with your new table's fields. Always include an id field of type text.
// Example: adding an "iptv_channels" table
TableSchemaUpdate({
  name: 'iptv_channels',
  fields: [
    { name: 'id',          type: 'text',   description: 'Channel ID' },
    { name: 'property_id', type: 'text',   description: 'FK β†’ properties.id' },
    { name: 'name',        type: 'text',   description: 'Channel name' },
    { name: 'number',      type: 'number', description: 'Channel number' },
    { name: 'is_active',   type: 'bool',   description: 'Active flag' }
  ]
})
2
Seed initial data
Use TableDataAdd to insert representative rows. Use prefixed IDs: iptv-001, iptv-002, etc.
3
Write fetch functions in JS
Add CRUD helpers to js/app.js or js/super-admin.js. Follow the existing pattern.
async function loadIPTVChannels(propertyId) {
  const { data } = await (await fetch(
    'tables/iptv_channels?limit=200'
  )).json();
  return data.filter(ch => ch.property_id === propertyId);
}
4
Add UI component
Add HTML markup to the relevant page/tab. Call your load function in the tab's init function. Render results to the DOM.
5
Document in API docs
Add a new endpoint section to api-docs.html covering GET, POST, PATCH, DELETE for the new table.
Extending

Adding a New SA Tab

The Super Admin tab system is designed to be extended. Follow these 4 steps.

// Step 1: Add tab button in super-admin.html
<button class="sa-tab-btn" onclick="saShowTab('iptv', this)">
  <i class="fa-solid fa-tv"></i> IPTV
</button>

// Step 2: Add tab panel in super-admin.html
<div id="sa-tab-iptv" class="sa-tab-panel" style="display:none;">
  <!-- Your HTML goes here -->
</div>

// Step 3: Add to _SA_TABS array in js/super-admin.js
{ id: 'iptv', init: initIPTVTab, rendered: false }

// Step 4: Write the init function
async function initIPTVTab() {
  const panel = document.getElementById('sa-tab-iptv');
  const channels = await loadIPTVChannels('prop-001');
  panel.innerHTML = channels
    .map(ch => `<div class="iptv-row">${ch.number} β€” ${ch.name}</div>`)
    .join('');
}
Deployment

Deployment

Because this is a static site, deployment is trivial. No build pipeline, no Docker, no server management.

1
Write your changes
Edit HTML, CSS, or JS files. Changes are auto-committed to the git repo on every file write.
2
Click Publish
Go to the Publish tab in the Genspark editor. One click deploys all files to the CDN.
3
Share the URL
The platform is live immediately. Share the published URL β€” no DNS config, no SSL setup needed.

Database persistence: All data stored in Genspark Tables is tied to your project. If you migrate to a different hosting provider, you will need to export and re-import your table data. The Table API follows standard REST conventions, making migration straightforward.

Setup

Local Development Setup

Since there's no build step, local development is instant. You just need a static file server.

# Option 1: Python (usually pre-installed)
python3 -m http.server 8080
# Visit: http://localhost:8080/index.html

# Option 2: Node.js serve
npx serve .
# Visit: http://localhost:3000

# Option 3: VS Code Live Server extension
# Right-click index.html β†’ "Open with Live Server"

CORS note: The Genspark Table API only works from the hosted platform URL, not from localhost. For local development, use the mock data in js/data.js and js/sa-data.js which require no network calls. The API layer activates automatically when deployed to the Genspark hosted environment.

Quality

Testing & Quality Checks

The platform uses Playwright for automated browser-based testing to catch JavaScript errors and rendering issues.

Pre-Deployment Checklist

  • Run Playwright on index.html β€” zero console errors/warnings
  • Run Playwright on super-admin.html β€” zero console errors/warnings
  • Run Playwright on api-docs.html β€” zero console errors
  • Test all SA tabs render without errors
  • Test Group Dashboard charts render
  • Test topology node click panel
  • Test ISP edit/save flow
  • Verify all Table API calls return 200/201
  • Mobile responsiveness check (Chrome DevTools)
  • Test search and pagination in property list

Console = zero tolerance: Any JavaScript error or unhandled promise rejection indicates a bug. The platform's quality bar is zero console output on all entry point pages after load and interaction.

HospitalityNet MSP Platform β€” Developer Documentation
v1.0 Β· May 2025 Β· Static Web App Β· 15 DB Tables Β· 4 JS Modules
API Docs Dashboard