Aplikacja full-stack

Gratia Maris

Samodzielnie zbudowany produkcyjny system rezerwacji apartamentów — projekt produktu, architektura, implementacja, testy i wdrożenie wykonane przez jednego developera. Zbudowany w Nuxt 4 i Cloudflare Workers. Stripe Checkout przetwarza płatności, a unikalność na poziomie bazy zapobiega double-bookingowi.

Informacje o projekcie

Rola
Samodzielnie odpowiadałem za cały cykl produktu: wymagania, UX, architekturę, implementację, testy i dostarczenie.
Okres
Lipiec 2026 · Niezależna budowa produktu
Zespół
Projekt samodzielny · 1 developer
Strona główna Gratia Maris z apartamentami nad morzem

Wyzwanie

Platformy rezerwacyjne często polegają na blokadach aplikacyjnych, które zawodzą przy równoległych żądaniach. System potrzebował gwarantowanej dostępności bez race conditions oraz pełnego panelu admina do kalendarza i zadań serwisowych. Kluczową decyzją architektoniczną było egzekwowanie unikalności na poziomie bazy danych zamiast dodawania rozproszonych blokad.

Kluczowa decyzja

Użyć ograniczenia UNIQUE w bazie jako ostatecznej blokady dostępności zamiast polegać na blokadach aplikacyjnych lub rozproszonych.

Podejście

Zbudowałem monorepo z frontendem Nuxt 4 i API na Cloudflare Workers (Hono + Drizzle ORM). Baza D1 egzekwuje UNIQUE(apartment_id, night) jako ostateczną blokadę overbookingu — świadomy wybór zamiast blokad Redis dla provable correctness przy równoczesnych zapisach. Webhooki Stripe obsługują pełny cykl płatności, a zdarzenia e-mail kolejkują się gracefully, gdy brakuje credentials. Panel admina używa Cloudflare Access lub cookie fallback.

Kluczowe elementy

  • Ograniczenie UNIQUE w bazie zapobiega race conditions przy double-bookingu
  • Stripe Checkout z weryfikacją zdarzeń webhook
  • Autentykacja admina przez Cloudflare Access lub cookie
  • Panel admina z kalendarzem rezerwacji i zadaniami serwisowymi
  • Integracja Resend z graceful fallback przez email_events

Architektura

  • Frontend Nuxt 4 z Pinia i komponentami PrimeVue
  • Cloudflare Workers + Hono REST API z Drizzle ORM
  • D1 SQLite z ograniczeniem UNIQUE(apartment_id, night)
  • Sesje Stripe Checkout z przetwarzaniem webhooków
  • Struktura monorepo: apps/web, apps/worker, docs
  • Pipeline CI z guardem D1, typecheck i buildem Nuxt

Rezultat

Wdrażalne MVP łączące bezpośrednie rezerwacje z płatnościami Stripe, gotowe na channel manager i produkcyjne klucze Stripe.

Nuxt 4PiniaPrimeVueCloudflare WorkersHonoD1DrizzleStripeTypeScript