KP
🚀 Flagship Project

StayMap Polska

A full-stack accommodation booking platform in Poland with a map-first approach, Polish AI search and real-time communication.

12

Django modules

44

Next.js views

25

test files

9

travel modes

Django 5Django REST FrameworkPostGISGeoDjangoRedisCeleryChannelsDaphneNext.js 14TypeScriptWebSocketOpenAIGoogle OAuthpytestDockerGitHub Actions

DEMO

Product in practice

Key project views showing map-first search, the booking flow, the host panel and real-time communication.

What you can check in the demo

accommodation search on the map

offer filtering

travel modes

host panel

booking flow

Polish AI search

real-time chat

Swagger/OpenAPI documentation

ORIGIN

Product problem

StayMap was created as a response to the problem of accommodation search, where location, price, availability and user needs are often scattered across different screens and filters.

Map as the main interface

In many platforms, the map is only an addition to the results list. In StayMap, location is the starting point — users discover offers directly on the map.

Pricing without seasonal context

Accommodation prices depend on dates, length of stay, season, holidays and number of guests. The dynamic pricing engine handles these rules in one consistent process.

Fragmented user journey

Guests, hosts and administrators often work in separate workflows. StayMap connects search, booking, communication, host management and moderation in one system.

SCOPE

My role in the project

This was an individual project — I designed and built the full application myself: backend, API, data model, business logic, integrations, frontend and live demo deployment.

Backend architecture

I designed the structure of 12 Django modules, model relationships, permission system and the booking lifecycle.

REST API + WebSocket

I built 47 DRF endpoints with Swagger/OpenAPI documentation and an ASGI layer with Daphne handling both REST and WebSocket communication.

Data and geolocation

I designed the PostgreSQL/PostGIS database schema, spatial queries, geographic indexes and location-based offer search.

Async tasks and integrations

I added Celery tasks, Redis in multiple roles, OpenAI integration, Google OAuth, transactional email and external location data sources.

DESIGN

System architecture

The architecture is split into layers: Next.js frontend, Django/DRF backend, WebSocket communication through Channels, PostgreSQL/PostGIS database and asynchronous background tasks with Celery.

01

Client

Browser and mobile users interacting with the booking platform.

BrowserMobileGuestHost
02

Frontend

User interface, routing, views and BFF proxy layer.

Next.js 14SSR/CSRBFF proxyTypeScript
03

API Layer

REST API, business logic, authentication and API contract documentation.

Django 5DRFSwagger/OpenAPIJWT
04

Real-time

WebSocket communication for chat and real-time status updates.

Django ChannelsDaphne ASGIWebSocketEvents
05

Data & Geo

Data model, bookings, location and spatial queries.

PostgreSQLPostGISGeoDjangoSpatial indexes
06

Async & Integrations

Background jobs, cache, AI search and external integrations.

RedisCeleryOpenAIGoogle OAuthNominatimOverpass

Why this architecture?

BFF proxy in Next.js

The frontend does not communicate directly with the backend. The proxy layer helps control requests, authentication and API structure.

ASGI for REST + WebSocket

Daphne makes it possible to handle standard HTTP requests and real-time chat within one application architecture.

PostGIS for location-based search

Location is the core of the product, so spatial queries are part of the data model instead of being an external add-on.

Redis in multiple roles

Redis handles cache, Celery broker and the WebSocket channel layer while keeping responsibilities logically separated.

FEATURES

Key technical features

Map-first UX + PostGIS

Geospatial accommodation search built with GeoDjango and PostGIS 3.4. Spatial queries, distance filtering, location-based ranking and integration with Nominatim and Overpass API.

Dynamic Pricing Engine

Multi-layer pricing engine: seasons, Polish holidays, weekends, extra guest fees and long-stay discounts. The final price is saved as a snapshot at the moment of booking.

Polish AI Search

OpenAI API interprets user queries in Polish and maps user intent to search filters. AI sessions include TTL and cost limits.

Real-time Chat

Django Channels + Daphne ASGI. WebSocket events: message.new, typing.start, typing.stop and message.read. Connection authorization is based on JWT.

Blind Reviews

Reviews are published only when both sides — guest and host — submit their opinion. This limits the influence of one review on the other and makes the process fairer.

Auth + Security

JWT with token rotation and HTTP-only cookies, Google OAuth, upload validation and rate limiting for AI, auth and upload endpoints.

CHALLENGES

Hardest problems to solve

Areas where the project required real technical decisions.

01

Redis in 3 roles

Redis had to work as application cache, Celery message broker and Django Channels layer at the same time, with proper database separation to avoid mixing data.

Separate Redis databases: db=0 for cache, db=1 for Celery, db=2 for Channels. Docker Compose health checks ensure Redis starts before the application.

02

ASGI + WSGI

Moving from WSGI to ASGI required understanding how HTTP request routing and WebSocket routing can work together in one application process.

asgi.py configuration with URLRouter for Channels and Django application wrapper for standard HTTP requests. Daphne as the main application server.

03

Dynamic pricing

Multiple pricing rules can overlap for the same date range: season, holiday, weekend and long-stay. The order of applying rules affects the final price.

Rule priority system with explicit order: base → season → holiday → extra guests → long-stay discount. Price snapshot saved atomically when creating a booking.

LEARNINGS

What I learned

ASGI vs WSGI architecture and when to use each of them

Geospatial queries with PostGIS — from theory to spatial indexes

BFF pattern in Next.js as a proxy layer between frontend and API

Managing complex booking state, deadlines and lifecycle

Redis as a multi-purpose tool — cache, broker and channel layer

Error monitoring, structured logging and thinking about application observability

ROADMAP

Planned product extensions

Features that naturally develop StayMap into a more complete travel product.

AI “When to go?” — date recommendationIsochrones — search by travel timeStripe — online paymentsTravel diary — photos after the stay

Interested in this project?

I would be happy to talk more about the technical decisions, architecture and problems I solved while building it.

StayMap Polska — Case Study | Krystian Potaczek