Portfolio

Real Estate Platform: BALTIC PALACE

In der östlichen Region von Mielno entsteht ein exklusiver Apartmentkomplex an der Ostsee, DUNE Resort. Dieses außergewöhnliche Projekt erinnert an luxuriös...

#Webseiten
Real Estate Platform: BALTIC PALACE

#Baltic-palace.com, Technik für ein Haus in Pobierowo

Vierundvierzig Zimmer und Apartments. Diese Zahl steht am Anfang, weil sie fast jede technische Entscheidung dieses Projekts erklärt. Baltic Palace ist kein Pensionsbetrieb und keine Kettenimmobilie, sondern ein Haus in genau der Größe, in der die eigene Website über die Marge entscheidet. Eine Kette verrechnet die Provision der Buchungsportale als Vertriebskosten. Ein einzelnes Haus an der polnischen Ostseeküste spürt sie unmittelbar.

Das Gebäude steht in Pobierowo im westpommerschen Dünengürtel, etwa hundert Meter vom Strandzugang entfernt, und wurde vom Architekturbüro MTA Architekci entworfen. Im Erdgeschoss liegen Empfangshalle, Bar, Restaurant, Behandlungsräume sowie ein SPA-Bereich mit zwei Becken und Saunen, dazu kommt ein Tagungsbereich. Diese Mischung ist folgenreicher, als sie aussieht, denn sie bedeutet drei Leserinnen und Leser, die nichts miteinander gemein haben: ein Paar für ein Wochenende, eine Familie für zwei Augustwochen und eine Tagungsorganisatorin, die wissen muss, wie viele Personen in den Raum passen.

Das Projekt lief 2017 und dauerte etwa sechs Wochen. Layout und Elementanordnung kamen vom Kunden. Meine Aufgabe war die Übersetzung in Templates, ein Inhaltsmodell und responsives Verhalten, nicht die Gestaltungsentscheidung.

#Wer diese Seite liest und wonach

Der Auftrag war nicht, Nachfrage zu erzeugen. Markenverkehr war vorhanden, die Seite sollte ihn nicht verlieren. Praktisch heißt das, der Buchungsweg muss das aushalten, was Menschen tatsächlich tun, und nicht das, was eine Vorführung tut. Sie öffnen zwei Tabs und vergleichen Termine. Sie drücken auf halber Strecke die Zurück-Taste. Sie beginnen im Zug am Telefon bei schwankender Verbindung und schließen drei Tage später am Laptop ab. Ein Buchungsprozess, der nur funktioniert, solange nichts Ungewöhnliches passiert, funktioniert nur in der Vorführung.

Das Tagungs- und Gruppenpublikum liest dieselben Seiten mit völlig anderen Augen. Es sucht Einschränkungen, keine Stimmung: Kapazität je Bestuhlungsvariante, ob die Pause im Restaurant stattfinden kann, wie weit der nächste Bahnhof entfernt ist. Diese Leserschaft entscheidet anhand einer Spezifikation, und eine Spezifikation, die in einem Fließtextabsatz vergraben liegt, findet niemand.

Der dritte Faden ist die Saison, und er hat die Technik stärker geprägt als alles andere. Verkehr auf der Website eines Ostseehauses ist keine Linie, sondern eine Folge schmaler Spitzen: Planung im Januar, das lange Maiwochenende, dann der Sommer. Dazwischen liegen Wochen mit einigen Dutzend Aufrufen am Tag. Eine Infrastruktur, die auf die Spitze ausgelegt ist, verbrennt den größten Teil des Jahres Geld. Eine Infrastruktur, die auf den Durchschnitt ausgelegt ist, bricht genau in der Woche zusammen, in der das Haus verdient.

#Der Buchungsweg und seine Bruchstellen

Das Frontend baut auf Tailwind CSS und Media Queries, mit Blick auf WCAG 2.1. Barrierefreiheit ist hier keine Formsache. Ein erheblicher Teil der Gäste ist älter, und ein Buchungsformular, das am Telefon in der Sonne gelesen wird, braucht einen Kontrast, den elegantes Hellgrau auf Weiß schlicht nicht liefert. Aus demselben Grund tragen die Formularfelder sichtbare Beschriftungen statt Platzhaltern, die beim ersten Tastendruck verschwinden.

Die Buchung läuft über ein eigenes Modul mit Stripe-Anbindung, serverseitiger Validierung und Speicherung in PostgreSQL mit AES-256-Verschlüsselung. Serverseitige Validierung ist neben der Browservalidierung nicht überflüssig. Das Formular nimmt einen Datumsbereich entgegen, und ein Datumsbereich ist das Feld, das sich in jedem Buchungssystem am leichtesten brechen lässt: Zurück-Taste, zwei offene Tabs, ein Termin, der beim Laden der Seite frei war und beim Absenden belegt ist. Jeder dieser Fälle sieht von der Clientseite aus wie ein einwandfreies Formular.

