About the project

Volley is a service for the town: non-profit and free to run. Here is the problem it solves and how it is built.

The problem

The three public sand courts were organised by guesswork: messaging groups, people turning up with no room, matches left short. Nobody knew how many would play or whether the weather would hold.

The solution

An installable web app (PWA) where each person signs up for a 1.5-hour-30-minute slot on one of the 3 courts. Each court has 12 spots (6 per team) and the match is created when someone signs up first.

It is free, with no ads and no selling of data. The site you are reading is the public part; the app lives at /app.

What it does

  • Sign up and leave a spot, with a limit of 2 slots per day and sign-up closing 30 minutes before the start.
  • Faults for late cancellations (under 2 h): at 3 you cannot create or join new matches for 7 days.
  • Weather forecast per zone (Open-Meteo) and notices from the administrator.
  • Live updates and optional push notifications.
  • Admin panel: slot closures, notices, settings, and a superadmin who adds the rest of the team.
  • Spanish and English, accessible and mobile-first.

Try the demo without signing in

Architecture

Architecture diagramThe browser loads the static site from Cloudflare Pages and talks to Supabase for sign-in, data and live updates. Weather comes from Open-Meteo. Push notices leave from an Edge Function through the browser push services.Browser (PWA)Astro + React + TailwindCloudflare PagesStatic hostingSupabaseAuth (Google)Postgres + RLSSQL functionspg_cronRealtimeEdge FnOpen-MeteoWeather forecastBrowser push servicesGitHub ActionsTests + checks
The browser loads the static site from Cloudflare Pages and talks to Supabase for sign-in, data and live updates. Weather comes from Open-Meteo. Push notices leave from an Edge Function through the browser push services.

Technical decisions

Rules live in the database
Every table has RLS on and the important actions (sign up, leave, close a slot) are SQL functions. Even if someone tampers with the browser, the database enforces the rules.
Privacy by design
Nobody sees other people’s data: only the minimum to play, through RLS and functions that return just what is needed. Only what is needed to sign in with Google is stored.
Zero cost
Free static hosting, Supabase on the free plan, Open-Meteo with no key, and GitHub Actions. No paid services.
Static public site, separate app
The public site is plain Astro (fast, search-friendly). The React app loads only at /app, and heavy libraries such as the PDF one are not downloaded on the public side.
Ready to grow
The camera (QR) and notifications sit in an isolated module so it can be swapped for Capacitor if a native app ever happens.

Quality and security

  • Unit tests with Vitest for the rules, the texts and SEO.
  • SQL test blocks that run against the database and roll themselves back.
  • End-to-end tests with Playwright on desktop and mobile.
  • Continuous integration with GitHub Actions on every change.
  • Security headers (CSP), versioned SQL migrations and an in-house security review.

Tech stack

  • Astro
  • React
  • TypeScript
  • Tailwind CSS
  • PWA
  • Supabase (Postgres, Auth, RLS, pg_cron, Realtime, Edge Functions)
  • Open-Meteo
  • Vitest
  • Playwright
  • GitHub Actions
  • Cloudflare Pages

Status

In development, close to launch. The code is in a private repository: if you would like to see it for a hiring process or out of technical curiosity, write to me and I will give you access.

Contact· volleyplaya.dev@gmail.com