Tour Dash started as a Lovable export — a generated front end with no working product behind it. It is now a real application: a Postgres database with row-level security, live authentication, a working marketplace loop from posting a job to leaving a review, and a design system built to hold up under scrutiny. This report is the honest version of that — what genuinely works, what is ready to show, and precisely what stands between here and taking payments from real agents.
The front end stopped being the product's problem. What remains is a small number of specific, nameable systems — chiefly money — that have to be connected before real agents can use it.
Three things are true at once, and it is worth holding all three in the room:
The fastest way to answer "is this still just an AI mockup" is to look at what lives on the server, because a mockup has nothing there.
| System | State | What it means |
|---|---|---|
| Accounts & sessions | Live | Real authentication. Signing up creates a database profile automatically via a trigger — brokerage, licence number, phone and service radius are captured at registration. |
| Access control | Live | Every table is protected by row-level security in the database itself, not by the app. A user cannot read another user's transactions or edit someone else's listing even if they bypass the interface entirely. |
| Geographic search | Live | Radius search runs as a database function, so filtering "within 15 miles" happens on the server across every listing — it does not download the table and filter in the browser. This is the difference between working at 50 listings and working at 50,000. |
| Live updates | Live | New listings appear without a refresh, over a shared realtime connection. A bug here — two screens fighting over the same connection and crashing the page — was found and fixed during this pass. |
| Notifications | Live | Generated by the database, not the app. Applying to a listing notifies the poster; approving notifies the applicant. Because it is a trigger, it fires no matter how the record was created. |
| Ratings | Live | Leaving a review recalculates the recipient's average rating and review count automatically, in the database. |
| File storage | Live | Avatars and listing photos upload to real storage buckets with per-user upload policies — publicly readable, but only the owner can write. |
| Mapping | Live | Mapbox integration with real pins, a search-radius overlay, and a basemap that follows light and dark mode rather than staying stuck in one. |
This is the demo. Every step below runs against the live database — nothing in this chain is simulated, and each step leaves a real record behind.
The posting form adapts to the job type — an open house asks for expected attendees and the hosting agent; a final walkthrough asks for punch-list items and the buyer agent's contact. Nine job types, each with its own fields. The address is geocoded on submission so it can be found by location.
On a live map with a search radius, or as a filterable list. Search from the header works across both. Filters and the map stay in sync.
The application is written to the database, and a notification lands for the listing agent without the app being involved.
Applicants are shown with their profile, rating and completed-job count. Approving does four things in one action: marks the application approved, creates the appointment, flips the listing to filled so nobody else applies, and notifies the person who got it.
With directions that open the real address in Maps and a contact action that dials or emails the actual client on the record.
And the rating on the profile updates itself.
The first reaction to this product was that it looked like generated software. That was a fair read of the original export, and it was fixed by removing what the generator left behind and finishing what it never started.
A dead stylesheet from the starter template that was never imported. Six font families loading on every page load when only one was used. The default "Oops!" error page. Fabricated placeholder people — Sarah Johnson, Michael Chen — sitting in the dashboard as if they were customers, alongside stock photos. A "John Doe" identity that appeared whenever a real name was missing.
Generated apps show you the happy path only. Every data screen now has a loading state shaped like the content it is about to show, a composed empty state that tells you what to do next, and an error state — instead of blank space or a spinner.
Job types were colour-coded with nine saturated rainbow colours. Tested against colour-blindness models, several were indistinguishable — two of them failed even for normal vision. Replaced with three measured, validated colour families, with the job type always written in words so colour is never the only thing carrying meaning.
A contrast failure on the calendar was measured at 1.11:1 — effectively invisible — and is now 16.15:1. Keyboard focus rings across the app. Numbers set in aligned figures so columns line up. Motion respects the operating-system reduced-motion setting.
Every interactive control was also audited for whether it actually does something. Several were decorative: a wallet show/hide-balance toggle wired to nothing, a calendar "Today" button that did not navigate, a header search that went nowhere, and directions and contact buttons that invented an address and a phone number rather than reading the record. All are now connected to real behaviour.
Split by whether it genuinely blocks a public launch. This is the section worth spending the most meeting time on, because most of it needs a decision before it needs code.
| Item | Status | Detail |
|---|---|---|
| Payment processing | Not started | There is no payment provider connected. The wallet is a working ledger — balances, history, filters, charts, a withdrawal flow — but requesting a withdrawal writes a record and moves no money. Connecting a provider such as Stripe is the largest remaining build, and it depends on the decisions below. |
| Job completion & payout | Not started | Nothing currently marks a completed appointment as done, which means no earnings are ever credited. The loop runs from posting to appointment, then stops. This is the missing link between the marketplace and the wallet, and it is a small build once the money model is decided. |
| Transactional email | Needs a provider | The project is on the platform's built-in mailer, which is rate-limited to a handful of messages per hour — we hit that ceiling creating a single account. Public sign-up cannot work until a real email service is connected. Small task, hard blocker. |
| Password reset | Half built | The reset function exists in the code but nothing in the interface calls it — there is no "forgot password" link and no page to land on. Anyone who forgets their password is locked out permanently. Depends on the email item above. |
| Licence verification | Decision needed | A real estate licence number is collected at sign-up and never checked against anything. For a marketplace sending strangers into clients' homes, whether the platform verifies licences or explicitly states they are self-declared is a liability question, not a feature question. |
| Legal copy | Needs review | The in-app terms and privacy text is generic placeholder wording, and it currently describes things that are not true yet — a secure payment system, bank transfers, and a specific 2.9% + $0.30 fee. It should be reviewed by counsel and matched to what the product actually does before anyone agrees to it. |
| Item | Status | Detail |
|---|---|---|
| Settings page | Partly cosmetic | Notification preferences do not save — they reset on reload. The "add card" form stores nothing (correctly, since card details belong with the payment provider, not in our database). The support form shows a confirmation but sends no message anywhere. |
| Custom domain | Not started | Still on the hosting platform's default address. A branded domain is a short task and matters for how the product is perceived. |
| Map key restrictions | Hardening | The mapping key is unrestricted. It should be locked to the product's own domain before public traffic, so it cannot be lifted and used elsewhere at your expense. |
| Automated tests | None | There is no test suite. Fine at this stage; it becomes important the moment more than one person is changing the code or real money is moving through it. |
| Off-site source backup | Not wired | The code currently lives locally and on the host. A remote backup repository should be connected — this is minutes of work and removes a single point of failure. |
These four answers unblock most of the remaining work. Engineering cannot pick them, and picking them wrong is expensive to reverse.
Does the client pay Tour Dash, which then pays the showing agent — with funds held until the job is confirmed complete — or do the two parties settle directly with Tour Dash charging a listing fee? That answer determines the entire payment architecture, the account structure agents have to register for, and the tax reporting obligations. It is the first domino.
Verified, manually reviewed, or self-declared with the risk disclosed. Each is defensible; the exposure is in doing none of them while collecting a licence number that implies otherwise.
A marketplace with listings in ten cities and two agents in each is empty everywhere. One metro area, seeded with enough agents on both sides to make the map look alive, is the only version of this that works at the start.
Needed for the site, the email sending address, and the map key restrictions — all three point at it.
Ordered by dependency rather than by size. Steps one and two are unblocked today and would take days, not weeks; step three is the substantial one and cannot start until the money model is settled.
Everything in this report traces to the code as it exists today: file by file, table by table, and verified on the live site rather than assumed from the build. Where something is half-finished it is described as half-finished, because the alternative is discovering it in front of a customer.