Der informative Teil über Pobierowo und das Haus ist auf die Suchanfragen ausgerichtet, die in dieser Gegend tatsächlich gestellt werden, mit beschleunigter Meldung von Änderungen über die Google Indexing API. Sicherungen laufen automatisch auf Amazon S3, mit regionsübergreifender Replikation, Versionierung und Zstandard-Kompression. Die Versionierung wiegt dabei schwerer als die Sicherung selbst, denn der Ausfall, der Beherbergungsbetrieben wirklich passiert, ist kein toter Server. Es ist eine Preisliste, die zwei Tage vor dem Maifeiertag mit der falschen Datei überschrieben wurde.

#Bildmaterial ist hier der Hauptinhalt

Galerien und die Darstellung des Baukörpers sind der schwerste Teil der Seite. Architektur- und Innenaufnahmen sind hier Inhalt erster Ordnung und keine Dekoration. Eine Kompression, bei der die Putzstruktur zu einem Fleck wird, nimmt dem Haus sein stärkstes Argument. Der Baukörper wird als dreidimensionales Modell in Three.js gezeigt, die Bildgalerien laden dynamisch über GraphQL mit srcset-Behandlung.

GraphQL hat hier einen konkreten Grund. Ein klassischer Endpunkt liefert für eine Galerie sämtliche Felder jedes Bildes, auch die, die eine Listenansicht nie benutzt, und eine einzelne Anfrage über ein Dutzend Objekte mit vollständigen Metadaten kann mehr wiegen als die Miniaturen selbst. Eine Abfrage, die ausdrücklich drei Felder verlangt, verschiebt diese Kosten vom Netz in die Datenbank, wo sie billiger sind.

Die Lage übernimmt ein Modul auf Basis von Mapbox GL JS mit GeoJSON-Daten und Kachelung. Bei einem Haus an der Küste beantwortet die Karte eine Frage, die niemand ausspricht: wie weit es wirklich zum Wasser ist, wo doch jedes Haus im Umkreis von einem Kilometer von sich behauptet, direkt am Strand zu liegen.

An dieser Stelle steht in vergleichbaren Fallstudien üblicherweise eine Liste von Ergebniszahlen. Hier steht keine. Auslastung, Buchungsvolumen und Umsatz gehören dem Haus und nicht der Fallstudie seines Dienstleisters, und keine dieser Zahlen ließe sich hier belegen. Was sich ehrlich sagen lässt und was sich auf ein nächstes Projekt überträgt, sind die Entscheidungen und ihre Gründe.

#Technische Herausforderungen und Lösungen

Das Gewicht der Galerie fiel zuerst im Test auf. Eine große Zahl hochauflösender Bilder verzögerte die erste Darstellung. Redis übernimmt das Zwischenspeichern der Abfragen, Fastly dient als zweite CDN-Schicht für die parallele Auslieferung der Medien. Die Trennung ergibt Sinn, weil Galerie und HTML-Dokument völlig unterschiedliche Invalidierungsprofile haben: Angebotstexte ändern sich alle paar Wochen, Aufnahmen aus einem Shooting praktisch nie. Beides unter derselben Cache-Regel zu halten bedeutet, entweder Bilder zu oft neu zu laden oder Texte zu selten zu aktualisieren.

Das dreidimensionale Modell bremste mobile Browser aus, was bei einem Haus mit stark mobilem Publikum ein reales und kein theoretisches Problem ist. Reduktion der Polygonzahl und Texturkompression mit Draco lösten die Übertragungsseite. Der Kompromiss gehört ausgesprochen: Jede solche Reduktion nimmt Detail weg, und das Detail ist der einzige Grund, warum das Modell überhaupt existiert. Die Grenze verläuft dort, wo der Baukörper noch als dieser Baukörper lesbar bleibt und nicht als beliebiger Block.

Das Buchungssystem stockte bei Verkehrsspitzen. Die Ursache ist strukturell. Eine Reservierung muss Verfügbarkeit prüfen, den Termin sperren, die Zahlung abwickeln und die Bestätigung versenden, und die Nutzerin wartet auf den letzten Schritt, obwohl sie nur am ersten interessiert ist. Die Trennung über RabbitMQ sorgt dafür, dass Sperre und Antwort sofort erfolgen, während Bestätigung und nachgelagerte Synchronisation in eine Warteschlange wandern. Rate Limiting auf Nginx-Ebene schützt denselben Endpunkt vor Doppelklicks und vor den Bots, die in der Saison Verfügbarkeiten abgrasen.

