Mastering Telecommunications Data Models: A Wi-Fi Hotspot ERD with PlantUML

In the rapidly evolving landscape of telecommunications and public Wi-Fi management, the ability to model complex data relationships is paramount for system architects. A Wi-Fi hotspot network is not merely a collection of access points; it is a sophisticated ecosystem requiring precise handling of guest identities, authentication events, session quotas, and bandwidth throttling policies. When designing a captive portal system, the underlying data model must seamlessly bridge the gap between user registration, network access control, and real-time usage monitoring. Without a clear, standardized data blueprint, developers risk creating fragmented databases that struggle to enforce session limits or track guest activity accurately.

Real-world system context and operational workflow illustration

Diagramming-as-code, specifically using PlantUML, offers a revolutionary approach to documenting these intricate telecommunications workflows. By defining the schema in code rather than dragging and dropping shapes, architects ensure that their data models are versionable, consistent, and easily auditable. This tutorial leverages VPasCode, the free web-based diagram-as-code editor, to guide you through building a comprehensive Entity-Relationship Diagram (ERD) for a Wi-Fi hotspot system. We will explore how to structure entities for guest credentials, authentication events, and policy enforcement, ensuring your documentation is as robust as the network it describes.

Understanding the Model: Purpose, Scope & Problem Framing

Diagram Abstraction & Representation

An Entity-Relationship Diagram (ERD) serves as the architectural blueprint for a database, defining the “things” (entities) within a system and how they relate to one another. In the context of a Wi-Fi hotspot, this diagram abstracts the physical hardware and software logic into logical data structures. It maps the lifecycle of a guest user from the moment they register (or are invited) through their authentication, active session, and eventual disconnection due to time or data limits. The diagram explicitly models the relationships between users, their credentials, the network zones they access, and the policies that govern their usage.

Target Domain Scope & Scenario

This specific ERD focuses on the core data requirements for a commercial or municipal Wi-Fi hotspot management system. The scope includes:

  • Identity Management: Storing guest profiles and their associated authentication credentials (passwords, tokens, or SMS codes).
  • Network Topology: Mapping Access Points (APs) and Network Zones (VLANs) to understand where traffic originates.
  • Session Lifecycle: Tracking the start, duration, and end of a guest’s connection, including real-time data usage metrics.
  • Policy Enforcement: Defining the rules (time limits, data caps) that automatically trigger session termination or throttling.

Crucially, this model addresses the “session limiter” problem: how the system knows when a user has exceeded their quota and needs to be disconnected.

Key Takeaways & Educational Insights

By constructing this diagram, you will gain a deeper understanding of how to model one-to-many relationships in telecommunications, such as a single guest having multiple authentication events or multiple sessions over time. You will also learn how to structure entities to support audit trails (e.g., Authentication_Event) and real-time monitoring (e.g., Bandwidth_Usage), ensuring your database schema is capable of supporting both operational needs and compliance reporting.

Complete Diagram & Full Source Code

Below is the complete visualization of the Wi-Fi hotspot data model. This diagram illustrates the flow of data from the guest user through the captive portal, across the network zones, and into the policy enforcement engine.

Descriptive Alt Text

@startuml
!theme plain
title Wi-Fi Hotspot Captive Portal Authentication and Guest Access Session Limiter ERD

/' 
This ERD models the data structures needed to support a Wi-Fi hotspot captive portal
authentication and guest access session limiter. The diagram covers guest identity and
credential management, captive portal authentication events, access point and network
zone assignments, active and historical guest sessions, session quotas and rate limits,
and policy enforcement records that determine when a guest must be disconnected or
throttled. It is intended to clarify how authentication, authorization, session tracking,
and usage limiting entities relate to one another in a hotspot management system.
'/

entity "Guest_User" as guest_user {
  * guest_id : UUID <<PK>>
  --
  full_name : VARCHAR
  email : VARCHAR
  phone_number : VARCHAR
  account_status : VARCHAR
  created_at : TIMESTAMP
  updated_at : TIMESTAMP
}

entity "Credential" as credential {
  * credential_id : UUID <<PK>>
  --
  guest_id : UUID <<FK>>
  credential_type : VARCHAR
  credential_value : VARCHAR
  is_active : BOOLEAN
  issued_at : TIMESTAMP
  expires_at : TIMESTAMP
}

entity "Captive_Portal" as captive_portal {
  * portal_id : UUID <<PK>>
  --
  portal_name : VARCHAR
  portal_url : VARCHAR
  auth_method : VARCHAR
  is_enabled : BOOLEAN
  created_at : TIMESTAMP
}

