A desktop-first auction access platform for a licensed vehicle broker. Many customers work inside the real auction experience through shared broker infrastructure, while each sees only their own bids, lots and purchases — isolation enforced above a platform the broker does not control.
This case study focuses on the delivery constraints, product choices, and workflow decisions that shaped the build.
Model
Broker access platform
Client
Electron desktop app
Upstream platforms
Three in production
ClientBidque
Service ProvidedProduct Architecture, Electron Desktop Development, Security Engineering, Full-Stack Development
Year2026
About Bidque.
The Goal
Convert one shared broker relationship into many isolated customer experiences. Each buyer enters with a personal access code, works inside the real auction experience, and sees only the activity that belongs to them.
The Challenge
The auction platform itself could not provide the separation the broker needed — so Bidque had to create it. Above a live third-party system, during real-time bidding, where a mistaken action can cost real money and customers may be competing for the same vehicle.
The Result
One internal model for customer isolation working across three upstream auction environments with materially different technical architectures, while the broker keeps central control of accounts, sessions, attribution and access.
Inside the Platform.
Bidque was built for a licensed vehicle broker whose customers buy through major North American auction platforms. The business model is established: the broker holds the commercial relationship and the auction access, and customers participate through the broker. The difficult part begins when many customers need to use that shared infrastructure independently.
From the auction platform's point of view, the activity still belongs to one broker. From the broker's point of view, those customers are separate commercial actors who may compete for the same vehicles and must never see one another's bids, purchases, watchlists, or financial context. Shipkit built the software layer that creates that separation — which was not primarily a UI problem, but an isolation, session, realtime and transaction-safety problem.
One Broker Account Is Not One Customer View
Auction platforms naturally show broker-level information: aggregate bids, watchlists, won vehicles, account details, transaction data. But Bidque's users are individual customers, and a customer should see their vehicles, their bids, their purchases, their own history — nothing else.
A separate login code by itself was not enough. Authentication tells the system who the customer is; it does not change what the upstream platform returns. So we treated customer isolation as its own security boundary rather than assuming the auction layer would enforce it for us.
Hiding Data in the Interface Is Not Security
The simplest version of this product would have loaded the broker view and hidden unrelated rows in the UI. That would have looked correct without being secure: if unauthorised records are still delivered to the client and only hidden visually, they remain available through page state, network responses, or developer tools. For competing customers, that is unacceptable.
We moved the filtering boundary earlier in the request lifecycle. Rather than asking the rendered page to hide information after receiving it, Bidque identifies relevant upstream responses and filters them before the page consumes the data. Visual filtering still exists where useful, but as presentation — not as the isolation mechanism. That was one of the most important architectural decisions in the project.
Filtering Systems We Do Not Control
Bidque integrates with live third-party applications that change independently of our release cycle, and different upstream systems expose data differently — REST responses, mobile-oriented APIs, server-rendered fragments, GraphQL responses, realtime event streams. A brittle parser written for one endpoint would have turned the integration layer into permanent maintenance debt.
We designed the filtering system around reusable rules: preserve the original response structure, filter contents rather than envelopes, identify relevant data through stable structural signals, avoid mutating unknown response families unnecessarily, and separate platform-specific detection from generic client-isolation logic. Because the host-specific bridge was kept deliberately thin, the same core logic can also move toward a mobile client.
Live Bidding Required Realtime Isolation
Static pages were only half the problem. Current bid, timer state, lot status and auction events arrive over realtime channels, and if those streams are broker-wide a customer could observe activity belonging to someone else. Filtering too aggressively creates the opposite failure: the user stops receiving legitimate updates for their own lot.
The realtime layer distinguishes the customer's allowed auction context from unrelated activity, and incoming messages are evaluated before the embedded page consumes them. Startup is handled explicitly, because the allowed-lot set may not exist yet when the page first loads — an explicit startup policy rather than pretending all authorisation context is available synchronously. For latency-sensitive actions, the bidding path was separated from slower general-purpose orchestration.
When a Mistake Costs Real Money
A bid is not a harmless UI mutation; it can be a binding commercial action. Ordinary web software can be tested freely in staging, but auction actions may have no perfect sandbox equivalent, and clicking to see what happens is not an acceptable debugging strategy.
So safety was built in layers. State-changing upstream actions are treated differently from read-only traffic, and unknown or sensitive action paths do not receive permission merely because the UI attempted them. Where actions are blocked or simulated in protected modes, Bidque still records the attempted intent — customer, lot, action, amount — preserving observability without requiring every development interaction to reach a live external system. The same interception architecture protects production traffic and supports safe testing, so there is not one set of rules for development and a different, less-tested set for production.
Client-side controls are not the final authority either: the platform can reconcile broker-side activity against Bidque's own records so unexpected actions are detected operationally. When the consequence of an error is financial, safety should not depend on one button, one validation rule, or one developer remembering a special case.
Access, Not Ownership of the Credential
The customer needs the capability of an authorised broker session without receiving the broker's underlying secrets. That is a standard credential problem until the product runs an external site inside a local desktop application.
Credentials are handled outside the normal renderer-facing interface: on desktop, privileged application code performs the sensitive session work rather than exposing secrets to the React UI layer. Logs were treated as part of the same surface — a system can protect secrets perfectly in the UI and still leak them through debugging output, so customer codes, session tokens and other protected identifiers are sanitised. That is easy to ignore during development and painful to fix once production logs already contain sensitive data.
Simultaneous Sessions, Leases and Stickiness
Several customers may need broker-controlled auction infrastructure at the same time, and those sessions are not always independent — authentication, session state, or upstream behaviour can create conflicts. We introduced controlled session allocation using persistent backend state rather than best-effort timing in the desktop application: account assignment, session slots, database-level locking, leases with expiration, recovery from abandoned allocations, and client polling for availability.
An important lesson was that stability did not come from aggressively rotating access. In this environment session stickiness was often safer — a customer stays associated with a stable broker-side context unless there is a reason to move them. That is product-specific engineering beating a generic infrastructure playbook.
One auction flow added redirects and an SMS verification step, where the system had to preserve authentication state while waiting for a human. If the allocation expired mid-flow, another customer could inherit an incomplete authentication context, so verification became part of the session state machine: pending authentication, code arrival, code matching, timeout, retry, invalid-code failure, duplicate delivery protection, session ownership. Human latency became part of the architecture.
Edge Cases a Normal Browser Hides From You
A production WebView integration surfaces problems that never appear in a normal browser tab: new-window navigation, third-party domains opening outside the protected flow, pages that expect to have been opened by another window, login pages that briefly render sensitive upstream UI during navigation, late-loaded scripts changing navigation behaviour. Each is a potential escape from the controlled client experience.
We solved them with navigation allowlists, protected window-opening rules, controlled environment emulation where required, renderer-level visual suppression during sensitive transitions, and reapplication of protective rules after SPA navigation or rerendering. Injected integration code was written to assume the upstream UI will change — idempotent behaviour, SPA route detection, rerender recovery, a small host boundary, and a path for shipping critical integration fixes faster than a full desktop release.
What We Refused to Build
Some of the best architectural choices in Bidque were features we deliberately did not add. We rejected a remote-desktop-style streaming architecture for the normal client experience: it would have added latency, worsened UX, complicated mobile distribution, and solved a problem that did not need to exist. We did not proxy all auction traffic through our own infrastructure, which would have created an operational bottleneck and collapsed many distributed customer sessions into one backend identity.
We did not rebuild the auction engine. Customers already understand the native experience, and recreating search, lot pages and live bidding would have duplicated mature upstream functionality while increasing transaction risk. Bidque focuses on the missing broker layer: identity, isolation, attribution, access and control.
We also avoided false abstractions. The broker's upstream financial capability is shared, so pretending the external platform exposes perfectly separate customer balances would have been a lie in software; where true separation does not exist, the safer choice is not to expose the shared financial layer to customers. And we did not generalise into a multi-broker SaaS before one real broker workflow was solved well.
The Broker Console
The broker manages auction accounts, customers, access codes, account assignment, activity, vehicle attribution and customer-level visibility from one admin panel, built on Next.js 15 with Prisma and PostgreSQL. Behind it the backend maintains customer identity, account relationships, session state, leases and allocation, allowed-lot ownership, audit records, reconciliation data and security policies.
The console is deliberately where the sensitive operations live — issuing access, adjusting it, revoking it — so the security surface of the platform is one screen with one audience.
Broker sign-in — the entry point to the console where customer access, sessions and attribution are managed.
The Result
Bidque gave the broker a software layer the auction platforms themselves do not provide. Customers use shared broker infrastructure while remaining operationally isolated: each sees their own lots, activity, bids, purchases and history, and the broker keeps central control over account access, customer identity, session ownership, attribution and operational visibility.
The system works across three upstream auction environments with materially different technical architectures while maintaining one internal model for customer isolation. Most importantly, the highest-risk behaviour was not left to UI convention — financial actions, credentials, realtime data and session state were treated as architecture.
Tech Stack
Next.js 15, Prisma and PostgreSQL carry the admin and backend layer — customer and account model, session allocation, audit and attribution, access-code authentication. The client is an Electron and React desktop application with an embedded WebView, a privileged host process, and strict renderer-host separation. Between them sits an injected JavaScript integration layer handling REST, GraphQL and WebSocket traffic, SPA route detection, and rerender-safe behaviour.
If you are scoping a marketplace, customer portal, or workflow-heavy MVP, start with the smallest transaction that proves the business works. Then estimate the cost, compare custom code against no-code, and decide which features belong in version one.
Lessons for building on platforms you do not control
Why not simply share the auction account with customers?
Because the account is the licence to trade. A shared credential gives every customer the ability to act as the broker, removes any record of who did what, cannot be withdrawn from one person without disrupting everyone, and exposes competing customers to each other's activity. The customer needs access, not ownership of the credential — those are not the same thing.
Is hiding other customers' rows in the interface enough?
No, and this was the central architectural decision. If unauthorised records are delivered to the client and only hidden visually, they remain reachable through page state, network responses and developer tools. The filtering boundary has to sit earlier in the request lifecycle, before the page consumes the data.
How do you develop software where a bug can cost real money?
By making safety architectural rather than procedural. State-changing upstream actions are treated differently from read-only traffic, sensitive paths are not permitted just because the UI attempted them, blocked actions still log intent, the same interception layer covers production and testing, and the server reconciles broker-side activity against its own records.
Can Shipkit build a platform on top of a third-party system?
Yes, and the useful skill is identifying which guarantees the upstream system does not give you, then moving those guarantees into your own architecture. That pattern — one privileged upstream identity, many downstream users, scoped access and complete attribution — recurs across brokerage, procurement, agency and reseller businesses.