$ cd ../projects

8rooms @ Zora AI

My current work at Zora AI: moving a real-estate website's catalogue onto AWS with server-side rendering, and an MCP server so Claude can manage its listings.

Role
Full-Stack Engineer at Zora AI · remote
Year
2026
Type
Full-stack
Status
In progress

$ cat brief.md# In short

The problem
8rooms' property listings lived in Payload CMS, a listing change needed a rebuild, and search engines and link previews had to get the listing data in the first HTML.
My contribution
The catalogue move and migration scripts, server-side rendering on Amplify, the performance work, reliable contact-form delivery and the MCP server. Others on the team worked on the site's design and on separate services.
Result
A listing edit now reaches the site in about a minute with no rebuild, and the listings payload dropped from 496 KB to 33 KB.
Website
Running on AWS Amplify; work is ongoing. A client system, so there are no screenshots here

$ stats --summary# In numbers

496 → 33 KB
listings payload after compression
~1,400
images moved to S3
160
properties migrated
~1 min
from a listing edit to the live site, no rebuild

$ cat README.md# System overview

8rooms is a bilingual real-estate website in Serbia, and my client project at Zora AI. My work is the path a property takes from the database to a visitor's screen.

The catalogue moved off Payload CMS into a database table served by an edge function, with about 1,400 images across 160 properties moved to S3 and served through CloudFront. Property and listing pages now render on the server on AWS Amplify through a custom adapter, so Google and WhatsApp or Viber link previews see the real listing. On top of that I built an MCP server that lets Claude read and edit listings and images.

$ tree architecture/# How it fits together

Clients

  • Website

    Built SSR

    Bilingual site. Property and listing pages render on the server; the rest stays static.

  • Claude

    Reads and edits the catalogue through a connector or Claude Code.

AWS

  • Amplify compute

    Built

    Custom adapter, compression and server-side caching.

  • S3 + CloudFront

    Migrated

    Property photos and generated thumbnails.

Catalogue

  • Edge function

    Built

    Serves published properties and image URLs.

  • MCP server

    Built

    Tools for listings and images, with per-person access keys.

  • Database

    Migrated

    The catalogue table that replaced Payload CMS for properties.

$ git log --author=amar# My contribution

  • Moved the property catalogue off Payload CMS into a database table served by an edge function, so a listing edit reaches the live site in about a minute with no rebuild.
  • Wrote the migration scripts that moved the listings and roughly 1,400 images across 160 properties to S3, and redirected old property URLs to the new ones with real 301s.
  • Moved property pages, listings and a properties sitemap to server-side rendering on AWS Amplify through my own adapter: only those paths go to the compute, and every other page stays static on the CDN.
  • Cut the listings payload from 496 KB to 33 KB by compressing server-rendered responses with brotli or gzip, which Amplify's CDN doesn't do for compute answers.
  • Kept pages fast after cache expiry by answering recently seen properties at once and refreshing them in the background, and added a 5-minute warm-up job against cold starts.
  • Served images through CloudFront, with generated thumbnails for property cards.
  • Made the contact form save every inquiry to the database before emailing it, with a column that flags unsent ones and a honeypot field against bots.
  • Built an MCP server that lets Claude read and edit listings and images, through a Claude connector or Claude Code. Each person uses their own access key, and each change is recorded under its owner.

$ cat fixed-bugs.md# Challenges I solved

  1. Search engines and WhatsApp or Viber previews only saw a listing after the browser had fetched it.

    Property pages render on request from the live catalogue, so title, description and share image are already in the first HTML.

  2. A listing page arrived as 496 KB of HTML, because the CDN compressed static files but passed server answers through unchanged.

    The server now compresses its own answers with brotli or gzip according to the request, bringing that page down to 33 KB.

  3. The first visitor after a quiet spell waited 1.5 to 3 seconds for a cold start.

    A scheduled job opens the key pages every 5 minutes, so the compute and the catalogue function stay awake and their caches stay full.

  4. A broad cache rule for HTML overrode the property pages' own header, so the CDN never cached them.

    Property paths got their own rule with the server's value, and pages are cached briefly on the CDN and in server memory, with errors left uncached.

$ cat package.json# Stack

TypeScript · Node.js · AWS S3 · CloudFront · Amplify · SSR · Edge functions · MCP · Payload CMS (migrated off)

# Next project in the logAgentic Video Editing