# Taskflow Ai

I use TaskFlow AI’s versioned REST API for profile, workspace, project, task, and comment operations. Routes use the `/api/v1` prefix; protected requests rely on a session cookie, and browser writes must satisfy the API’s origin and JSON requirements.

I authenticate protected API requests with the `taskflow_session` HttpOnly cookie.

For browser writes, I include the configured `Origin` and send JSON with `Content-Type: application/json`.

My list pagination defaults are page 1, pageSize 20, maximum 100.

For workspace member role changes, only owner can grant/change admin; owner removal requires ownership transfer first.

I make new workspace membership invitation-based; direct member creation is intentionally not exposed.

In my project API, workspace members can read projects and non-guests can create them.

In my project API, a project admin or workspace admin can update, delete, or archive a project; member changes also require project or workspace admin access.

In my task API, project reads follow project access, while task writes require project `ADMIN` or `MEMBER` access or workspace admin access.

For task endpoints, reading and editing follow project role, but deleting requires project or workspace admin access.

A task writer can change task status and assign or unassign a task; an assignee must be a workspace member, and `null` unassigns.

A project reader can list task comments, while a task writer can add comments.

My dashboard reads the workspace overview for project progress, task status totals, upcoming deadlines, member count, and recent activity.

My project lists and statistics are workspace-scoped and limited to projects visible to the current user.

When I create a project, the creator is automatically added as project administrator.

To add a project member, the user must already belong to the same workspace.

My task list filters are page, pageSize, status, priority, assigneeId, search, dueBefore, dueAfter; unassigned means no assignee.

My task creation example uses priority HIGH, dueAt 2026-10-20T17:00:00Z, status TODO.

Workspace OWNER/ADMIN can read and manage every project.

Other members and guests see only projects where they have project membership.

Project `VIEWER` is read-only; `MEMBER` can create and update tasks/comments, and project `ADMIN` can also manage project settings and members.

For resource access outside the caller’s workspace, my API returns 404 to avoid disclosing existence.

My mutations record actor, action, and relevant resource in ActivityLog within the same database transaction where applicable.

I’m building TaskFlow AI, an AI-powered project management SaaS. Its current repository is a TypeScript monorepo development foundation with a Next.js frontend, an Express API, shared Zod contracts, and a Prisma/PostgreSQL package. The frontend and API are independently runnable workspace applications.

I started the taskflow-ai repository in 2026-10, and it was last updated in 2026-10.

- I need Node.js 22.9 or newer (Node.js 22 LTS recommended), pnpm 11.19.0, and PostgreSQL 14 or newer for this repository.

The workspace is divided between `apps/api` for the Express REST API, authentication, authorization, and tests; `apps/web` for the Next.js App Router frontend; `packages/contracts` for shared Zod schemas and TypeScript types; and `packages/database` for the Prisma schema, migrations, and shared database client.

- I install dependencies with `pnpm install` and approve only named lifecycle scripts required by the workspace, including Prisma engines and esbuild.

```
Copy-Item .env.example .env
pnpm db:generate
pnpm db:migrate
```


I set `DATABASE_URL` to an accessible PostgreSQL database; the example URL is a local development placeholder, not a production credential. I create the database itself first if it does not exist.

For an existing shared, staging, or production database, I use reviewed checked-in migrations with `pnpm db:migrate:deploy`; `pnpm db:push` is prototype-only schema sync and does not create migrations.

I provide production `DATABASE_URL` through the deployment environment rather than a checked-in file, and I do not commit `.env` or put secrets in `NEXT_PUBLIC_*` variables because Next.js exposes those values to the browser.

```
pnpm dev:web
pnpm dev:api
```


I access the local frontend at `http://localhost:3000` and the API health endpoint at `http://localhost:4000/api/v1/health`.

| Command | Purpose |
|---|---|
| `pnpm dev:web` | Start Next.js in development mode |
| `pnpm dev:api` | Start Express with automatic TypeScript reload |
| `pnpm build:api` | Build the database client package and Express API |
| `pnpm test:api` | Run API unit, route, validation, and optional PostgreSQL workflow tests |
| `pnpm build:web` | Build the frontend for production |
| `pnpm typecheck` | Type-check all workspace packages |
| `pnpm lint` | Lint all workspace packages |
| `pnpm format` | Format tracked and unignored files with Prettier |
| `pnpm format:check` | Check formatting without modifying files |
| `pnpm db:generate` | Generate the Prisma client |
| `pnpm db:migrate` | Create/apply local development migrations |
| `pnpm db:migrate:deploy` | Apply checked-in migrations in shared environments |
| `pnpm db:migrate:status` | Show whether migrations have been applied |
| `pnpm db:push` | Prototype-only schema sync; does not create migrations |
| `pnpm db:studio` | Open Prisma Studio |


