Back to list

Pony Academy — Riding School Booking Platform

A welcoming website backed by resource-aware scheduling and Aurum

AurumNuxtBooking SystemsDomain-Driven DesignPaymentsVue.js

Overview

A custom Nuxt website and Aurum booking module that connect lesson discovery, horse and instructor availability, online payments, customer accounts, and school administration.

Technologies Used

Nuxt
Vue.js
TypeScript
Node.js
MongoDB
Tailwind CSS

The project

Pony Academy offers individual riding lessons for children. For a parent, booking starts with understanding the experience: how a lesson works, what equipment is provided, and how the instructor supports the child. For the school, every booking must fit a real schedule shared by instructors and horses.

I built the public website and the Pony Academy booking module on my Aurum framework. The scope connects a bespoke frontend with availability, bookings, payment integration, customer access, and an administration interface.

Visit Pony Academy

Pony Academy homepage, with lesson information and a clear booking call to action

A calm path from discovery to booking

The website introduces the first lesson before asking the parent to commit. It brings together the lesson structure, safety information, instructor profile, offers, and frequently asked questions, with a clear route into booking.

The booking journey breaks a complex decision into six steps: offer, date, instructor, horse, contact details, and payment. The interface presents availability through the booking API rather than asking the visitor to reconcile separate calendars. It supports guest booking as well as customer accounts; creating an account is optional.

The frontend uses Nuxt, Vue, TypeScript, and Pinia. Booking, account, and content integrations have their own module boundaries, so presentation components do not need to own scheduling or payment rules.

Pony Academy booking entry, showing optional customer accounts and the six-step booking journey

Scheduling two resources at once

A lesson requires both an instructor and a suitable horse. A free instructor does not make a slot bookable if the horse is unavailable, already booked, or needs a break.

I modelled availability around instructor schedules, horse blackouts, existing bookings, lesson duration, and horse workload rules. The calendar derives valid slots from these inputs instead of storing a second, potentially inconsistent calendar of bookable times.

The backend also protects against simultaneous requests. Creating a temporary hold and changing a resource schedule use the same resource-and-day locks within a database transaction. This makes conflicts a server-side business rule, even when two visitors or an administrator act at the same time.

The scheduling domain remains independent of Vue, HTTP, database drivers, and payment providers. That separation lets the same rules serve the public booking flow and administrative operations.

Payments as a booking lifecycle

A redirect back from checkout is not proof that a lesson has been paid for. The payment-return screen reads the booking state and distinguishes confirmed, pending, and failed outcomes.

SituationSystem behaviour
A customer starts checkoutTemporarily hold the selected resources and create checkout using an idempotency key.
A payment notification is repeatedApply the booking change once using a transactional event inbox.
A hold expires before payment arrivesHandle the late payment through a durable refund intent.
A customer returns from checkoutRead the booking state before showing confirmation.

The browser can retain the booking hold session for recovery after a refresh. Hold expiration, payment events, and cancellation policies remain under backend control. Notifications and reminder scheduling are recorded alongside booking changes, keeping follow-up work tied to the committed booking state.

Aurum for operations, Aurora for content

The Pony Academy module integrates with Aurum's Payments, Customers, Notifications, Storage, and Translations contracts. The school administration interface brings together offers, horses, instructors, availability, blackouts, bookings, and notification settings.

Customer identity belongs to the Customers module. A booking keeps its own historical contact and offer snapshots, while verified accounts can access their associated reservations. This keeps the lesson record understandable even when customer or offer details change later.

Aurora provides visual editing for website copy and images. The embedded site sends editing intentions to a trusted parent application, which authorizes and saves changes; the public frontend does not hold administrative tokens. Published content is loaded during server rendering, with defined fallbacks if the content service is unavailable.

This project extends Aurum beyond property websites: shared platform services support a different business domain while the public website retains its own identity.

Validation and engineering outcome

The booking code includes tests for resource conflicts, simultaneous holds and blackouts, permissions, payment idempotency, and scheduling boundaries. Payment scenarios can use a local fake provider, allowing failure paths to be exercised without real transactions.

The public website and booking entry are live. The engineering outcome is a connected product: parents can discover lessons and enter a guided booking journey, while the implementation gives the school a common model for resources, reservations, payments, and communication.

The central design decision was to keep business rules in the booking domain and shared capabilities in Aurum. That gives the frontend room to evolve without duplicating the rules that protect the school's schedule.

Interested in a similar project?

Get in touch

KB / PRIVACY

Your privacy. Your choice.

The website works the same whatever you decide. Analytics is off by default.

No choice saved yet

Remembering your choice

We store only your decision and its date in your browser (localStorage). Your choice lasts for 180 days. This is not an advertising identifier.

Optional analytics

With your consent, GoatCounter on our server counts pageviews, contact, CV, project, external link and Saldo download clicks, use of illustrative demos, section visibility and reading progress. Form content, searches and values entered in demos are never sent. We process the page path without queries or fragments, title, referring domain, browser, operating system, language, screen width and approximate country. Your IP address is used to handle the connection and determine the country; it is not saved in the statistics. We use no analytics cookies or session recordings. Statistics are retained for up to 180 days. Do Not Track and Global Privacy Control signals disable tracking.

You can withdraw consent at any time through Privacy settings in the footer. Withdrawal stops further tracking; it does not remove existing aggregate statistics. Rejecting does not send analytics events.

The data controller is Kamil Bartczak Software Development, Czarnowo 100, 66-600 Czarnowo, Polska, NIP 9261697200. Privacy questions: office@kamilbartczak.dev.