Delivered remotely for a business based in Barcelona, Spain. Names withheld by agreement.
Project Overview
Industry: Residential real estate — direct-to-investor property sales.
Type of solution: A two-sided marketplace: a token-authenticated REST API with a web administrative back office, and a cross-platform mobile application carrying two distinct role experiences.
Business context: There is a large, quiet market in houses that never reach a traditional listing. An owner inherits a property, relocates at short notice, or faces repairs they cannot fund, and needs a sale measured in weeks rather than months. The established route is to approach a cash buyer, receive one number, and accept or walk away. The seller has no comparison and no leverage; the buyer has market knowledge, capital, and the knowledge that the seller is in a hurry. On the other side, investors spend heavily on marketing to find those properties, and then have to evaluate them from a handful of photographs or a site visit they may not have time to make.
General users: Property owners selling directly; property investors buying for cash; and platform administrators who verify participants, approve listings and oversee transactions.
General purpose: To give the seller competitive tension where there was none, and to give the buyer enough structured evidence about a property to bid on it with confidence before ever standing in front of it.
The Business Challenge
One offer is not a market. A seller presented with a single number cannot tell whether it reflects the property's value or the buyer's assessment of their urgency. Without competition, there is no price discovery at all.
Nobody is watching the clock. A competitive window only works if it actually closes. The auction has to resolve, the winner has to be declared, the losing bids have to be settled and the next phase has to begin — at the moment the window expires, whether or not a single person has the application open.
A remote buyer cannot bid on three photographs. Investors need to understand roof age, systems age, what has been renovated and how recently, and the honest condition of every room. A conventional photo gallery does not carry that information, and a seller cannot be expected to know what to volunteer.
A seller has no reason to trust a stranger's bid. Accepting an offer from an unknown investor means believing the money exists. Without a mechanism to establish that, the highest bid is not necessarily the best one — and the seller cannot tell the difference.
The transaction does not end when the auction does. A winning bid opens a due-diligence period, during which the buyer usually wants to see the property. That means proposing times, agreeing one, and handling the cancellations and changes of mind that follow — all with both parties on their phones and neither in the same room.
Two products, one application. A homeowner listing one house and an investor evaluating many have almost nothing in common in what they see or do. Both had to ship in a single mobile application without either experience being compromised.
Everything happens by notification. A bid arrives, a window closes, an offer wins, a walkthrough is proposed. Each of these is time-sensitive, and each has to reach the right person and put them on the right screen with one tap.
Our Approach
Make the clock the primary actor. We built the transaction's forward motion into scheduled server-side processes rather than into user requests. Two timed windows run in sequence — a competitive listing window, and a due-diligence window that opens the moment the first one resolves. When a window expires, the platform promotes the leading offer, settles every other offer, notifies both sides and opens the next phase, unattended. This is the decision that makes the product trustworthy: the outcome cannot depend on who happened to be looking.
Turn listing into a structured survey. Rather than asking the owner to upload photographs, we built a guided sequence that walks them through the property area by area — elevations, each bedroom, each bathroom, living space, basement, garage, other rooms, and the mechanical systems — capturing images against each area together with whether that area has been renovated recently and what was done, plus make and serial details for major systems. The output is not a gallery; it is a condition dossier an investor can act on.
Gate participation rather than badge it. Buyers register with supporting evidence of funds, and the ability to place an offer is withheld at the API until an administrator has reviewed it. Verification is enforced in the offer path itself, not displayed as a label next to an unverified bid.
Put auction integrity on the server. One offer per buyer per property, a mandatory minimum increment on any improved offer, automatic detection when a leading offer is displaced, and an explicit separate path for raising an existing offer — all enforced server-side, where a client cannot negotiate them away.
Model every way a deal can end. Seller declines, buyer withdraws, the window closes with no offers, the owner closes the listing, the due-diligence period lapses — each resolves to its own distinct state, so the platform and its operators can tell them apart and respond to each appropriately.
Give the seller a route out of silence. A listing that attracts no offers is not a dead end. The owner is prompted to relist and restart the window, close it, or request a direct offer from the platform operator.
Treat notifications as a first-class subsystem. Every state change in the domain emits a durable notification record from the model layer itself, which is then delivered to the user's device and deep-links into the correct screen for their role and that event. Because the emission happens at the data layer, a change made through the mobile app, the back office or a scheduled process notifies identically.
Build one binary that is two applications. The mobile client resolves an entire navigation tree from the user's role at launch, so the owner and the investor each get an experience designed for them, with no compromise layer between.
Automate deployment from the start. Continuous integration drives scripted deployment to both staging and production, running database migrations, clearing caches and restarting application processes as part of every release.
The Solution
Guided property listing. A multi-step wizard covering location, dwelling attributes, homeowner association obligations, overall condition banding and a room-by-room photographic survey, with the address resolved to coordinates on submission.
Condition and systems metadata. Each surveyed area carries its own recent-renovation record and description, and major mechanical systems are captured with make and serial identification — giving a remote buyer evidence rather than impressions.
Administrative listing approval. No listing becomes biddable until reviewed. Approval is what starts the competitive window; rejection returns the listing to the owner with a route to correct and resubmit.
Verified buyer onboarding. Investors register with supporting funding evidence and an investment strategy classification, and are approved by an administrator before they can participate.
Map and list discovery. Buyers browse available properties on a map or as a list, ordered by proximity to their current location or to a searched address, with place autocomplete.
Competitive timed offers. One offer per buyer per property, raised through a dedicated improvement path subject to a server-enforced minimum increment, with the previously leading buyer notified the moment they are displaced.
Automatic auction resolution. At expiry the platform promotes the leading offer, settles all others, notifies the owner and the winning buyer, and opens the due-diligence period — with no manual step.
Staged due-diligence period. A second timed window with reminder notifications at defined intervals before expiry, resolving automatically to bind the property to the buyer.
Walkthrough scheduling. The owner proposes multiple slots; the winning buyer receives them as an actionable notification and confirms, declines, cancels or declares a visit unnecessary. Either side can cancel, with the counterparty notified and the offer's standing preserved. A confirmed slot can be written to the device calendar.
No-offer resolution paths. Relist and restart, close the listing, or request a direct offer from the operator.
Notification centre. A persistent record of every event affecting the user, separated into unread and read, with each entry deep-linking to the relevant screen.
Administrative back office. Participant verification and approval, listing review, offer inspection and manual intervention, walkthrough oversight, content pages, and role management — built on an established open-source administrative template with a database-driven, role-filtered navigation structure.
Key Features
Scheduler-driven transaction state machine Two sequential timed windows — competitive and due-diligence — resolved by scheduled server-side processes, so the transaction advances correctly whether or not anyone is using the application.
Structured room-by-room condition survey A guided capture sequence producing typed imagery per area with per-area renovation history and mechanical systems identification, designed to support a bid made without a site visit.
Verified-buyer gating on participation Funding evidence captured at registration and reviewed by an administrator, with the ability to make an offer withheld at the API until approval is granted.
Server-enforced auction integrity One offer per buyer per property, a mandatory minimum increment on improvements, and automatic displacement detection — all enforced server-side.
Automatic resolution and settlement Leading offer promoted, all others settled, both parties notified and the next phase opened, without a manual step or a user present.
Model-layer notification event bus State changes emit durable notification records from the data layer itself, so events raised by the mobile app, the back office or a scheduled process are communicated identically.
Role-aware push deep linking Every notification type routes to the correct destination screen for the recipient's role, turning a push message into a single-tap action.
Two role experiences in one application Separate navigation trees resolved from the stored role at launch, so the owner and the investor each get a purpose-built product from one shipped binary.
Proximity-based discovery Map and list browsing ordered by distance from the buyer's location or a searched place, with address autocomplete.
Technical Architecture
Mobile client. A cross-platform application of roughly forty-three thousand lines, maintaining two independent navigation trees — an owner experience built around a drawer and a multi-step listing flow, and an investor experience built around bottom tabs, map discovery and offer management. State is held in a central store with asynchronous action handling, over a single service module wrapping every API call. Device capabilities include camera and gallery capture with cropping, mapping, geolocation, place autocomplete, push notification handling and calendar integration.
API layer. A token-authenticated REST API with controllers partitioned by role over a shared base controller that standardises response envelopes, with role-checking middleware gating each route group and resource classes shaping every response payload.
Scheduled processing layer. Console commands executed on a fixed interval by the framework scheduler, responsible for resolving expired competitive windows, settling offers, opening and resolving due-diligence windows, and emitting staged reminders.
Notification layer. Domain state changes emit notification records through model-level observers; a single observer on the notification record resolves the recipient's registered device, composes a role- and event-aware payload and dispatches it to the push service.
Administrative layer. A server-rendered back office sharing the same models and database, built on an established open-source administrative template with database-driven, role-filtered navigation and an ordered role hierarchy.
Data layer. A relational database covering users and roles, properties, typed photo groups and per-area survey metadata, offers, walkthrough slots and notification records — with soft deletion and cascade cleanup across dependent records.
Supporting services. Cloud object storage for property imagery, a transactional email service, a geocoding service for address resolution, and a hosted push notification service.
Delivery pipeline. Continuous integration triggering scripted deployment to staging and production, including database migration, cache clearing and application process restart.
Flow: Mobile app (role-resolved) → Token-authenticated API → Domain models with observer-emitted events → Relational database → Scheduled timer processes resolving auctions and due-diligence windows → Notification records → Push delivery to devices
Technology Stack
| Category | Technology |
|---|---|
| Backend language | PHP |
| Backend framework | Laravel |
| Database | MySQL, migration-managed schema |
| API authentication | OAuth2 bearer tokens (Laravel Passport) |
| Roles & permissions | Role middleware on API routes; permissions package with ordered role hierarchy in the back office |
| Media handling | Media library package with cloud object storage adapter |
| Object storage | Google Cloud Storage |
| Push notifications | Firebase Cloud Messaging |
| Email delivery | SendGrid |
| Geocoding & places | Google Maps Geocoding and Places |
| Scheduled processing | Framework task scheduler with console commands |
| Admin back office | Blade server-rendered UI on an open-source Bootstrap/CoreUI Laravel admin template, with Laravel Mix, SASS and Chart.js |
| CI/CD | CircleCI driving Capistrano deployment across staging and production |
| Mobile framework | React Native with React |
| Mobile navigation | React Navigation (stack, bottom tabs, drawer, material top tabs) |
| Mobile state | Redux with thunk middleware; Axios; device-local persistence |
| Mobile UI libraries | NativeBase and React Native Paper, vector icons, SVG, bottom sheet, tab and pager views |
| Mobile device features | Maps, geolocation, Places autocomplete, image crop picker, grid image viewer, calendar event integration, date/time pickers |
| Mobile push & auth | Firebase Messaging with platform push modules; social sign-in SDK |
Technical Challenges & Solutions
| Challenge | Our Approach |
|---|---|
| A competitive window is worthless unless it reliably closes, and no user may be present when it does | Auction resolution was built into scheduled server-side processes running on a fixed interval: promote the leading offer, settle every other offer, notify both parties and open the next phase — idempotently, and independently of any request. |
| Two timed phases with different endings running back to back on the same property | Each phase carries its own timer, its own reminder schedule and its own set of participants, with the resolution of the first being what opens the second — modelled as distinct states rather than as one generic countdown. |
| An investor cannot commit money based on a photo gallery | A guided survey capturing typed imagery per room and feature, with per-area renovation history and mechanical systems identification, producing a structured condition dossier instead of an unstructured set of pictures. |
| An owner has no basis to trust an unknown buyer's offer | Funding evidence captured at registration and reviewed by an administrator, with the ability to place an offer refused at the API until approval is recorded — verification enforced in the offer path rather than displayed as a label. |
| Auction rules must not be negotiable by the client | One offer per buyer per property, a mandatory minimum increment on any improvement, and displacement detection all implemented server-side, with offer improvement handled through its own dedicated path rather than as an unrestricted update. |
| Every material event has to reach the right person, on the right screen, immediately | Notification records emitted declaratively from model-level observers on domain state changes, dispatched through a single point that composes a role- and event-aware payload, with the client routing each notification type to its correct destination screen per role. |
| An owner listing one house and an investor evaluating many need entirely different products | Two independent navigation trees resolved from the stored role at application launch, sharing networking, state and components while presenting purpose-built experiences from one binary. |
| A deal can end in several different ways, and they are not interchangeable | Every terminal condition — declined by owner, withdrawn by buyer, no offers received, closed by owner, window lapsed — resolves to its own distinct state, so the platform and its operators can respond appropriately to each. |
Security & Reliability
Token-based API authentication. The mobile application authenticates against an OAuth2 bearer token implementation, with the web back office using a separate session-based guard.
Role-gated route groups. Owner and investor API surfaces are separated into distinct controller namespaces, each protected by role-checking middleware, so an authenticated user of one type cannot reach the other type's endpoints.
Participation gating. The ability to place an offer is withheld at the API until an administrator has reviewed the buyer's submitted funding evidence — a check enforced in the offer creation path itself.
Administrative approval before exposure. No property listing becomes visible or biddable until an administrator has reviewed and approved it.
Standardised response handling. A shared base controller normalises success, validation and error envelopes across the API, and resource classes constrain what each response returns.
Recoverable deletion with cascade integrity. Domain records use soft deletion, and removing a parent record cascades to its dependent images, offers, scheduled visits and notifications so no orphaned data is left behind.
Durable event record. Every notification is persisted, not only pushed, so a user who misses or clears a device notification retains a complete record of what happened on their listings and offers.
Automated, repeatable deployment. Releases run through continuous integration into scripted deployment with database migration, cache clearing and process restart, so environments are provisioned identically and a release is not a manual procedure.
Operational visibility. Application log inspection is available to administrators from within the back office.
Scalability & Performance
Media offloaded to cloud object storage. Property surveys generate a large number of images per listing. Storing and serving them from cloud object storage rather than the application server keeps the application tier light and image delivery independent of application load.
Stateless API tier. Bearer-token authentication keeps API requests free of server-side session state, so application instances hold nothing that ties a user to a particular machine.
Filtering pushed to the database. Proximity-ordered discovery is computed in the database rather than by loading and sorting listings in application memory.
Constrained response payloads. Resource classes define exactly what each endpoint returns, so responses stay proportionate to what the screen consuming them actually renders — significant on mobile connections where listings carry many images.
Batch work moved off the request path. Auction resolution, offer settlement, phase transitions and reminder generation run as scheduled background processes, so none of that work is ever performed inside a user-facing request.
Debounced client-side search. Address autocomplete requests are debounced on the client, avoiding a request per keystroke against the geocoding service.
Push rather than polling. Time-sensitive events reach users through push notification rather than the client repeatedly asking the server whether anything has changed.
Business Outcomes
- A seller receives competing offers rather than a single take-it-or-leave-it number, introducing price discovery into a segment that previously had none.
- Offers are resolved on schedule and without intervention, so the competitive window means what it says and the outcome does not depend on who was watching.
- Buyers can evaluate a property remotely with structured evidence, because listing captures a condition survey rather than a photo gallery.
- Sellers have a basis for trusting the bids they receive, because participation requires reviewed funding evidence rather than self-declaration.
- The transaction continues past acceptance inside the platform, with a due-diligence period, staged reminders and property visit scheduling handled in-product rather than reverting to phone calls.
- A listing that attracts no interest has a defined next step, rather than simply expiring.
- Both sides of a two-sided marketplace ship in one mobile application, each with an experience designed for how they actually work.
- Operators retain oversight at the points that matter — participant verification, listing approval and intervention in individual transactions — through a dedicated back office.
- Releases are automated and repeatable across staging and production from early in the project's life.
Why it worked
Marketplaces fail in a specific and predictable way: the mechanism works when someone is watching it, and quietly does the wrong thing when nobody is. An auction that only closes because a user opened the app is not an auction — it is a suggestion. The first thing we established on this project was that the transaction had to advance on its own clock, correctly, unattended, and we built the timed resolution as scheduled server-side processes before building any of the screens that sit on top of it.
The second thing that decides whether a marketplace like this works is whether the item can be evaluated remotely. A photo gallery does not let an investor commit capital to a house. So we replaced "upload some photos" with a guided survey that walks an untrained seller through the property area by area and captures what a buyer actually needs to know — including the things a seller would never think to volunteer. That is a product design decision as much as an engineering one, and it is the reason a bid can be made before anyone visits.
The third is trust, and we treated it as a gate rather than as decoration. Funding evidence is reviewed by a person, and the ability to bid is refused by the API until that review has happened. A verification badge that does not stop anything is not verification.
Our team builds with that kind of judgement about which parts of a business process must be enforced by the system and which can be left to the people using it. Our teams work across Laravel and PHP API design, scheduled and event-driven backend processing, notification architecture, cloud media handling, and complex multi-role React Native applications — with automated deployment pipelines in place from the beginning rather than added once the project is already difficult to release.
Final Summary
Selling a house for cash outside the traditional market has always been a conversation with one buyer, where the seller has no comparison and no leverage, and the buyer knows both. On the other side, investors spend to find those properties and then have to judge them from photographs or a visit they may not have time to make.
Our team built a marketplace that changes both halves. A homeowner completes a guided survey of their property from their phone — area by area, with renovation history and mechanical systems captured alongside the imagery — producing a condition dossier rather than a gallery. Once approved, the listing opens a competitive window in which verified cash buyers, admitted only after their funding evidence has been reviewed by a person, place and improve offers under server-enforced rules.
What makes it a marketplace rather than a listing site is what happens when nobody is looking. Scheduled server-side processes close the window on time, promote the leading offer, settle every other one, notify both parties and open a due-diligence period with its own timed reminders — all without a user present and without a manual step. From there the platform handles property visit scheduling between the two parties, with every state change emitting a durable notification that deep-links its recipient straight to the screen where they can act on it.
The result is delivered as a single React Native application carrying two purpose-built role experiences over a Laravel API, with an administrative back office for verification and oversight, and automated deployment across staging and production. It gives a seller competitive tension where there was none, and a buyer enough evidence to bid without standing in the driveway — which is the whole proposition, and the only reason either side would use it.