Documentation/Reference apps/A real estate brokerage website in four schemas, open source as Haven
A real estate brokerage website in four schemas, open source as Haven
Haven is an open-source real estate brokerage website with listing search, tour requests and offers. Source on GitHub, live demo at haven.supero.live.
- apps
- real-estate
- workflows
- sagas
- marketplace
Overview
Haven is an open-source real estate brokerage website: one brokerage's listings and offers in four schemas, where the broker's Accept button runs a workflow that knows how to reverse itself.
Accepting an offer on a house changes two records. The offer becomes
accepted, and the listing it was made on stops being active. If the first write lands and the second does not, the brokerage holds an accepted offer on a home the public search still shows as available.Haven handles that with a workflow called
offer_accepted, declared in setup.py. Thirteen of the 19 reference apps in the repo define a workflow with on_error set to compensate. Haven's is the only one where two different record types each carry their own undo. The app's code is the haven folder of that repo.Four schemas, two of them readable without a login
schemas.py defines
Listing, Agent, Tour and Offer, one schema per table, and nothing else. Listing and Agent are named in PUBLIC_SCHEMAS, so the search page works for a visitor who has never signed in. I fetched https://haven.supero.live/api/public/listing with no credentials on 2 October 2026 and got 14 listings back, the same 14 that setup.py seeds: 12 active, one pending, one sold. The agent endpoint returned eight.The model is flat.
No schema references another, and a
Tour or an Offer copies listing_title and agent_name as plain strings. That keeps every list on screen to one read, with no second fetch to resolve a name.Search is done in the browser. The app loads the public listings once and filters them in memory with a text match on location and four dropdowns (listing type, property type, bedrooms, price band), and the search box on the home page hands its choices to the results page in the URL hash, as in
#/search?city=Oakland&beds=2.A buyer's portal that holds only that buyer's rows
Two roles carry policies.
tenant_admin is the broker. tenant_user is the buyer, and the whole of the buyer's access is ten lines:python
PolicyDef(role="tenant_user", default_access="none", rules=[
# Discovery — every signed-in buyer reads the public marketplace:
PolicyRule(entity="listing", can_read=True),
PolicyRule(entity="agent", can_read=True),
# Private — each buyer owns only their own tours and offers:
PolicyRule(entity="tour", can_read=True, can_create=True, can_update=True,
filter_field="owner_username", filter_match="$user.name"),
PolicyRule(entity="offer", can_read=True, can_create=True, can_update=True,
filter_field="owner_username", filter_match="$user.name"),
]),This is policy-based row scoping. The filter on
owner_username is applied by the server, so the portal's "my tours" and "my offers" tabs are ordinary list calls with no where clause in app.js.The broker's policy allows writes to all four entities. Delete is allowed on listings and agents only.
Requesting a tour does more than insert a row. An event binding on
@create:haven:tour starts the tour_confirmation workflow, which has an email step and an SMS step, and the binding takes the email recipient from user.email, the address of the account that made the request. A second binding on @create:haven:offer starts offer_received, whose Slack step posts the amount and listing title to an #offers channel.The demo buyer is seeded with five tours and five offers.
Where Haven stops and Lattice begins
Lattice is the repo's second real-estate app. The two share almost nothing. Haven runs one brokerage in one tenant; its config.py lists a single
default-tenant, and the live config.js reports isMultiTenant: false. Lattice runs three property-management companies side by side, with eight schemas, units nested under buildings and a rent ledger.Choose by date. Haven covers everything up to the moment an offer is accepted, and Lattice covers the years after someone moves in, when the questions are about leases, rent and repairs. Building for agents and buyers, start from Haven.
Clone the real estate brokerage website and press Accept
The full source is in apps/real-estate/haven. To run it:
bash
git clone https://github.com/supero-platform/supero-apps
cd supero-apps/apps/real-estate/haven
cp .env.example .env # set SUPERO_DOMAIN and SUPERO_PASSWORD in it, then:
./run.shSUPERO_DOMAIN can be any free name. No account is needed, and it is running in about two minutes at http://localhost:5675. The app code is MIT. Supero, the hosted platform it calls, is not open source.The login form at haven.supero.live lists two demo accounts: one buyer, one broker. On your own copy, sign in as the broker and open Offers. The offer on "Cozy Starter Condo" is seeded as
submitted against an active listing. Accept it, then reload the public search and look at that card.A different brokerage model is a different schema file, and that one you write at supero.dev.
On this page