Veralteter Cache war die letzte dieser Baustellen und die kaufmännisch teuerste. Eine Angebotsänderung, die niemand sieht, ist ein Anruf mit Beschwerde. Varnish mit Purge über Webhooks und Edge Side Includes für dynamische Abschnitte löst das, ohne den Cache überall sonst aufzugeben. ESI beantwortet eine konkrete Spannung: Eine Zimmerseite besteht zu neunzig Prozent aus Inhalt, der sich monatelang nicht ändert, und zu wenigen Prozent aus Preis und Verfügbarkeit, die sich täglich ändern. Ohne diese Trennung müsste die Cache-Lebensdauer des ganzen Dokuments nach dem kurzlebigsten Fragment bemessen werden, was dem Abschalten gleichkommt.

#Eingesetzte Technik

Yoast SEO kümmert sich um Metadaten, XML-Sitemaps und Benachrichtigungen an Suchmaschinen. UpdraftPlus sichert nach Amazon S3 mit regionsübergreifender Replikation und AES-256-Verschlüsselung. Cloudflare stellt die CDN-Schicht mit Argo Smart Routing, Brotli-Kompression und Schutz gegen volumetrischen Verkehr. Redis hält den Objekt-Cache mit Sharding und Persistenz für Abfragen und Sitzungen. Varnish betreibt den Seiten-Cache über eigenes VCL, mit Grace-Modus und ESI.

Der Grace-Modus verdient einen eigenen Satz, weil er die am meisten unterschätzte Einstellung dieser Konfiguration ist. Er erlaubt, eine leicht veraltete Seite auszuliefern, wenn das Backend nicht antwortet, statt einen Fehler zu zeigen. In der Hochsaison ist der Unterschied zwischen einer zwei Minuten alten Seite und einer Fehlermeldung der Unterschied zwischen einer Buchung und keiner.

Lighthouse läuft automatisch in der CI/CD-Strecke auf GitHub Actions, sodass eine Leistungsregression bei der Änderung sichtbar wird und nicht in einer Beschwerde. RabbitMQ stellt Buchungsaufgaben und Bestätigungen mit Wiederholungen in die Warteschlange. Fastly ergänzt einen zweiten Auslieferungsweg für Medien mit geografischer Optimierung. Mapbox GL JS zeichnet die Karte mit Kachelung. GraphQL übernimmt das Laden von Galerie- und Informationsdaten mit Batching, und Git samt Strecke hält die Änderungshistorie in einem Zustand, in dem sich eine Sache zurücknehmen lässt und nicht eine ganze Arbeitswoche.

Es gehört dazu, zu sagen, was diese Liste nicht aussagt. Sie sagt nichts darüber, wie derselbe Stack in einem anderen Haus wirkt. Drei Cache-Ebenen bei vierundvierzig Zimmern und ausgeprägter Saison sind genau durch diese Verkehrsform gerechtfertigt. Bei gleichmäßiger Auslastung über das Jahr wäre dieselbe Konfiguration Ballast, dessen Pflege den Nutzen übersteigt.

SPA-Bereich und Tagungsräume verhalten sich im Inhaltsmodell anders als Zimmer, und diese Differenz wird leicht übersehen. Ein Zimmer hat Verfügbarkeit und Preis, ist also ein Datensatz. Der SPA-Bereich hat in diesem Sinn keine Verfügbarkeit, sondern Anwendungen, Öffnungszeiten und saisonale Einschränkungen. Ein Tagungsraum hat eine Kapazität, die sich mit der Bestuhlung ändert, und genau diese Zahl löst die Anfrage aus, nicht das Foto. Wer alle drei in einen einzigen Inhaltstyp presst, bekommt Felder, die in zwei Dritteln der Fälle leer bleiben, und eine Redaktionsoberfläche, in der sich nach einem Jahr niemand mehr zurechtfindet.

Die Saison hat eine zweite Folge, die weniger offensichtlich ist als die Last. Angebotsinhalte altern sprunghaft und nicht allmählich. Preise für das Folgejahr, Termine, die Speisekarte und der Umfang der SPA-Pakete ändern sich auf einen Schlag, meist im Herbst, und jemand im Haus muss dann ein Dutzend Stellen in einem Zug aktualisieren. Stehen diese Werte fest im Seitentext, bleibt immer eine Seite bis zum Frühjahr auf dem alten Preis. Das Inhaltsmodell trennt deshalb Beschreibung von Parameter, damit ein Parameter an einer Stelle geändert wird.

