dwp.visualization is the 3D team's visualization workflow manager. Use when the user needs to submit a 3D rendering request, track visualization jobs through design phases (Briefing → Concept → Pre-Schematic → Schematic), generate AI-assisted concept images or videos, analyse design styles from reference imagery, decode white-model materials, browse or upload 3D assets via Autodesk ACC, manage prompt libraries, generate standardised file names, or view the outsource renderer directory. Trigger phrases include "submit a render request", "generate a concept image", "what phase is this project in", "analyse this design style", "upload a 3D model to the library", "create a prompt for Midjourney", and "name this rendering file".
dwp.visualization (internally dwp.intelligence-3d-pipeline) is the centralised workflow and AI toolkit for the dwp 3D Visualization team. It guides projects through four design phases — Briefing & Site Analysis, Concept, Pre-Schematic, and Schematic — providing AI-powered generation, quality gates, asset management, and outsource coordination in a single interface.
Single-page SPA architecture with two routes:
/ — Auth gate → VizWorkflowApp (leader/member), OutsourcePortal (outsource role), or "Access Pending" (no role)/book3d — Standalone 3D viewer (embedded view)All other routes are API endpoints under app/api/.
components/
├── core/ Providers (GoogleOAuth + Auth)
├── auth/ LoginPage (email + Google OAuth)
├── features/
│ ├── VizWorkflow/ Main tabbed workspace (14 tab components)
│ ├── PdfLibrary/ PDF document management
│ ├── StyleLens/ Image/text style analysis
│ ├── WhiteModelDecoder/ BIM material projection
│ ├── DriveUploader.tsx Google Drive upload
│ └── ResourceViewer.tsx Resource browser
├── portals/ Outsource, Submission, Library, Settings, Request
├── dashboard/ Overview dashboard + tools grid + workflow progress
├── viewers/ APSViewer, ModelViewer, Gallery, FileBrowser
└── ui/ shadcn-style primitives (Button, Tabs, Skeleton, Spinner)
vizworkflow.css (.viz-light / .viz-dark token sets)<script> tag in app/layout.tsx (not PostCSS — @apply does not work)var(--bg), var(--tx), var(--or), etc.)dark: prefixuseState as primary orchestrator for projects, logs, tabs, modalsstore/usePdfLibraryStore.ts for PDF library statedwp_user, dwp_access_token, dwp_token_expiryTables: viz_projects, viz_logs, threed_user_roles, dwp_refresh_tokens, prompt_library, project_prompts, pdf_sections, pdf_documents, project_all, threed_projects, threed_outsource_assignments, project_requests
next/dynamic with { ssr: false } for heavy client components (Three.js, APS Viewer)upsert() to SupabaseMath.random().toString(36).substr(2, 9) via uid() in constants.ts{tab === "key" && <Component />}components/features/VizWorkflow/NewTab.tsxVizWorkflowApp.tsxNAV_ITEMS, LIB_ITEMS, or TOOL_ITEMS_BASE array{tab === "newtab" && <NewTab />}Create app/api/<name>/route.ts exporting GET/POST functions. Follow the pattern in app/api/gemini/route.ts.
UserRole type in contexts/AuthContext.tsxapp/page.tsx MainLayoutthreed_user_roles Supabase tablecomponents/portals/NewPortal.tsxVizWorkflowApp.tsx| Class | Purpose |
|---|---|
vw-root | Root flex container (100vh) |
vw-rail / .open / .closed | Sidebar (220px open / 52px closed) |
vw-mn | Main content area |
vw-bar | Top bar |
vw-fg, vw-fgi, vw-fi, vw-fs, vw-ft | Form group, item, input, select, textarea |
vw-cd, vw-tcard | Card, tool card |
vw-btn, vw-btn-p, vw-btn-g, vw-btn-d, vw-btn-sm | Button variants (primary/ghost/danger/small) |
vw-ov, vw-mdl | Modal overlay + dialog |
vw-empty, .ei, .et, .es | Empty state container + icon/title/subtitle |
vw-notice | Toast notification (fixed, top-center, auto-dismiss 3s) |
vw-render-msg, .user, .ai | AI conversation message with role variants |
<script> tag, not PostCSS. @apply does not work. Classes are runtime-only..viz-dark and .dark are toggled on <html>. ThemeContext toggles both.isLocked is hardcoded to false (line 101 of VizWorkflowApp.tsx). Phase locking is not enforced.app/page.tsx exports force-dynamic — the main page is never statically generated.<div onClick> instead of <button> — no keyboard navigation or ARIA attributes.| Feature | Model / Service | Description |
|---|---|---|
| Text Consultation | Gemini (via @google/genai) | Design narrative generation, brief-to-narrative synthesis, prompt refinement, render critique |
| Concept Image Generation | Gemini Imagen | Text-to-image and image-to-image concept generation |
| Video Preview Generation | Gemini Veo (veo-2.0-generate-001) | Text-to-video and image-to-video animation previews (16:9 / 9:16) |
| StyleLens — Image Analysis | Gemini 2.0 Flash | Extracts style name, summary, elements, colour palette, and character from reference images |
| StyleLens — Text Generation | Gemini 2.0 Flash | Generates full style profiles from text descriptions |
| WhiteModelDecoder — Analysis | Gemini 2.0 Flash | Identifies architectural elements in white-model renders |
| WhiteModelDecoder — Render | Gemini Imagen | Generates photorealistic material projections at standard, 2K, and 4K resolutions |
| WhiteModelDecoder — Angles | Gemini Imagen | Generates alternative camera-angle renders from reference materials |
| Pipeline Route Detection | Gemini 2.0 Flash | Analyses project descriptions to recommend input/output workflow routes |
| Claude Integration | Claude API (Anthropic) | Secondary AI consultation endpoint |
| Layer | Technology | Version |
|---|---|---|
| Framework | Next.js | 15.1.6 |
| UI Library | React | 19.0.0 |
| Language | TypeScript | 5.8.2 |
| 3D Rendering | Three.js + @react-three/fiber + @react-three/drei | 0.182 / 9.5 / 10.7 |
| AI SDK | @google/genai | 1.40.0 |
| Database | Supabase (@supabase/supabase-js) | 2.95.3 |
| Authentication | Google OAuth (@react-oauth/google) | 0.13.4 |
| Animation | GSAP | 3.14.2 |
| Styling | Tailwind CSS (CDN) + Vanilla CSS | — |
| Icons | Lucide React | 0.563.0 |
| UI Components | Radix UI (Tabs) + shadcn/ui | — |
| Date Utilities | date-fns | 4.1.0 |
| Runtime | Node.js (Alpine) | 20 |
Projects and logs are stored as in-memory state with Supabase persistence. Key data models:
id, name, projectId, sector, studio, phase, gates (pass/fail per gate), createdid, projectId, phase, tool, prompt, referenceInputs, outputFile, status, designer, date, notes, inLibrary| Output | Format | Source Feature |
|---|---|---|
| Concept Images | PNG (base64) | dwp.render / Gemini Imagen |
| Video Previews | MP4 (base64) | Gemini Veo |
| Material Renders | PNG (base64, up to 4K) | WhiteModelDecoder |
| Style Analysis | JSON (structured) | StyleLens |
| 3D Models | Via APS (RVT, 3DS, OBJ, FBX, etc.) | 3D Model Library |
| File Uploads | Via Google Drive API | Submission Portal |
/book3d route)Revit, 3DS Max, Midjourney, D5 Render, Krea.ai, Meshy.ai, Magnific AI, Stable Diffusion, Autodesk Forma, PromeAI, Veras, Luma Dream Machine, Runway Gen-3, Kling AI, Mattoboard, Hyper 3D, Tripo 3D
| Aspect | Detail |
|---|---|
| Audience | Internal dwp — 3D Visualization team |
| Authentication | Google OAuth (@dwp.com accounts) |
| General Access | All @dwp.com Google account holders |
| Admin Access | 3D Portal features may require admin privileges |
| External Access | Not client-facing |
Client briefs & reference images
↓
dwp.visualization
(workflow → prompt gen → AI render → asset library)
↓
3D / BIM pipeline (Revit, 3DS Max)
↓
dwp.design pitching (presentations)
↓
dwp.Visualization intranet (company-wide access)
dwp.design pitching (linked from tools), dwp.Visualization intranetdwp-pipeline-v1 in asia-southeast3dwpaivibecodeasia-southeast3-docker.pkg.dev/dwpaivibecode/pipeline-repo/pipeline-app| Variable | Purpose | Scope |
|---|---|---|
GEMINI_API_KEY | Google Gemini API authentication | Build + Runtime |
GEMINI_CLIENT_ID | Google OAuth Client ID | Build + Runtime |
NEXT_PUBLIC_SUPABASE_URL | Supabase project URL | Build (public) |
NEXT_PUBLIC_SUPABASE_ANON_KEY | Supabase anonymous key | Build (public) |
APS_CLIENT_ID | Autodesk Platform Services client ID | Runtime |
APS_CLIENT_SECRET | Autodesk Platform Services client secret | Runtime |
APS_CALLBACK_URL | APS OAuth callback URL | Runtime |
CLAUDE_API_KEY | Anthropic Claude API key | Runtime |
# Install dependencies
npm install
# Run locally
npm run dev
# Build for production
npm run build
# Start production server
npm start
# Deploy via Cloud Build (from repository root)
gcloud builds submit --config=cloudbuild.yaml \
--substitutions=_GEMINI_API_KEY=...,_GEMINI_CLIENT_ID=...,_NEXT_PUBLIC_SUPABASE_URL=...,_NEXT_PUBLIC_SUPABASE_ANON_KEY=...,_APS_CLIENT_ID=...,_APS_CLIENT_SECRET=...,_APS_CALLBACK_URL=...,_CLAUDE_API_KEY=...
| Path | Description |
|---|---|
app/page.tsx | Entry point — auth gate → VizWorkflowApp |
app/layout.tsx | Root layout with Tailwind config and providers |
app/book3d/ | Standalone 3D viewer page |
app/api/gemini/ | Gemini API route |
app/api/claude/ | Claude API route |
app/api/video-gen/ | Video generation API route |
app/api/aps/ | Autodesk Platform Services API routes (9 endpoints) |
components/features/VizWorkflow/VizWorkflowApp.tsx | Main workspace orchestrator |
components/features/VizWorkflow/PromptGenWorkspace.tsx | AI prompt engineering workspace |
components/features/VizWorkflow/RenderWorkspace.tsx | In-app dwp.render workspace |
components/features/VizWorkflow/ModelsTab.tsx | 3D model library with APS upload |
components/features/VizWorkflow/Book3DTab.tsx | Embedded Three.js 3D viewer |
components/features/VizWorkflow/WorkspaceTab.tsx | Project dashboard |
components/features/VizWorkflow/constants.ts | Phases, tools, gates, presets, types |
components/features/VizWorkflow/vizworkflow.css | Theme tokens + all component CSS classes |
components/features/GeminiPanel.tsx | AI chat/image/video panel |
components/features/PdfLibrary/ | PDF library components (PdfLibrary, PdfUploader, PdfSectionPicker, StorageGauge) |
components/features/StyleLens/ | Style analysis components (4 files) |
components/features/WhiteModelDecoder/ | Material projection components (2 files) |
components/features/DriveUploader.tsx | Google Drive upload component |
components/features/ResourceViewer.tsx | Resource browser component |
components/portals/OutsourcePortal.tsx | Outsource renderer dashboard |
components/portals/SubmissionPortal/ | Submission workflow + DrivePicker |
components/portals/SettingsPortal.tsx | User settings (leader-only) |
components/portals/LibraryPortal.tsx | Digital archive / asset library |
components/portals/RequestPortal.tsx | Work request submission form |
components/dashboard/Dashboard.tsx | Pipeline overview dashboard |
components/viewers/APSViewer.tsx | Autodesk APS 3D viewer embed |
components/viewers/ModelViewer.tsx | Generic 3D model viewer |
components/ui/Skeleton.tsx | Loading skeleton component |
components/ui/Spinner.tsx | Loading spinner component |
services/geminiService.ts | All Gemini AI functions |
services/apsService.ts | Autodesk Platform Services integration |
services/googleDriveService.ts | Google Drive file management |
services/supabaseClient.ts | Supabase client initialisation |
services/emailService.ts | Email notification service |
contexts/AuthContext.tsx | Google OAuth + Supabase auth + SSO context |
contexts/ThemeContext.tsx | Dark/light theme context |
store/usePdfLibraryStore.ts | Zustand store for PDF library |
utils/sso.ts | SSO URL builder + redirect helper |
app/api/auth/ | OAuth code exchange + token refresh routes |
app/api/drive/ | Google Drive routes (list, upload, create-project, assign-outsource) |
app/api/imagen/ | Imagen 4 image generation route |
app/api/gpt/ | GPT API route |
app/api/project-prompts/ | Project-specific prompts route |
app/api/prompt-library/ | Global prompt library route |
types.ts | Shared TypeScript type definitions |
constants.tsx | Pipeline phase data and tool definitions |
Dockerfile | Multi-stage Docker build |
cloudbuild.yaml | Cloud Build CI/CD configuration |
deploy.ps1 | PowerShell deployment helper script |