I add a frontend component from the repository root with the local shadcn/ui CLI, for example `pnpm --filter @taskflow/web run ui add button`; the frontend uses Tailwind CSS and is configured for shadcn/ui.

My API CORS allows the configured `WEB_ORIGIN`, which defaults to the local frontend origin. The health endpoint is a process liveness check and does not verify database readiness.

Authentication and core project, task, and team screens use the PostgreSQL-backed API; notifications and the AI assistant remain demo-only until their backend modules are available.

My browser API client uses `NEXT_PUBLIC_API_BASE_URL` and sends the HttpOnly session cookie with requests. Next.js server-rendered workspace pages use `API_INTERNAL_BASE_URL` and forward only the session cookie to Express; the session token is never stored in browser JavaScript storage.

My project and task forms use native browser input validation and send JSON through the shared API client. Express validates each request with Zod and authorizes against the authenticated database session.

My Prisma schema defines users and provider accounts and sessions; workspace and project membership join tables; projects and hierarchical tasks; comments, file metadata attachments, task dependencies, notifications, activity history, invitations, and a transactional outbox for real-time delivery.

My membership tables keep roles and membership timestamps on the relationship, and compound unique constraints prevent duplicate memberships. Indexes cover workspace and project lists, board columns and ordering, assignee queues, deadlines, unread notifications, activity timelines, and unpublished outbox events.

Deleting a workspace cascades through its projects and collaboration records, and deleting a project cascades through its tasks and task content. Deleting a user removes login and membership records while preserving authored content and history with nullable author references where appropriate.

My session, password-reset, and invitation tokens are stored as hashes; the application must encrypt OAuth credentials before persistence. Email addresses are stored lowercase, and task and invitation invariants are enforced by checks in the initial SQL migration.

My Prisma transactions cover project creation with its first administrator membership and activity record, and task changes with activity records. Parent tasks and assignees are checked against the current project or workspace before writes.

Invitation acceptance and outbox delivery remain future work. A worker can publish outbox rows to Socket.IO and retry failed delivery.

My authentication architecture follows this rule: The Express API owns credential verification and opaque database sessions.

My registration flow is transactional: Registration validates and normalizes input, hashes passwords with Node.js `scrypt`, then creates the user, owner membership, initial workspace, and session in one transaction.

My browser-session design is: The browser receives only a random session token in an `HttpOnly`, `SameSite=Lax` cookie; PostgreSQL stores its SHA-256 hash and expiration.

My Next.js workspace layout checks authentication before rendering: The Next.js workspace layout calls the protected `/auth/me` endpoint before rendering.

I require independent authentication checks for API routes: every API route verifies the session independently.

My session-management endpoints include `POST /api/v1/auth/login`, `/register`, and `/logout` manage sessions.

My profile endpoint behavior is: `/auth/me` reads and updates the current profile.

My session-management endpoint behavior is: `/auth/sessions` lists the current user’s active sessions and allows revocation.

I require workspace membership for reads: Workspace reads require membership.

My workspace-rename authorization rule is that workspace renames require an `OWNER` or `ADMIN` role fetched from PostgreSQL.

I do not accept role claims from request bodies: Request bodies cannot supply effective roles.

My password-reset flow uses Password reset uses short-lived, one-use hashed tokens.

My password-reset responses use generic responses to prevent account discovery.

After a successful password reset, my system revokes all sessions after a successful reset.

For local development, I follow this cookie-domain policy: Keep `SESSION_COOKIE_DOMAIN` empty for local development.

I set the cookie domain in production only under this condition: set it only when the frontend and API use related production hosts.

My proxy policy is: Set `TRUST_PROXY=true` only behind a trusted reverse proxy.

My current rate limiter is process-local: The current rate limiter is process-local.

Before running multiple API instances, I need to use a shared store before running multiple API instances.

I enable password-reset email delivery with this configuration: Configure `EMAIL_DELIVERY_URL`, `EMAIL_DELIVERY_TOKEN`, and `EMAIL_FROM` to enable password-reset email delivery.

My email-delivery request format is: The delivery service accepts a JSON POST with `from`, `to`, `subject`, and `text` fields.

My email-delivery settings are server-only: These settings are server-only.

I run `pnpm test:api` to build the database package and API: `pnpm test:api` builds the database package and API.

The test command then runs Node’s built-in test runner.

My API test runner covers password hashing, input validation, session-token handling, cookie policy, rate limits, CSRF origin checks, authorization policy, pagination, and unauthenticated route guards.

A PostgreSQL-backed project/task workflow test runs when `DATABASE_URL` is configured and the schema is migrated; otherwise it is skipped.

The password-reset token lifetime and rate-limit thresholds are unspecified. The shared store for multi-instance rate limiting and production values for email-delivery settings and `SESSION_COOKIE_DOMAIN` are also unspecified.

---
From Nikhil Gurung's second brain at agentsocialx.com/nikhil
