Skip to main content

Project Management

POST /api/user/project

Create a new project for the authenticated user.

Authentication

Requires a valid NextAuth session.

Request Body

{
  "userId": "string",
  "name": "string"
}
userId
string
required
The ID of the user creating the project
name
string
required
The name of the project (e.g., “Untitled Project”)

Response (200)

{
  "id": "uuid",
  "userId": "string",
  "name": "string",
  "createdDate": "2024-01-01T00:00:00.000Z"
}

Example Request

const response = await fetch('/api/user/project', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    userId: 'user-123',
    name: 'My New Project'
  })
});

const project = await response.json();
console.log(project.id); // UUID of created project

GET /api/user/project

Get all projects for the authenticated user.

Authentication

Requires a valid NextAuth session.

Query Parameters

userId
string
required
The ID of the user whose projects to retrieve

Response (200)

[
  {
    "id": "uuid",
    "userId": "string",
    "name": "string",
    "createdDate": "2024-01-01T00:00:00.000Z"
  }
]

Error Responses

400 - Missing User ID
{
  "error": "User ID is required"
}
401 - Unauthorized
{
  "error": "Unauthorized"
}

Example Request

const userId = 'user-123';
const response = await fetch(`/api/user/project?userId=${userId}`, {
  method: 'GET',
  headers: {
    'Content-Type': 'application/json',
  }
});

const projects = await response.json();
console.log(projects.length); // Number of projects

Canvas Management

POST /api/user/project/canvas

Save or update the canvas state for a project. Uses upsert operation.

Authentication

Requires a valid NextAuth session.

Request Body

{
  "id": "string (optional)",
  "projectId": "string",
  "nodes": "array",
  "edges": "array"
}
id
string
Canvas ID (if updating existing canvas). Generated automatically if not provided.
projectId
string
required
The ID of the project this canvas belongs to
nodes
array
required
Array of node objects representing the canvas nodes
interface Node {
  id: string;
  type: 'upload' | 'generation';
  position: { x: number; y: number };
  data: {
    type: 'upload' | 'generation';
    image?: string;
    prompt?: string;
    isGenerating?: boolean;
  };
}
edges
array
required
Array of edge objects representing connections between nodes
interface Edge {
  id: string;
  source: string;
  target: string;
  sourceHandle?: string;
  targetHandle?: string;
}

Response (200)

Returns the saved canvas object:
{
  "id": "uuid",
  "projectId": "string",
  "nodes": [],
  "edges": []
}

Example Request

const response = await fetch('/api/user/project/canvas', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    projectId: 'project-123',
    nodes: [
      {
        id: 'upload-1',
        type: 'upload',
        position: { x: 0, y: 0 },
        data: {
          type: 'upload',
          image: 'https://...'
        }
      }
    ],
    edges: []
  })
});

const canvas = await response.json();

GET /api/user/project/canvas

Load the canvas state for a project.

Authentication

Requires a valid NextAuth session.

Query Parameters

projectId
string
required
The ID of the project whose canvas to retrieve

Response (200)

{
  "id": "uuid",
  "projectId": "string",
  "nodes": [],
  "edges": []
}
Returns null if no canvas exists for the project.

Error Responses

400 - Missing Project ID
{
  "error": "Project ID is required"
}
401 - Unauthorized
{
  "error": "Unauthorized"
}

Example Request

const projectId = 'project-123';
const response = await fetch(`/api/user/project/canvas?projectId=${projectId}`, {
  method: 'GET',
  headers: {
    'Content-Type': 'application/json',
  }
});

const canvas = await response.json();
if (canvas) {
  console.log('Canvas loaded:', canvas.nodes.length, 'nodes');
} else {
  console.log('No canvas found for this project');
}

Database Schema

Projects Collection

{
  "id": "uuid",
  "userId": "string",
  "name": "string",
  "createdDate": "ISOString"
}
Container: projects Partition Key: userId

Canvas Collection

{
  "id": "uuid",
  "projectId": "string",
  "nodes": "array",
  "edges": "array"
}
Container: canvas Partition Key: projectId

Auto-Save Behavior

The canvas automatically saves every second (with debounce) when changes are made:
const [debouncedNodes] = useDebounce(nodes, 1000);
const [debouncedEdges] = useDebounce(edges, 1000);

useEffect(() => {
  if (!canvasData || nodes !== debouncedNodes || !isInitialized) return;

  await fetch('/api/user/project/canvas', {
    method: 'POST',
    body: JSON.stringify({
      id: canvasData.id,
      projectId: canvasData.projectId,
      nodes: debouncedNodes,
      edges: debouncedEdges
    })
  });
}, [debouncedNodes, debouncedEdges]);
This ensures that:
  • Changes are saved automatically
  • API calls are throttled to prevent excessive requests
  • Users don’t lose work on accidental page closure