Interactive resort map for viewing live cabana availability and booking poolside cabanas through a REST API.
- Interactive resort map rendered from an ASCII layout file and image tiles
- REST API for map data and cabana booking
- In-memory cabana booking state with immediate map refresh after booking
- Guest validation against the provided bookings file
- Human-readable validation and data-file error messages
- Automated tests for backend logic, API routes, and frontend booking flows
- Bun
Use the single entrypoint from the repository root:
./run.shCustom data files are supported:
./run.sh --map ./map.ascii --bookings ./bookings.jsonAbsolute paths are also supported:
./run.sh --map /absolute/path/to/map.ascii --bookings /absolute/path/to/bookings.jsonrun.sh installs dependencies, creates an optimized production build, and starts the production server on port 3000. Relative data-file paths are resolved from the repository root, so the command behaves the same from any working directory. Absolute paths and paths containing spaces are supported.
For development with hot reload, install dependencies and run Next.js directly:
bun install
bun run dev-
GET /api/mapReturns the tile grid and all cabana availability data. -
POST /api/cabanas/:id/bookBooks an available cabana for a valid guest.
Request body:
{
"room": "101",
"guestName": "Alice Smith"
}Run all automated tests:
bun run testRun the test watcher:
bun run test:watchRun lint:
bun run lintRun a production build check:
bun run buildThis solution keeps the app as a single Next.js project with App Router API routes so the frontend and backend can be launched with one command and share the same type definitions. The backend owns all file parsing, validation, and booking state, while the client only consumes the REST API and renders the map.
- Booking state is stored in memory, which keeps the implementation simple and matches the task, but it resets when the process restarts.
- The map is read from an ASCII file and translated into image-based tiles in the frontend, which keeps the API data-oriented and presentation-agnostic.
- The app favors a compact architecture over introducing a separate database, service layer, or dedicated state machine.
-
src/app/page.tsxMain client page and booking flow state. -
src/app/apiREST API routes. -
src/libServer-side data loading, validation, and booking logic. -
src/app/componentsMap and modal UI components. -
map.asciiDefault resort layout. -
bookings.jsonDefault guest data. -
AI.mdAI-assisted workflow notes.
- Booking is allowed only when room number and guest name match a guest in
bookings.json. - After a successful booking, the cabana is marked as booked immediately and the UI returns to the map.
- If a map or bookings file is malformed, the API returns a readable error message instead of failing silently.