entity "Access_Point" as access_point {
  * ap_id : UUID <<PK>>
  --
  ap_name : VARCHAR
  mac_address : VARCHAR
  location : VARCHAR
  status : VARCHAR
  last_seen_at : TIMESTAMP
}

entity "Network_Zone" as network_zone {
  * zone_id : UUID <<PK>>
  --
  zone_name : VARCHAR
  vlan_id : INTEGER
  bandwidth_limit_mbps : INTEGER
  session_timeout_minutes : INTEGER
  is_guest_zone : BOOLEAN
}

entity "Authentication_Event" as auth_event {
  * auth_event_id : UUID <<PK>>
  --
  guest_id : UUID <<FK>>
  portal_id : UUID <<FK>>
  ap_id : UUID <<FK>>
  credential_id : UUID <<FK>>
  auth_result : VARCHAR
  failure_reason : VARCHAR
  client_mac : VARCHAR
  client_ip : VARCHAR
  occurred_at : TIMESTAMP
}

entity "Guest_Session" as guest_session {
  * session_id : UUID <<PK>>
  --
  guest_id : UUID <<FK>>
  ap_id : UUID <<FK>>
  zone_id : UUID <<FK>>
  auth_event_id : UUID <<FK>>
  session_status : VARCHAR
  client_mac : VARCHAR
  client_ip : VARCHAR
  started_at : TIMESTAMP
  ended_at : TIMESTAMP
  bytes_uploaded : BIGINT
  bytes_downloaded : BIGINT
}

entity "Session_Policy" as session_policy {
  * policy_id : UUID <<PK>>
  --
  policy_name : VARCHAR
  max_session_minutes : INTEGER
  max_data_mb : INTEGER
  max_concurrent_sessions : INTEGER
  idle_timeout_minutes : INTEGER
  is_active : BOOLEAN
}

entity "Policy_Assignment" as policy_assignment {
  * assignment_id : UUID <<PK>>
  --
  policy_id : UUID <<FK>>
  guest_id : UUID <<FK>>
  zone_id : UUID <<FK>>
  assigned_at : TIMESTAMP
  expires_at : TIMESTAMP
}

entity "Session_Limit_Event" as limit_event {
  * limit_event_id : UUID <<PK>>
  --
  session_id : UUID <<FK>>
  policy_id : UUID <<FK>>
  limit_type : VARCHAR
  limit_value : VARCHAR
  action_taken : VARCHAR
  triggered_at : TIMESTAMP
}

entity "Bandwidth_Usage" as bandwidth_usage {
  * usage_id : UUID <<PK>>
  --
  session_id : UUID <<FK>>
  recorded_at : TIMESTAMP
  upload_mbps : DECIMAL
  download_mbps : DECIMAL
  total_mb : DECIMAL
}

