Frontend MVP shell for an AI-native sales deck workspace. The app provides routed surfaces for dashboard, pitch deck build (account brief + intel review), and slide editing.
/— Marketing landing (hero, product sections, trust content). Sign in / Sign up navigate to/authand/signup./auth— Existing Supabase email + password flow (magic link + reset preserved). Signed-in users are redirected according to role rules below./signup— Owner-focused signup entry (same Supabase password signup). After a session exists, continue with/onboarding/company.
Static assets load as usual; there is no Stripe, no paid AI APIs, and no external site builders—everything ships from this Vite app.
Protected by ProtectedLayout: /dashboard, /build, /edit, /company, /owner, and all /onboarding/* wizard steps. Guests are redirected to /auth with a from state payload.
/dashboard— Pitch deck workspace library (existing Deck Drive experience)./owner— Owner / company admin console (knowledge governance, org scaffolding, mock AI folder suggestions). Only owner or admin membership on the active organization can view this route; others are redirected to/dashboard./company— Company Brain (shared memory scaffold)./build,/edit— Pitch deck build + editor surfaces.
After sign-in, owners and admins default to /owner; members and viewers default to /dashboard, unless a deep-link from state points elsewhere. The landing page and /signup route signed-in users through resolvePostSignupPath: net-new companies without a local org record go to /onboarding/company.
If VITE_SUPABASE_URL / VITE_SUPABASE_ANON_KEY are missing, Continue in local workspace mode on /auth still unlocks the private app without cloud login; data stays in the browser.
Billing / subscriptions are not implemented.
| Variable | Required for |
|---|---|
VITE_SUPABASE_URL |
Supabase project URL (public) |
VITE_SUPABASE_ANON_KEY |
Supabase anon key (public, RLS-protected) |
Optional:
VITE_AI_BACKEND_ENABLED— see AI adapter section below.
Never expose SUPABASE_SERVICE_ROLE_KEY or other backend secrets in Vite / client code. Keep them in serverless or Edge Functions only.
npm install
npm run devThe app is a Vite SPA. Workspace data defaults to browser localStorage; manual Save to Cloud / Load from Cloud is available when Supabase is configured and the user is signed in. There is no auto-sync; existing confirmation behavior for load/merge is preserved.
Copy .env.example when setting up.
Only variables prefixed with VITE_ are exposed to frontend code by Vite:
VITE_SUPABASE_URLVITE_SUPABASE_ANON_KEYVITE_AI_BACKEND_ENABLED
For testing Supabase Edge Function AI scaffolding from the frontend:
- set
VITE_AI_BACKEND_ENABLED=true - keep
VITE_SUPABASE_URLandVITE_SUPABASE_ANON_KEYconfigured - no AI provider key is required yet
Backend-only secrets must stay in serverless functions, Supabase Edge Functions, or the host’s non-VITE_ environment:
SUPABASE_SERVICE_ROLE_KEYAI_PROVIDER_API_KEYAI_PROVIDER
Do not import backend-only secrets from src/ or expose them through Vite.
This workspace should be initialized as a Git repository before connecting to GitHub. package-lock.json is included because the project uses npm. .env, .env.*, node_modules, dist, .vercel, and cache output are ignored so secrets and generated files are not committed.
- Create a Supabase project and enable Email auth (password; optional magic link / OTP as configured in the project).
- Add
VITE_SUPABASE_URLandVITE_SUPABASE_ANON_KEYto local.envand to Vercel (or your host) project environment variables. - Keep
SUPABASE_SERVICE_ROLE_KEYonly in backend/serverless environments. - Review
supabase/migrations/0001_foundation.sqlbefore applying it. - Apply
supabase/migrations/0002_workspace_snapshots.sqlfor theworkspace_snapshotstable and RLS tied toauth.uid(). - Apply
supabase/migrations/0003_company_brain.sqlfor the Company Brain relational scaffold (organizations, memberships, knowledge folders/items, brand kit, messaging snippets, case studies, product/service bullets, activity logs). - Add real row-level policies for normalized tables when collaboration rules are ready.
The browser client is src/data/supabaseClient.ts and uses only the public anon key.
The app uses two buckets (create them in Supabase Dashboard → Storage):
| Bucket id | Purpose |
|---|---|
source-files |
Raw files uploaded on the build flow (account research sources). Objects use paths {auth_user_id}/{deck_id}/{file_asset_id}/{filename}. |
deck-assets |
Slide images inserted or replaced in the editor (visual-placeholder blocks). Same path pattern with a unique asset key per upload. |
Recommended setup
- Create both buckets. For the simplest client behavior (stable image URLs in slides), mark them public and rely on long random paths for obscurity, or keep them private and plan to resolve signed URLs when loading slides (the editor currently uses
getPublicUrlafter upload; private buckets may require follow-up work to usecreateSignedUrlor edge helpers). - Add Storage policies so authenticated users can read/write only under their own prefix. Example policy shape (adjust names as needed; run in SQL editor against
storage.objects):
-- Example: allow authenticated users full access to objects under their user id folder in source-files
create policy "source_files_own_prefix"
on storage.objects for all
to authenticated
using (bucket_id = 'source-files' and (storage.foldername(name))[1] = auth.uid()::text)
with check (bucket_id = 'source-files' and (storage.foldername(name))[1] = auth.uid()::text);
create policy "deck_assets_own_prefix"
on storage.objects for all
to authenticated
using (bucket_id = 'deck-assets' and (storage.foldername(name))[1] = auth.uid()::text)
with check (bucket_id = 'deck-assets' and (storage.foldername(name))[1] = auth.uid()::text);Public buckets still require insert/update policies for authenticated users; use the Supabase policy UI or SQL to match your security model.
App behavior
- No Supabase env vars / local dev mode: uploads stay local (existing mock ingestion and data URLs). Nothing is sent to Storage.
- Signed in with Supabase: the build flow uploads each selected file to
source-fileswhen possible and stores astoragereference on theFileAsset. The editor uploads slide images todeck-assetsand prefers the cloud URL forSlideImageAsset.dataUrl. If Storage is missing, misconfigured, or the upload fails, the app falls back to the previous local-only behavior and shows an informational toast.
Helpers live in src/data/workspaceStorage.ts (uploadWorkspaceAsset, getWorkspaceAssetUrl, deleteWorkspaceAsset). Existing workspace JSON and localStorage data are not auto-migrated to buckets.
Deckspace ships a lightweight company workspace / knowledge library scaffold so reps can accumulate shared narratives, proofs, approvals, brand defaults, offerings, and case studies locally while Supabase relational tables mature.
- Frontend route:
/company(Company Brain in the sidebar) hosts tabs for overview, knowledge, review queue, brand kit, messaging, casework, catalogs, membership, and an activity timeline. /ownerowner console: complements/companywith an administration-focused overview (sections for knowledge library, catalogs, mock AI folder suggestions, activity, etc.). It reads the same normalized workspace JSON—no duplicate datastore.- Knowledge folders (nested + suggestions):
KnowledgeFoldersupportsparentFolderId, optionaldescription, and mock AI metadata (suggestedByAi,ownerApproved). Items may carrysuggestedFolderId/ownerApprovedFolderwhile owners reconcile placements. - Mock AI organization:
suggestCompanyKnowledgeOrganizationinsrc/data/companyKnowledgeOrganization.tsproposes folder targets using deterministic rules (source type + light keyword cues). No remote models—safe for prototyping. - Local/mock behavior: all Company Brain payloads live inside the existing
workspaceJSON persisted tolocalStorage(same as decks). Older snapshots auto-normalize: missingworkspace.companyBrainbackfills empty arrays/objects so nothing breaks offline. - Role-aware retrieval (mock heuristic):
getRelevantCompanyKnowledgeForUserranks knowledge items during the Build Pitch Deck flow using approval flags, visibility, department/title matchers, deck brief keywords (target company / buyer persona / offerings), tags, and source types. No embeddings / no vector search yet. - Intel Review integration: when you toggle knowledge selections in Build,
/generate-intel-reviewmocks include those excerpts in local intel drafts viagenerateIntelDraftFromSources, and citations only hydrate when linkedFileAssettraces exist. - Supabase rollout: migrations
supabase/migrations/0003_company_brain.sqldefine the Postgres tables plus RLS aligned to owners/admins/members. Wired cloud sync UI + policies can land later without changing the UX contract modeled here.
Important: there are still no paid AI APIs, no Stripe billing, no embeddings / vector search, and no OCR / parsing pipelines bundled with this scaffold—purposefully safe for prototyping.
Guided steps live at /onboarding/company → /onboarding/company-info → /onboarding/company-knowledge → /onboarding/review. Step 1 is Supabase signup (/signup). Steps 2–5 capture company basics, optional narrative copy, mock upload labels, knowledge-library preference (auto / manual / hybrid / drive-like), and a confirmation that seeds the local organization via completeCompanyBrainOnboarding with variant: 'owner-create'. Draft answers persist in sessionStorage until completion.
Workers invited into an existing organization continue to use the catalog-based Company Setup modal (worker-profile variant) when they need to declare department/title assignments—owners creating a net-new company only supply company name, optional website, and optional display name.
- Supabase configured: sign-in is required to use the app; cloud save/load uses the signed-in user id.
- Supabase not configured: use local development mode from the sign-in screen; work is not cloud-saved.
- Cloud save/load uses
workspace_snapshots.workspace_jsonand does not replace localStorage automatically. Loading a snapshot still flows through the existing workspace store.
- Push the Git repo to GitHub.
- Create a Vercel project from the GitHub repo.
- Build:
npm run build, output directorydist. - Add
VITE_SUPABASE_URLandVITE_SUPABASE_ANON_KEYfor production auth.
No vercel.json is required for the current Vite SPA unless you add rewrites or serverless routes.
Vite does not provide app server routes by itself. The placeholder backend route plan is documented in api/README.md.
Recommended first backend path: Supabase Edge Functions for AI proxy calls.
src/data/aiClient.ts is the frontend adapter seam. With VITE_AI_BACKEND_ENABLED=false, it keeps calling local mock functions.
Mock AI backend function scaffold (no paid provider calls yet):
supabase/functions/generate-intel-review/index.ts- shared sanitization + response builder:
supabase/functions/_shared/intelReviewShared.ts
Deploy function:
supabase functions deploy generate-intel-reviewServe locally while developing:
supabase functions serve generate-intel-reviewCurrent behavior:
- verifies Supabase JWT and rejects unauthenticated requests (
401) - validates/sanitizes request payloads (
400on malformed input) - returns structured mock intel JSON and warnings
- never fabricates citations (returns only sanitized
sourceTracesfrom request) - if
webResearchEnabled=true, returns a warning that web research is not connected yet
Future AI provider integration should use Supabase Function Secrets (server-side only), not frontend VITE_ variables. Intel Review Gemini (optional): set secret GEMINI_API_KEY, AI_PROVIDER=gemini, and optionally AI_MODEL (defaults to gemini-2.5-flash); optional mock guards SUPABASE_TEST / INTEL_REVIEW_FORCE_MOCK.
src/context/AuthContext.tsx
Supabase session, sign-in / sign-up / sign-out, password reset, and local dev bypass (session flag when env vars are missing).src/pages/AuthPage.tsx
Sign-in and sign-up UI; local development entry when Supabase is not configured.src/components/auth/ProtectedLayout.tsx
Gate for all in-app routes.src/context/WorkspaceContext.tsx
Client-side workspace store with local persistence.src/data/mockWorkspace.ts
Seed data and deck creation helpers.src/data/deckGenerator.ts
Deterministic mock slide generation.src/pages/*
Dashboard, build, editor, auth,/company, marketing landing (/),/signup, owner onboarding steps,/owner.src/pages/CompanyBrainPage.tsx
Company Brain workspace scaffold (tabs, mock CRUD, activity log).src/components/editor/*
Slide editing, comments, Present Mode, export.src/data/pptxExport.ts
Browser PPTX export viapptxgenjs.src/data/aiClient.ts
AI adapter seam.src/data/supabaseClient.ts
Optional Supabase browser client.src/data/workspaceCloudPersistence.ts
Manual cloud snapshot save/load.src/data/workspaceStorage.ts
Supabase Storage uploads and URLs forsource-filesanddeck-assets.
Slides render from Slide.blocks[] with type, content, and style (align, fontSize, bold, italic).
Fullscreen slide stage with next/previous/exit. Keyboard: ArrowRight, Space, ArrowLeft, Escape.
Editor toolbar Export PPTX downloads a widescreen .pptx from the deck title.
- Replace local mock generation with async backend jobs returning the same slide JSON contract
- Real file parsing and source trace metadata on
FileAsset - Collaboration and version restore flows
- Deeper owner-console CRUD and Supabase sync for org metadata