AI-powered operations workspace for digital and creative agencies. BusinessFlow AI unifies leads, clients, projects, tasks, documents, and delivery into one tenant-scoped workspace, with Google Gemini assisting human decision-making rather than replacing it.
- Live Application: https://businessflow-ai-lime.vercel.app/
- Source Code: https://github.com/arbaz93/BusinessFlow-AI
- Developer Portfolio: https://yousafars.netlify.app/
- Overview
- Product Workflow
- Key Features
- Product Gallery
- Technology Stack
- Architecture & Security
- Getting Started
- Environment Variables
- Supabase & Database Setup
- AI Provider Configuration
- Demo Experience
- Testing & Quality Checks
- Security & Privacy
- Project Structure
- License
Digital and creative agencies juggle a fragmented chain of work: a lead comes in, becomes a client, spawns a project with a client brief, generates tasks, and needs to stay on schedule — all while documents live in one place and context lives in another. BusinessFlow AI connects that chain into a single workspace so nothing is lost between capture and delivery.
The workspace is organized around organizations (workspaces). Every record — leads, clients, projects, tasks, documents, AI analyses, and assistant conversations — belongs to one organization, and every query and route is resolved against the signed-in user's active workspace. AI appears at the two points where it adds the most value: turning a project brief into structured intelligence, and suggesting actionable tasks that a human must approve before they ever become real work.
A complete MVP is deployed at https://businessflow-ai-lime.vercel.app/.
- Agencies and consultancies that need a single place to run the lead → delivery lifecycle.
- Recruiters and hiring managers evaluating the engineering and product decisions behind a full-stack AI SaaS built on Next.js, React Server Components, Prisma, and Supabase.
- Developers who want a reproducible, production-oriented reference implementation of multi-tenant authorization, server actions, and an AI provider integration with input validation and staleness handling.
BusinessFlow AI follows one end-to-end delivery flow, keeping a human in the loop wherever AI suggests work:
flowchart LR
Leads["Leads<br/>inbound pipeline"] --> Clients["Clients<br/>won leads convert"]
Clients --> Projects["Projects<br/>scoped to a client"]
Projects --> Docs["Project Brief &<br/>documents"]
Docs --> AI["AI Project Intelligence<br/>analyzes the brief"]
AI --> Review["Suggested tasks<br/>presented for review"]
Review --> Human["Human approves<br/>before creation"]
Human --> Tasks["Tasks<br/>real work items"]
- Capture leads from the pipeline and qualify them through status stages.
- Convert won or qualified leads into client records (history is preserved; converted leads become read-only).
- Create a project bound to a client, with status and priority tracking.
- Upload the project brief and supporting documents to a private, per-organization storage area.
- Analyze the primary brief with AI: Gemini returns a structured summary, requirements, deliverables, risks, missing information, and suggested tasks — all validated against a Zod schema before it is stored.
- Review the suggested tasks, edit them, and approve only the ones you want.
- Deliver the approved tasks as real, assignable work items with status and due dates.
A separate AI Assistant is available for general, workspace- and project-scoped questions. It can also infer a task-creation intent and draft task proposals that, like AI Project Intelligence, require human approval before becoming tasks.
- Lead management with statuses
NEW,CONTACTED,QUALIFIED,PROPOSAL_SENT,WON,LOST, optional estimated value and currency. - Lead detail and editing with optimistic-concurrency checks (
expectedUpdatedAt) so simultaneous edits are detected. - Lead → Client conversion: only
QUALIFIEDorWONleads can convert; converting creates a client linked to the lead, and the lead becomes read-only to preserve sales history. - Client records with
ACTIVE/INACTIVEstatus; clients cannot be deleted while activity history references them (the UI offers deactivating instead). - An immutable activity log records every create, status change, conversion, and deletion.
- Projects bound to a client with status (
PLANNING,IN_PROGRESS,ON_HOLD,COMPLETED,CANCELLED) and priority (LOW–URGENT). - Tasks scoped to a project with status (
TODO,IN_PROGRESS,BLOCKED,COMPLETED,CANCELLED), priority, optional assignee (workspace members only), and due dates. - Project overview, project-level task lists, and a global tasks view.
- A dashboard summarizing total leads, active clients, active projects, overdue tasks, upcoming tasks, and recent activity.
- Private Supabase Storage bucket named
project-documents(created private automatically; uploads are rejected if the bucket is public). - Upload validation: extension/MIME cross-check, file-signature verification, 20 MB size limit, server-side sanitization of file names.
- Server-generated storage paths (
organizations/{orgId}/projects/{projectId}/documents/{documentId}/{sanitizedName}) — client-supplied paths are never trusted. - Tenant-scoped downloads/views: every request is authorized server-side against the active organization and project, and a short-lived signed URL (10 minutes) is issued only after authorization.
- Transactional uploads with automatic storage cleanup if the database record fails to persist.
- One primary Project Brief per project, enforced at the application layer when a brief is created or promoted.
- Triggered from a project's AI tab: the primary Project Brief is read, its text is extracted from PDF, DOCX, TXT, or Markdown, and it is sent to Gemini for analysis.
- The model is asked to return structured JSON that is parsed and validated with Zod before it is stored: a brief summary, requirements (with importance), deliverables, risks (with severity), missing-information questions, and suggested tasks (with priority).
- Results are persisted with a
PROCESSING→COMPLETED/FAILEDlifecycle, and the system tracks staleness: if the primary brief changes, a prior analysis is flagged for re-analysis rather than silently reused. - The AI tab also keeps an analysis history and lets users submit feedback against specific parts of an analysis.
- Human approval is required: suggested tasks are presented for review and editing; nothing is added to the project until an owner/editor confirms. This is enforced with a serializable, retry-safe transaction that prevents double-approval.
- A persistent, per-organization conversation workspace (
/assistant) with message history and auto-titled conversations. - Context resolution scoped to the active workspace, and to a specific project when the conversation is project-scoped: the assistant receives project, client, task, document, brief, and existing AI intelligence context, selected by intent.
- Bounded recent-message windowing plus a conversation memory summary that is refreshed as the conversation grows.
- Task-creation intent detection: when the assistant proposes a task, it produces an editable draft (title, description, priority, due date, assignee) that must be approved before a task is created.
- The assistant is read-only-by-default and guarded against instruction injection from conversation content or stored memory.
- Global workspace search (
Ctrl/Cmd + K) scoped to the active organization across leads, clients, projects, and tasks, with results limited per group and de-duplicated. - Settings for workspace profile and business type, member management, and user profile and security (password changes, account deletion).
- Workspace switching via a server-side
businessflow_active_workspacecookie for users with multiple memberships.
- Supabase email/password authentication with email confirmation and password recovery (forgot + reset).
- A sign-in/sign-up flow that resolves an entry state:
UNAUTHENTICATED→ login,NO_WORKSPACE→ create the first workspace,INVITATION_AVAILABLE→ accept a pending invitation,READY→ dashboard. - Auth callbacks at
/auth/callback(sign-in/confirmation/recovery) and/auth/callback/invitations/[token](invitation acceptance). - Server-side rate limiting on authentication, sign-up, password recovery, invitations, uploads, and AI endpoints.
All screenshots are stored in screens/ and are used unedited.
The homepage introduces the product and links into sign-in.
The Features page highlights core capabilities.
Sign-in with email/password, plus a demo sign-in option when demo mode is enabled.
Account creation with name, email, and password confirmation.
First-workspace creation with business type selection.
Workspace overview with metrics, upcoming tasks, recent activity, and AI shortcuts.
Lead pipeline board with status and estimated value.
Lead detail view with timeline and the activity feed.
Client list grouped by active and inactive.
Client record linked to a converted lead.
Project list with status and priority.
Project overview with client and delivery timeline.
Project-scoped task board.
Global task list with filtering.
Task detail with status and assignments.
AI Project Intelligence results in the dark theme: summary, requirements, risks, and suggested tasks pending review.
The AI Assistant conversation workspace with a task proposal.
Project documents with primary brief selection.
Global workspace search (Cmd/Ctrl + K).
Workspace and user settings.
| Layer | Technology | Role |
|---|---|---|
| Framework / routing | Next.js 16.4.0 (App Router) | Server and client components, server actions, API routes |
| Runtime UI | React 19.2.8 | Component model and interactivity |
| Language | TypeScript 5 (strict) | Types across the app |
| Styling | Tailwind CSS 4 | Utility-first styling with CSS variables |
| Components | shadcn/ui conventions (new-york, neutral base, lucide icons) |
Reusable UI primitives |
| UI primitives | Radix UI | Headless primitives (e.g. the search dialog) |
| Database | PostgreSQL on Supabase | Tenant-scoped data store |
| ORM | Prisma 7.10.0 (@prisma/adapter-pg, pg) |
Schema, migrations, and typed client; client emitted to app/generated/prisma |
| Auth | Supabase Auth (@supabase/ssr) |
Cookie-based email/password sessions |
| Storage | Supabase Storage (@supabase/supabase-js) |
Private project-documents bucket, signed URLs |
| Validation | Zod 4.6.5 | Input, schema, and environment validation |
| AI provider | Google Gemini (gemini-2.5-flash) via the Generative Language API |
AI Project Intelligence and the AI Assistant |
| Lint / format | ESLint 9 (eslint-config-next, core-web-vitals + TypeScript) |
Static analysis and code style |
| Testing | Node.js built-in test runner (node --test) |
Unit/integration tests with @/ alias resolution |
| Deployment | Vercel | Production hosting with per-route timeouts |
Supabase Auth is configured for email/password (no third-party OAuth providers are wired in the current build). AI is provided exclusively by Google Gemini;
AI_PROVIDER=geminiis the only accepted value.
The application follows the Next.js App Router conventions already in the repository. Server components fetch data and render pages; mutations go through Server Actions (app/actions/*.ts) that are server-only and import server-only; an API route (app/api/projects/[projectId]/ai-analysis/route.ts) backs long-running AI analysis. The active-workspace shell lives under app/(application)/ and is guarded by requireOrganization; marketing pages live under app/(marketing)/.
- Supabase Auth issues a cookie-based session via
@supabase/ssr(lib/supabase/server.ts). The server client reads the session from cookies on every request. - Supabase admin client (
lib/supabase/admin.ts) is constructed with the service-role key and is used only for private storage operations and admin auth APIs. It is never imported from client code. - Prisma connects over the session pooler (
DATABASE_URL, port 6543) at runtime;DIRECT_URL(port 5432) is used by the Prisma CLI for migrations. The client is generated intoapp/generated/prismaand a singleton is reused in development (lib/db/prisma.ts).
BusinessFlow AI is a single shared database with application-level tenant isolation. The protections are implemented in code and verified against the routes and actions:
- Protected routes: every application route resolves the organization through
requireOrganization(lib/auth/dal.ts), which reads the session, syncs the user profile, and resolves the active workspace from abusinessflow_active_workspacecookie. Unauthenticated users are redirected to/login; users without a workspace go to/no-workspace; invite-only users go to/onboarding. - Tenant-scoped access: dedicated authorization helpers (
lib/auth/authorization.ts) check organization membership for each resource type —requireOrganizationAccess,requireProjectAccess,requireClientAccess,requireTaskAccess,requireDocumentAccess, andrequireConversationAccess— so a request can never read or mutate another workspace's records. - Database scoping: every Prisma query carries
organizationIdfilters (modeled via composite keys and indexes on theorganizationIdcolumn for each model). - Role model:
OWNER(workspace manager — can invite/cancel members) andMEMBER. - Private storage: documents live in a private
project-documentsbucket. The bucket is created private and uploads are rejected if the bucket is public. Download/view requests are authorized server-side against the active organization and project, then a 10-minute signed URL is issued. Storage paths are server-generated and validated against an expected pattern before deletion or download. - AI safety: AI output is returned as JSON and validated with Zod before persistence; the Gemini request times out at 60 s. The assistant is read-only-by-default and guarded against instruction injection from memory or message content; task creation is always gated behind human approval.
- Rate limiting: per-IP, in-process limits on auth, sign-up, password recovery, invitations, uploads, AI chat, and AI analysis.
- Rate limiting is in-process (per instance); a multi-instance deployment would need a shared store.
- AI quality depends on the configured Gemini model and the quality of the source brief; the application validates structure but does not guarantee business correctness of generated content.
- Tenant isolation is enforced at the application layer; database-level row-level security is not configured separately.
- Node.js 20.9+.
- npm 10+ (the project is not yarn/pnpm managed; use the committed
package-lock.json). - Git.
- A Supabase project (PostgreSQL, Auth, and Storage) — free tier is sufficient for local development.
- A Google AI Studio API key — required for AI Project Intelligence and the AI Assistant. Without it, AI features report that AI is not configured and non-AI flows still work.
The application can boot and serve static pages without a database, but authentication, workspaces, and every business record require a configured Supabase Postgres database.
git clone https://github.com/arbaz93/BusinessFlow-AI.git
cd BusinessFlow-AInpm installCopy the verified environment template:
cp .env.example .env.localEdit .env.local and fill in the values described in Environment Variables.
npm run devOpen http://localhost:3000. Sign in or create an account, then create your first workspace.
.env.example is the canonical, fully commented template. Local secrets live in .env.local, which is gitignored and must never be committed. Variables split into browser-safe public values and server-only secrets:
| Variable | Classification | Required for local dev | Source |
|---|---|---|---|
NEXT_PUBLIC_SITE_URL |
Public (client bundle) | Yes | Your app origin, e.g. http://localhost:3000 |
NEXT_PUBLIC_SUPABASE_URL |
Public (client bundle) | Yes | Supabase project URL |
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY |
Public (client bundle) | Yes | Supabase anon/publishable key |
DATABASE_URL |
Server-only secret | Yes (auth + business data) | Supabase session pooler, port 6543 |
DIRECT_URL |
Server-only secret (optional) | No, but needed for local migrations | Supabase direct connection, port 5432 |
SUPABASE_SERVICE_ROLE_KEY |
Server-only secret | Yes (documents, admin auth, invitations) | Supabase service role key |
GEMINI_API_KEY |
Server-only secret | Only for AI features | Google AI Studio |
GEMINI_MODEL |
Server-only (default gemini-2.5-flash) |
No | Google model name |
AI_PROVIDER |
Server-only (default gemini) |
No | Must be gemini |
WORKSPACE_INVITATION_EXPIRY_DAYS |
Optional (default 7) |
No | Integer 1–90 |
SEED_DATA_ENABLED |
Optional (default false) |
No | Set true only for controlled test/staging DBs; never production |
DEMO_MODE_ENABLED |
Optional (default false) |
No | Set true to enable demo sign-in and sandbox reset |
The application validates these with a Zod schema at import time (lib/env.ts); in production, the public and server-required variables are mandatory, and GEMINI_API_KEY is required when AI is configured. The server-side code asserts these are present before serving production traffic (assertProductionReady).
- Create a project in the Supabase Dashboard and open Settings → API for the URL and anon key, and Settings → Database → Connection pooling for both the session pooler URL (port 6543) and the direct connection URL (port 5432).
- Configure Auth redirects for email confirmation, sign-in, and password recovery. Add these redirect URLs in Authentication → URL Configuration:
http://localhost:3000/auth/callbackhttp://localhost:3000/auth/callback/invitations/**http://localhost:3000/update-password- Enable the email/password provider and (optionally) a custom SMTP server so confirmation and invitation emails are delivered; if email delivery is unavailable, the app surfaces a copyable invitation link instead.
- Create the storage bucket. A private bucket named
project-documentsis created automatically on the first upload if it does not exist, and the application refuses to upload to a public bucket. You can also create it manually under Storage and leave it private. - Apply the schema and generate the client:
For an empty local development database you can also use
npm run db:generate npm run db:migrate:deploy
npm run db:migrate:dev -- --name init.
A deterministic seed script populates a local database with a complete "Demo Workspace" so the UI can be explored end-to-end:
npm run db:seedThe seed is guarded against production and remote Supabase databases (it checks NODE_ENV, Vercel environment metadata, and the database URL). When run locally it creates:
- 3 documents (2 Project Briefs and 1 design asset)
- 1 completed AI analysis with feedback
- 10 activity records across the canonical activity types
- 1 AI Assistant conversation with 4 messages
- 5 projects covering all statuses, 6 tasks in different states, 6 leads across all statuses, and 3 clients
Demo credentials that back the seeded demo users are defined in the repository at
lib/demo/config.tsandprisma/seed/factories.ts. They are synthetic (.example.testaddresses) and are not reproduced here. See Demo Experience.
To wipe and re-seed a local database: npm run db:reset-dev (destructive; refused against remote Supabase projects).
AI features use Google Gemini (gemini-2.5-flash by default) via the Google Generative Language API. Provide a key with Generative Language access in GEMINI_API_KEY.
- AI Project Intelligence calls Gemini with a JSON-response prompt and validates the result with Zod before persisting it. It is triggered from
POST /api/projects/{projectId}/ai-analysis, which is rate-limited. - AI Assistant calls Gemini with a system instruction built from trusted, server-resolved workspace context (never from user message content) plus a conversation memory summary. It is rate-limited and uses a 60-second request timeout.
Set GEMINI_MODEL to any gemini-* model name. Leave AI_PROVIDER at its default (gemini); it is the only supported value. Without GEMINI_API_KEY, AI features report that AI is not configured instead of failing noisily.
The repository includes a self-contained demo mode (lib/demo/) that can be enabled with DEMO_MODE_ENABLED=true. When enabled:
- The sign-in page shows a Try demo workspace button that provisions a shared, disposable demo account and workspace.
- A Reset sandbox button appears in the workspace banner, which deletes the demo workspace's data and re-seeds it, so the workspace can be restored to a known state at any time.
- The demo workspace is named "Demo Workspace" (organization slug
demo-workspace) and contains the sample data described in Seed data.
The demo account's sign-in credentials are stored in lib/demo/config.ts and are gated by DEMO_MODE_ENABLED. They use synthetic .example.test addresses and are intended for exploration only — they are not a substitute for creating a private workspace. Try the live deployment at https://businessflow-ai-lime.vercel.app/, or run the app locally with demo mode enabled to reproduce the exact demo experience.
The test suite uses Node's built-in test runner (node:test) with a custom @/ path-alias loader (tests/helpers/register.mjs). Tests are isolated from demo seed data; they use in-memory fixtures and mocked AI responses.
npm testExisting coverage is organized across tests/ and includes, at a high level: authentication error mapping and callback URLs, password recovery schema validation, session lifecycle and entry-state resolution, workspace member invitations (tokens, expiry, acceptance), the seed environment guard, project AI analysis/extraction/approval/currentness/feedback/history, project document file validation, project and task schemas and progress, assistant context, and settings schemas.
The test suite is not wired to a CI workflow in this repository (there is no
.github/workflowsdirectory). A full build and type check are recommended before sharing changes:npm run typecheck # tsc --noEmit npm run lint # eslint npm run build # prisma generate && next build
- Never commit
.env.localor any secret file..env*is gitignored except.env.exampleand.env.local.example, which are tracked as templates. - Keep
SUPABASE_SERVICE_ROLE_KEYandGEMINI_API_KEYserver-side only (neverNEXT_PUBLIC_-prefixed, never used in client code). - Configure Supabase Auth redirect URLs to your actual origin; mismatched origins break email confirmation and password recovery.
- Keep the
project-documentsbucket private; the application enforces this and refuses to upload to public buckets. - Scope all workspace data through server-side authorization; every query is tenant-filtered by
organizationId. - The app exposes no marketing cookies or analytics; it uses functional session cookies only.
- Screenshots and demo data use fictional companies and synthetic
.example.testaddresses. - No dedicated security or vulnerability-reporting channel exists in this repository. Suspected vulnerabilities should be reported privately through GitHub rather than the public issue tracker.
app/
(application)/ # Protected workspace UI (dashboard, leads, clients, projects, assistant, settings)
(marketing)/ # Public pages (home, features, solutions, security, etc.)
api/ # API routes (e.g. AI analysis trigger)
actions/ # Server Actions (mutations and workflows)
auth/callback*/ # Supabase Auth callback routes
onboarding, login, signup, no-workspace
components/ # React components (shadcn/ui primitives + feature modules)
lib/ # Utilities: auth/dal, supabase, db (Prisma), AI (project-ai, assistant),
# project-documents, security/rate-limiter, demo, env validation
prisma/ # schema.prisma and migrations/ (applied with db:migrate:*)
prisma/seed/ # Deterministic demo seed (production-guarded)
tests/ # Node test runner suite + alias loader
public/ # Static assets (favicons, default SVGs)
screens/ # README screenshots
BusinessFlow AI is licensed under the Eclipse Public License 2.0 (EPL-2.0). See LICENSE for the full license text.
Developer portfolio: https://yousafars.netlify.app/



