guest_user ||--o{ credential
guest_user ||--o{ auth_event
guest_user ||--o{ guest_session
guest_user ||--o{ policy_assignment

captive_portal ||--o{ auth_event

access_point ||--o{ auth_event
access_point ||--o{ guest_session

network_zone ||--o{ guest_session
network_zone ||--o{ policy_assignment

credential ||--o{ auth_event

auth_event ||--o{ guest_session

guest_session ||--o{ limit_event
guest_session ||--o{ bandwidth_usage

session_policy ||--o{ policy_assignment
session_policy ||--o{ limit_event

@enduml

Step-by-Step Architectural Walkthrough

Building a complex ERD like this requires a structured approach. We will break down the construction into four logical phases: setting the stage, defining the core entities, mapping the relationships, and refining the visual details.

Phase 1: Canvas Configuration & Layout Directives

Before defining any data structures, we must configure the rendering environment. In PlantUML, this is done using directives at the very top of the file. We start by declaring the diagram type and the theme.

@startuml
!theme plain

The @startuml directive initializes the ERD parser. The !theme plain directive is crucial here; it removes default styling and colors, providing a clean, high-contrast black-and-white look that is ideal for technical documentation and printing. We then add a descriptive title and a comment block using the /' ... '/ syntax to provide immediate context for anyone reading the code.

Phase 2: Declaring Core Entities, Actors, and Boundaries

The backbone of an ERD is the entity definition. In this model, we start with the primary actor: the Guest_User. This entity holds the PII (Personally Identifiable Information) and account status.

entity "Guest_User" as guest_user {
  * guest_id : UUID <>
  --
  full_name : VARCHAR
  email : VARCHAR
  phone_number : VARCHAR
  account_status : VARCHAR
  created_at : TIMESTAMP
  updated_at : TIMESTAMP
}

Notice the use of * to denote the Primary Key (PK) and UUID as the data type, which is standard for modern distributed systems to ensure uniqueness across multiple access points. The double dash -- acts as a separator between keys and attributes, improving readability. We then define supporting entities like Credential, Captive_Portal, and Access_Point, ensuring each has a unique identifier and relevant attributes like timestamps for auditing.

Phase 3: Mapping Data Flows & Key Interactions

The most critical part of this ERD is the Guest_Session entity. This acts as the central hub connecting the user, the network hardware, and the policies. It records the specific instance of a user connecting to the Wi-Fi.

entity "Guest_Session" as guest_session {
  * session_id : UUID <>
  --
  guest_id : UUID <>
  ap_id : UUID <>
  zone_id : UUID <>
  auth_event_id : UUID <>
  session_status : VARCHAR
  client_mac : VARCHAR
  client_ip : VARCHAR
  started_at : TIMESTAMP
  ended_at : TIMESTAMP
  bytes_uploaded : BIGINT
  bytes_downloaded : BIGINT
}

Here, we see Foreign Keys (FK) explicitly marked (e.g., guest_id : UUID <>). This establishes the logical link that a session belongs to a specific user and occurred on a specific access point. We also include bytes_uploaded and bytes_downloaded to track data usage, which is essential for the “session limiter” functionality.

Phase 4: Grouping, Annotations & Visual Polish

To enforce the “session limiter” logic, we introduce the Session_Policy and Policy_Assignment entities. This separates the rules (policy) from the application of those rules (assignment).

entity "Session_Policy" as session_policy {
  * policy_id : UUID <>
  --
  policy_name : VARCHAR
  max_session_minutes : INTEGER
  max_data_mb : INTEGER
  max_concurrent_sessions : INTEGER
  idle_timeout_minutes : INTEGER
  is_active : BOOLEAN
}

Finally, we define the relationships using the ||--o{ syntax. The || indicates a mandatory relationship (one guest must have a session), and the o{ indicates an optional relationship (a guest may or may not have a session, or a session may or may not have a limit event). This visual notation clearly communicates the cardinality of the data model.

Syntax & Keyword Deep Dive

PlantUML provides a powerful set of keywords specifically for ERD modeling. Understanding these allows you to create precise and semantically correct diagrams.

  • entity: Defines a table or class. The syntax entity "Name" as alias allows you to use a readable label on the diagram while using a shorter alias in relationship definitions.
  • ||--o{: This is the standard PlantUML relationship connector. || represents “one” (mandatory), and o{ represents “zero or many” (optional). This is used to denote one-to-many relationships, such as one Guest having many Sessions.
  • PK and FK: These are stereotypes. <> marks a Primary Key, and <> marks a Foreign Key. PlantUML renders these with specific icons to make the diagram self-documenting.
  • /* ... */ and /' ... '/: While /* is standard code comments, /' ... '/ is a special PlantUML block comment often used for long descriptions that appear in the diagram metadata or title area, ensuring the diagram remains clean while retaining context.
  • !theme: A directive that applies a global visual theme to the entire diagram, overriding default colors and fonts for consistency.

Best Practices & Pitfalls to Avoid

When constructing ERDs for telecommunications systems, adherence to best practices ensures the diagram remains useful as the system evolves.

  • Normalize Your Data: Avoid storing redundant data. For example, do not store the guest_email inside the Guest_Session table. Instead, link to the Guest_User entity via a Foreign Key. This ensures that if a user changes their email, you only update it in one place.
  • Use UUIDs for Distributed Systems: In a Wi-Fi hotspot environment with multiple access points, local auto-increment IDs can clash. Using UUIDs (Universally Unique Identifiers) as Primary Keys ensures global uniqueness across the entire network infrastructure.
  • Separate Policies from Assignments: Notice the Session_Policy and Policy_Assignment separation in this model. This is a critical design pattern. Policies are reusable templates, while assignments are the specific instances of a policy applied to a user. Mixing them leads to rigid, hard-to-maintain schemas.
  • Keep Relationship Lines Clean: Avoid crossing lines where possible. PlantUML’s automatic layout engine handles this well, but defining the order of entities in your code can sometimes influence the final layout to reduce visual clutter.

Start Building Telecommunications ERDs Faster with VPasCode

Instantly render, customize, and export your Wi-Fi hotspot data models in your browser with zero local installation required.

Scroll to Top