Ehrlicherweise gehört auch dazu: Die Ebene, auf die ein Umsetzer den geringsten Einfluss hat, ist in dieser Branche die wichtigste. Das Bildmaterial entscheidet stärker über eine Buchung als jede Ladezeitoptimierung. Aufgabe der Seite ist, diesem Material nicht im Weg zu stehen, es also nicht automatisch so zu beschneiden, dass der Baukörper abreißt, es nicht in einer Reihenfolge zu laden, in der das erste sichtbare Bild ein Flur ist, und es nicht auf ein Niveau zu komprimieren, auf dem der Himmel über der Düne in Streifen zerfällt.

Im Betrieb kostet nicht der Code am meisten, sondern die Abweichung zwischen dem, was auf der Seite steht, und dem, was die Rezeption sagt. Jede Integration, die diese Abweichung verkleinert, rechnet sich schneller als eine weitere Cache-Schicht, und das ist nach der ersten Saison meist die richtige Ausbaurichtung.

#Betrieb und Wartung

Die Seite braucht laufende Beobachtung. System- und Plugin-Aktualisierungen laufen über eine Testumgebung mit vollständiger Kopie und nicht über die Produktion mit Zuversicht. Am deutlichsten zeigt sich der Unterschied im Buchungsmodul: Eine Aktualisierung, die auf einer leeren Installation getestet wird, geht immer durch, weil es nichts zu zerstören gibt, während dieselbe Aktualisierung gegen eine Produktionskopie sofort offenlegt, dass das Plugin das Datumsformat bestehender Datensätze verändert hat.

Cloudflare, Redis und Fastly tragen die Leistung unter Last, Varnish und RabbitMQ die Stabilität der dynamischen Vorgänge. SQL-Abfragen laufen über zusammengesetzte Indizes, denn eine Verfügbarkeitssuche filtert immer gleichzeitig nach Datum und Zimmertyp, und ein Index auf einer dieser Spalten allein hilft dieser Abfrage nicht. Der Cache wird bei Inhaltsänderungen punktuell geleert und nicht pauschal, denn ein vollständiger Purge vor einem langen Wochenende bedeutet, dass die ersten mehreren hundert Aufrufe auf einen kalten Cache treffen.

Eine Spannung kehrt in jedem Beherbergungsprojekt wieder und wird besser vor dem Bau benannt als danach. Eigene Website und Buchungsportal beschreiben dasselbe Zimmer in zwei verschiedenen Sprachen. Das Portal erzwingt ein Beschreibungsformat, eine feste Ausstattungsliste und eigene Zuschnittregeln, weshalb es für jedes Haus am Ort gleich aussieht. Die eigene Seite ist der einzige Ort, an dem sich zeigen lässt, was das Formular des Portals nicht trägt: der Zuschnitt einer Terrasse, der Blick aus einem bestimmten Stockwerk, die Art, wie das Nachmittagslicht in den Speisesaal fällt. Wer die Portalstruktur kopiert, gibt seinen einzigen Vorteil auf und behält eine schlechtere Terminsuche.

Ausbaufähig ist die Seite in Richtung einer Anbindung an das Hotelsystem an der Rezeption, eines Moduls für Saisonaktionen oder eines Bereichs für Gästestimmen. Jede dieser Richtungen ist ein eigener Umfang, der nach Analyse kalkuliert und nicht nebenbei ergänzt wird.

Welchen Umfang hatte das Projekt BALTIC PALACE?#
BALTIC PALACE ist ein Projekt der Kategorie Webseiten, 2025 übergeben. Dahinter stehen WordPress, JavaScript, Redis, HTML5 und SASS.
Wie lief die Umsetzung bei BALTIC PALACE?#
Der Build lief rund sechs Wochen und ging 2025 live. Er steht auf WordPress, JavaScript, Redis, HTML5 und SASS. Das Layout kam vom Kunden. Darauf habe ich Templates und Content-Modell gebaut und die Pfade mit Traffic auf einer Produktionskopie geprüft, nicht auf einer leeren Installation.
Was war technisch am anspruchsvollsten bei BALTIC PALACE?#
Performance unter Last und Cache-Verhalten. BALTIC PALACE brauchte Staging nahe der Produktion.
Welcher Teil von BALTIC PALACE lässt sich bei einem weiteren Build wiederverwenden?#
Übertragbar ist die technische Schicht: WordPress, JavaScript, Redis, HTML5 und SASS. Sie sieht beim nächsten Build ähnlich aus. Nicht übertragbar sind das Content-Modell dieses Projekts und seine Integrationen, geschrieben auf die Daten eines Kunden und ein Briefing der Kategorie Webseiten. Ein zweiter Build beginnt mit einer Umfanganalyse, das Angebot folgt danach.

Sie brauchen ein FAQ für Branche und Zielmarkt? Wir erstellen eine Version passend zu Ihren Business-Zielen.

Kontakt aufnehmen