Resource Booking and Analytics Platform
Event registration and resource booking workflow.

Overview
For Busworld 2025, I developed a comprehensive event management platform for a leading Busworld Exhibitor. This enterprise-grade application unifies complex resource booking workflows—from visitor tickets to exclusive hospitality areas—into a single, seamless portal.
The platform was engineered to handle the scale of a major international trade show, supporting over 15 distinct markets with localized business rules while providing organizers with real-time visibility into capacity and performance.
Tech Stack: Nuxt 3, Vue 3 (Composition API), Pinia, Nuxt UI, Tailwind CSS, Zod Validation
The Challenge
Building a unified booking platform for an event of this magnitude presented several critical engineering challenges:
- Polymorphic Resource Management: The system needed to handle fundamentally different booking types (simple daily tickets vs. time-slotted hospitality tables) within a cohesive UI.
- Real-Time Concurrency: With thousands of attendees, preventing overbooking when multiple users vie for the last slot was paramount.
- Multi-Market Complexity: Supporting 15+ international markets, each with specific quotas, legal requirements, and content.
- Operational Visibility: Organizers required a “Mission Control” view to monitor the event’s pulse in real-time without performance degradation.
Technical Approach
Architecture: Unified & Reactive
I architected the solution using Nuxt 3 to leverage Server-Side Rendering (SSR) for performance and SEO, hydrating into a fast Single Page Application (SPA) for the complex booking interactions. The core philosophy was “Single Source of Truth”—sharing the same state management logic between the public-facing booking flow and the internal admin dashboard.
State Management: Relational Store Design
Using Pinia, I structured the useBookablesStore to mirror a relational database, enabling efficient updates and retrieval.
export const useBookablesStore = defineStore('bookables', () => {
// 1. Groups: High-level categories (Hospitality, Stand, Forum)
const groups = ref([])
// 2. Objects: Mapped by group for O(1) access
const objects = ref({})
// 3. Availabilities: Granular time slots
const availabilities = ref({})
// Computed properties transform raw data into UI-ready structures
const bookables = computed(() => ({
Hospitality: createBookablesForGroup('Hospitality'),
Stand: createBookablesForGroup('Stand'),
Forum: createBookablesForGroup('Forum')
}))
return { groups, objects, availabilities, bookables }
})
Component Architecture: Polymorphic Design
To avoid code duplication, I implemented a Polymorphic Booking Engine. The BookablesUniversal component dynamically reconfigures its form fields and validation logic based on the resource type passed via props, ensuring a consistent user experience across diverse booking flows.
Key Features & Solutions
1. Polymorphic Booking Engine
The Problem: Hardcoding separate forms for “Visitor Tickets”, “Hospitality”, and “Stand Tours” would lead to massive code duplication and maintenance nightmares.
My Solution: I built a universal component that adapts to the resource context. It uses Zod to generate validation schemas on the fly, enforcing business rules specific to the selected resource (e.g., strict guest limits for tours vs. flexible limits for hospitality).
// Dynamic Zod Schema Generation
const schema = computed(() =>
z.object({
quantity: z
.number()
.min(1)
.max(maxAllowedQuantity.value, {
message: `Only ${maxAllowedQuantity.value} spots remaining`
}),
extended_fields: z.object({
contact_phone: z
.string()
.regex(/^\+\d{1,3}\s?\d{4,14}$/, 'Include country code')
})
})
)
Impact: Reduced codebase size by ~40% and ensured that any business rule change propagates instantly across all booking types.
2. Real-Time Availability System
The Problem: In high-demand scenarios, “stale data” leads to overbooking. If User A sees a slot is free, but User B books it milliseconds before, User A’s subsequent attempt must be handled gracefully.
My Solution: I implemented a Smart Caching Strategy combined with Optimistic UI.
- Smart Caching: The store tracks timestamps and only refetches data if it’s “stale” (older than 60s), reducing API load.
- Optimistic Updates: The UI updates immediately upon selection to feel instant.
- Server Guard: The API acts as the final authority. If a conflict occurs, the UI rolls back and notifies the user.
async function getAvailabilities(groupName, objectId, { cache = true } = {}) {
if (cache && isFresh(lastFetched.value[groupName]?.[objectId])) {
return cachedData
}
// Fetch fresh data and update timestamp
await fetchAndCache(groupName, objectId)
}
Impact: Zero overbooking incidents during peak traffic and a snappy, responsive user interface.
3. Admin Analytics Dashboard
The Problem: Operations teams needed to filter through thousands of bookings across 15+ markets to make real-time capacity decisions.
My Solution: I built a client-side aggregation engine within the admin dashboard. By reusing the useBookablesStore, the dashboard performs instant filtering and aggregation (Total vs. Daily vs. Slots) without hammering the database for every view change.
Impact: Empowered the operations team to manage the event proactively, identifying high-demand areas instantly.
Technical Highlights
Smart Caching Strategy
Implemented a “Business-Aware” caching layer that balances data freshness with server load. Critical actions trigger a cache: false bypass to ensure absolute accuracy, while general browsing relies on cached data to keep the interface fast.
Context-Aware Validation
Leveraged Zod to create schemas that “know” about the current resource’s capacity. The validation logic isn’t just checking types; it’s checking business constraints (e.g., “You can’t book 5 seats if only 3 are left”), providing immediate, helpful feedback to users.
Responsive & Accessible Design
Built with Nuxt UI and Tailwind CSS, the platform features a mobile-first grid system. Complex data tables in the admin view use intelligent overflow handling to remain readable on tablets and phones, crucial for on-site staff.
Domain Expertise: Event Management
Capacity Management
The system is built around the core constraint of finite resources. Every architectural decision—from the nested store structure to the optimistic UI—was designed to handle the reality that “once a seat is gone, it’s gone.”
Internationalization at Scale
Serving 15+ markets required a deep understanding of localization. The platform handles not just language translation, but also market-specific business rules (e.g., different booking quotas for the German market vs. the Mexican market).
Results & Impact
Scalability: The platform effortlessly supported the concurrent booking activities of thousands of attendees across all international markets.
Operational Efficiency: The real-time admin dashboard eliminated the need for manual spreadsheet tracking, allowing the team to focus on guest experience.
Robustness: The multi-layered validation and concurrency handling ensured a 100% accurate booking record, building high trust with both the client and the attendees.
Key Takeaways
- Single Source of Truth: Sharing the state logic between the user app and the admin dashboard guaranteed consistency and reduced bugs.
- Optimistic UI requires Pessimistic Validation: Making the UI fast is easy; making it fast and correct requires a robust rollback mechanism when the server says “no.”
- Polymorphism Reduces Complexity: Treating different booking types as variations of a single “Bookable” entity simplified the codebase and made adding new resource types trivial.