← Coursework

Canem: Pet Walker Booking System

A booking system for a pet walking marketplace, built as a layered service: a browser app over a REST API whose business rules check every booking before it reaches a relational store.

Course
Software Development in Teams
School
Universidad de Los Andes
Term
Spring 2019
Role
Backend Developer
Stack
  • Java
  • Java EE 7
  • EclipseLink
  • Apache Derby
  • Payara
  • Angular
  • TypeScript
  • Bootstrap
  • Maven
  • Arquillian
  • Postman
Code
Canem · localhost:4200localREST api :8080
C A N E MThree of its pages, in the app's own SpanishView
Paseadores
C A N E MInicioPaseadoresClientesZonasCentro de ayudaPQRIniciar sesiónRegistrarse
Filtrar por precio
Min
$0
Max
$25000
Filtrar por zona
Suba2Usaquen1Chapinero1Fontibon0
Filtrar por calificacion
★★★★★★★★★★★★★★★
BuscarReiniciar busqueda
Laura MéndezMe gusta pasear perroslaura.mendez@example.com$1,000
Ver más informacion
Camilo RuizMe gusta pasear perroscamilo.ruiz@example.com$3,000
Ver más informacion
Ana TorresMe encantan los canes!ana.torres@example.com$5,000
Ver más informacion
The booking site, as it runs. Three of its pages: the walker search, a walker's profile and the booking contract. Pick one in the sidebar.

Problem

Any marketplace that sells a person's time, from dog walkers to cleaners and tutors, has the same core: a provider says when and where they work, a customer books a slot, and the booking is then paid, rated and reviewed. The hard part is not the screens but the rules around the booking: a slot cannot end before it starts, a review can only follow a finished walk, a rating counts once, and nothing a booking depends on can be deleted from under it. Those rules have to hold whichever screen or client calls the system, so they cannot live in the browser. This project builds that core for a pet walking service in Bogotá, as a team of five over one semester.

Solution

The system is three tiers with calls in one direction: a browser app, a REST API, and a layer of rules over a relational store. The booking is the centre of the data model: each one ties a customer, a walker, a zone and their pets to exactly one time slot, one payment, one rating and one review, so every rule is checked against a single record. The URLs follow ownership, so a walker's slots live under that walker, and the API confirms the parent exists before it touches the child. Every rule sits in one layer of stateless services that turns a violation into the same clear error, tested inside a real application server while recorded API calls replay each resource's contract.

BrowserBooking web appwalker search, profile and contract pagesone feature module per resourcelist and detail share one pageAngular 6 · ng serve :4200 · 8 feature modulessearch, sign up, add zoneAPI clientone service per resourcebase URL set per environmentfailed calls become toastsHttpClient · HttpErrorInterceptorJSON over HTTP :8080APIAPI contract tests122 recorded requestsexpect 200, 204, 404 or 4123 of 10 collections run as ITsPostman · Arquillian · Payara :7070Root resourcesfour root paths under /apiJSON mapped to entitieslight lists, detailed recordsJAX-RS · RestConfig /api · 13 DTOsreplayed requests{id} checked, else 404Nested resourcesunder a walker, client, bookingslots, pets, payments, reviewsparent checked first, else 4048 locators · /paseadores/{id}/franjasentity from DTOrule broken: HTTP 412Rulesslot, pet, paymentAccount and slot rulesslot end not before its startvalid name, email and contactno delete while bookings exist10 @Stateless EJBs · 168 testsBooking rulesprice above zero, all partiesrating 0 to 5, one per bookingreview only after the walkContratoLogic · CalificacionLogicvalidated recordvalidated bookingPersistence layerone data class per entityqueries scoped by parent idschema generated at deployJPA · EclipseLink 2.6.5 · paseadoresPUStoreJPQL by parent idConnection poolconnections held by the serverfound by name, not by URLone transaction per callpaseadores_pool · 8 steady, 32 maxbooking and its partsSQL in one transactionBooking databasethe booking at the centre of the modelslot, payment, rating, review: one each10 tables and 2 join tables, seeded by handApache Derby · localhost:1527/paseadores
Every call passes one layer of rules before it reaches the store, and the booking record ties each slot, payment, rating and review to one walk.

Learnings

  • Learning

    The booking as the aggregate

    Making the booking the record that owns its slot, payment, rating and review gives every rule one place to look: one rating per booking, a review only after the walk, no deletion before it is paid and finished. Without that anchor the same rule gets checked in several places and the copies drift apart. This is what lets a marketplace add a new kind of charge or feedback later without auditing every screen that touches a booking.

  • Learning

    Rules in one layer, errors in one shape

    Validation in the browser protects one client; validation behind the API protects all of them, including the ones not written yet. Putting every rule in stateless services and mapping every violation to the same HTTP status with a readable message means a mobile app, a partner integration or a test script all get the same answer. That single contract is what lets several teams build clients against one backend in production.

  • Learning

    Tests at the boundary a client sees

    The rules were tested twice: 168 tests run the rules and data layers inside a real application server, and recorded API calls replay each resource's contract, expected status codes included, against the running service. Tests at the boundary catch what unit tests miss, from a wrong status code to a broken mapping between a record and its JSON. They are what let several people change the same API in parallel and find out before a client does.

← Back to coursework