DeskFlow Studio is a portfolio demo for configuring one modular desk product in 3D and carrying its commercial context through a Buyer-to-Sales quote workflow. It demonstrates how product configuration, authoritative pricing, role-scoped actions, and quote lifecycle rules can live in one coherent Next.js application.
Configurable products often split the customer experience from the sales process. Buyers communicate dimensions and finishes through screenshots or free-form messages, while sales teams reconstruct the same context before preparing a quote. DeskFlow Studio keeps the selected configuration, estimated price, shared view, quote terms, and decision history connected.
- One configurable product: a modular desk with constrained dimensions, three materials, and optional accessories.
- A responsive React Three Fiber preview with selectable views and a static fallback boundary.
- Buyer workspace for creating, editing, saving, and sharing designs.
- Read-only bearer share URLs whose token can be rotated to revoke the previous URL.
- Buyer quote submission based on a server-recomputed catalog price.
- Sales pipeline and quote review with discount, lead time, optional note, and final price.
- Buyer acceptance or decline with a persisted quote event timeline.
- Role-scoped demo sessions entered through Buyer and Sales buttons, with no username or password.
- Buyer: enter the demo as Buyer, create a design, adjust dimensions, material, accessories, and camera view, then save it.
- Buyer: optionally copy the read-only share URL or rotate it, then request a quote. An active quote locks the design against commercial drift.
- Sales: switch roles at
/demo, open the incoming request, start review, set discount and lead time, add an optional note, and issue the quote. - Buyer: switch back to Buyer, review the issued terms, accept or decline, and verify the terminal status in the quote history.
The enforced state machine is SUBMITTED -> REVIEWING -> QUOTED -> ACCEPTED | DECLINED. Sales owns the review and issue transitions; Buyer owns the terminal response.
The browser uses the Next.js App Router and a client-side configurator. Real mutations run through Server Actions into domain modules. Repository functions use the Prisma 7 client with the @prisma/adapter-better-sqlite3 adapter and SQLite. The 3D branch is isolated behind React Three Fiber and Three.js; product options and pricing rules come from a static, Zod-validated TypeScript catalog.
| Area | Implementation |
|---|---|
| Application | Next.js 16 App Router, React 19, TypeScript 5.9 |
| 3D | React Three Fiber, Drei, Three.js |
| Data | Prisma 7, @prisma/adapter-better-sqlite3, SQLite |
| Validation | Zod 4 |
| Styling | Tailwind CSS 4 tooling and project CSS |
| Testing | Vitest, Testing Library, Playwright |
Requirements: Node.js 20.19 or newer and npm.
cp .env.example .env.local
npm ci
npx playwright install chromium
npm run db:generate
npm run db:migrate
npm run db:seed
npm run devOpen http://localhost:3000. Running npm run db:seed deletes existing local demo quotes, quote events, and designs before restoring the deterministic demo users, catalog records, and starter design. Treat it as a local demo reset command.
| Variable | Required | Purpose |
|---|---|---|
DATABASE_URL |
Yes | SQLite connection URL. The local example uses file:prisma/dev.db. |
DEMO_SESSION_SECRET |
Yes | HMAC secret for signed demo sessions. Use at least 32 characters outside tests. |
Generate a dedicated random secret for each environment and keep it outside version control. The value in .env.example is a placeholder.
There are no demo usernames or passwords. Visit /demo and use Continue as Buyer or Continue as Sales. Selecting a role replaces the current signed demo session.
The following chain completed with exit code 0 on 2026-07-22:
npm run lint && npm run typecheck && npm test && npm run test:e2e && npm run build| Check | Verified result |
|---|---|
| ESLint | Passed |
| Next route generation and TypeScript | Passed |
| Vitest | 41 test files passed; 398 tests passed |
| Playwright | 3 Chromium scenarios passed |
| Next.js production build | Passed; 9 routes built: 4 static and 5 dynamic |
Exact production route output:
| Route | Rendering |
|---|---|
/ |
Static |
/_not-found |
Static |
/configurator/[id] |
Dynamic |
/demo |
Static |
/preview/desk |
Static |
/sales |
Dynamic |
/sales/quotes/[id] |
Dynamic |
/share/[token] |
Dynamic |
/workspace |
Dynamic |
- Demo role sessions are HMAC-SHA-256 signed, expire after eight hours, and use
HttpOnly,SameSite=Laxcookies withSecureenabled in production. - Server Actions re-read the session, enforce Buyer or Sales authorization, validate untrusted form data, and return bounded error messages.
- Buyer design and quote queries are owner-scoped; sales-only transitions are checked in the domain state machine.
- Prices are integer cents and are recalculated from the static server catalog when designs and quotes are persisted.
- Design and quote writes use versions as compare-and-swap guards. Quote transitions and timeline events are committed in Prisma transactions.
- Share links are read-only bearer URLs. Anyone holding a current URL can view that design; rotating the token invalidates the previous URL.
These controls demonstrate deliberate application boundaries for the portfolio scenario. They are not a substitute for a production identity, authorization, audit, and operations program.
features/**/*.test.ts(x)covers catalog pricing, configuration behavior, session signing, Server Actions, quote state transitions, and UI components.app/**/*.test.tsxcovers route-level authorization and rendering states.tests/integration/exercises Prisma repositories, real SQLite concurrency, and action workflows.tests/runtime/checks production session behavior, shared-page cache behavior, and the 3D runtime fallback.e2e/runs the complete Buyer-to-Sales-to-Buyer flow and a 375 x 812 mobile configurator flow in Chromium.
This repository is a portfolio demo with deterministic local data. It makes no claim of production certification or production readiness. The implemented evidence does not include:
- production authentication certification or a complete identity lifecycle;
- multi-tenancy or tenant isolation;
- order management or fulfillment;
- PDF quote generation;
- payment processing;
- real-time collaboration;
- WCAG conformance certification;
- published performance benchmarks or performance guarantees.
The verified counts above describe one recorded local acceptance run. They are test evidence, not user, revenue, reliability, accessibility, or performance metrics.
- Replace role-button sessions with a production identity provider and explicit tenant model.
- Add catalog administration, order conversion, PDF quote export, and payment integration as separate bounded capabilities.
- Add collaborative presence only after defining conflict, ownership, and audit semantics.
- Commission an independent accessibility audit and establish measured performance budgets before making compliance or speed claims.

