Back to portfolio
Engineering case study / Rental marketplace

RentalHunt

A rental marketplace that connects property listings, applications, conversations, viewings, and paid access.

Development snapshot · September 2026Overview → architecture → implementation

The key boundary is a database commit: the application is recorded now; email and other provider work can finish later.

The problem

A renter’s expression of interest needs to reach the right landlord, open the right conversation, and leave a clear record of what happens next. A lost response or failed email should not turn that into a half-created application.

The approach

The web client sends an authenticated request to a shared application service. The service validates the current listing and saves the related product records together. External follow-up is processed after the database commit.

01 / How it fits together

Product state first. Follow-up work second.

This view follows the core application path. PostgreSQL holds authoritative product state, Firebase supplies identity, and a separate outbox worker processes committed follow-up work. Redis supports selected entitlement reads; it is not the source of purchased access.

System diagram
This view follows the core application path. PostgreSQL holds authoritative product state, Firebase supplies identity, and a separate outbox worker processes committed follow-up work. Redis supports selected entitlement reads; it is not the source of purchased access.

This view follows the core application path. PostgreSQL holds authoritative product state, Firebase supplies identity, and a separate outbox worker processes committed follow-up work. Redis supports selected entitlement reads; it is not the source of purchased access.

Request or data movementDeferred processing
Mermaid source

Website and identity

The Next.js website organizes listing and application features. Firebase identifies the signed-in person; the backend resolves their product profile and checks whether they can perform the action.

Shared domain service

FastAPI routes delegate to a shared application primitive used by manual, quick, and automated application paths. It checks current state under database locks instead of relying on what the browser previously displayed.

Product database and outbox

The application, listing conversation, optional initial message, and follow-up intent are written within the same transaction. A tenant/listing uniqueness constraint backs up the duplicate check.

Connected applications

Admin, sales, marketing, and a mobile prototype belong to the same RentalHunt system. Operator tooling combines backend commands with some direct product-data access; sales and communications also maintain their own operational records. They are not separate marketplace products.

The relationship behind the duplicate boundary

Data model
A renter profile can submit many applications, and a listing can receive many applications. The application table permits one row for each renter/listing pair. Conversations and follow-up events are coordinated by the application service.

A renter profile can submit many applications, and a listing can receive many applications. The application table permits one row for each renter/listing pair. Conversations and follow-up events are coordinated by the application service.

Labeled relationship
Mermaid source
02 / Follow one request

From “apply” to a landlord notification

The synchronous path confirms the application and conversation. A separate polling worker performs follow-up after commit. An optional viewing invitation depends on the listing’s current stage.

Step 1 of 5

Send the request

The website keeps a pending application intent and sends the listing, message, and consent alongside the current identity token. It preserves enough context to handle an uncertain response.

Sequence diagram
The synchronous path confirms the application and conversation. A separate polling worker performs follow-up after commit. An optional viewing invitation depends on the listing’s current stage.

The synchronous path confirms the application and conversation. A separate polling worker performs follow-up after commit. An optional viewing invitation depends on the listing’s current stage.

Call or state operationResponse
Mermaid source

03 / Engineering decisions

The choices visible in the implementation

What each approach enables, and the complexity it introduces.

01

Commit the application graph together

Related product records and follow-up intent are saved through one shared transaction, with database constraints for the important uniqueness boundary.

The tradeoff The local workflow can stay consistent even when email is unavailable. Delivery becomes deferred work that needs workers, retry states, and operational visibility.

02

Recover state after uncertain delivery

The browser reconciles application state after ambiguous responses, while checkout and provider work keep durable identities for repeated attempts.

The tradeoff The system can distinguish some retries from new work, but it needs more state transitions and a review path for outcomes it cannot prove.

03

Cache selected reads, retain database authority

Entitlement checks use scoped, expiring cache entries and support a fresh database path.

The tradeoff This can reduce repeated reads, but cache invalidation and purchase expiry still need careful handling. It does not remove the database from the access decision.

04 / Results & next steps

What the implementation establishes

Current boundaries

  • The reviewed development trees include recent work; this snapshot does not establish which features are currently deployed.
  • The mobile prototype does not yet demonstrate full contract parity with the current web/backend application flow.
  • External delivery and payment activation depend on worker processes and provider configuration that source review alone cannot verify.

Potential improvements

Possible next work; not implemented outcomes.

  • Add release and contribution annotations tying each engineering story to the version that shipped.
  • Validate mobile/API contracts and rehearse worker failure recovery in an isolated integration environment.

This case study describes an inspected implementation. Source code and configuration alone do not establish a current deployment or measured product results.

Save the written case study