# API Documentation for TaskCo Builder Backend

## Overview

This document outlines all API endpoints required by the TaskCo Builder frontend application. The frontend uses two main API services:

1. **Builder API** (`/api/builder/*`) - For the CMS/builder interface (draft/editing mode)
2. **Published API** (`/api/published/*`) - For the live/public site (published content)

Both APIs share the same structure but serve different content sources.

---

## Base Configuration

```javascript
Base URL: process.env.NEXT_PUBLIC_API_URL
Authentication: Bearer token via cookies (taskco_auth_token)
Content-Type: application/json
Credentials: include (withCredentials: true)
```

### Authentication Headers

All authenticated requests include:

```
Authorization: Bearer {token}
```

The token is automatically retrieved from the `taskco_auth_token` cookie.

---

## 🏗️ Builder API Endpoints

Used by: `/builder` route (CMS editor interface)

### 1. Get Tenant Metadata

**Endpoint:** `GET /api/builder/meta`

**Description:** Fetch lightweight tenant metadata including theme, mode, layout, and list of pages.

**Request:**

```http
GET /api/builder/meta
Authorization: Bearer {token}
```

**Response:**

```json
{
  "success": true,
  "data": {
    "tenantId": "tenant1",
    "theme": "theme1",
    "mode": "light",
    "layout": {
      "nav": {
        "logo": "https://example.com/logo.png",
        "items": [
          {
            "label": "Home",
            "href": "/",
            "isExternal": false
          },
          {
            "label": "Products",
            "href": "/products",
            "isExternal": true,
            "children": [
              {
                "label": "item1",
                "href": "/item1",
                "isExternal": true
              }
            ]
          }
        ],
        "style": "default"
      },
      "footer": {
        "columns": [
          {
            "title": "Company",
            "links": [
              { "label": "About", "href": "/about" },
              { "label": "Contact", "href": "/contact" }
            ]
          }
        ],
        "copyright": "© 2024 Company. All rights reserved."
      }
    },
    "pages": [
      {
        "name": "home",
        "title": "Home Page",
        "isPublished": true,
        "updatedAt": "2024-01-06T10:00:00Z",
        "isDynamic": false
      },
      {
        "name": "blog-post",
        "title": "Blog Post Template",
        "isPublished": true,
        "updatedAt": "2024-01-06T10:00:00Z",
        "isDynamic": true,
        "dynamicConfig": {
          "routePattern": "blog/:slug",
          "paramName": "slug",
          "dataSource": "/api/mock/posts",
          "dataMatchField": "slug"
        }
      }
    ]
  }
}
```

**Notes:**

- This is called once on builder initialization
- Should be lightweight and fast
- `isDynamic` pages use template-based routing with parameter interpolation

---

### 2. Update Tenant Metadata

**Endpoint:** `PUT /api/builder/meta`

**Description:** Update tenant theme or mode settings.

**Request:**

```http
PUT /api/builder/meta
Authorization: Bearer {token}
Content-Type: application/json

{
  "theme": "theme1",
  "mode": "dark"
}
```

**Response:**

```json
{
  "success": true,
  "data": {
    "tenantId": "tenant1",
    "theme": "theme1",
    "mode": "dark",
    "layout": { ... },
    "pages": [ ... ]
  }
}
```

---

### 3. Get Page Data

**Endpoint:** `GET /api/builder/page/:pageName`

**Description:** Fetch a single page's section data for editing.

**Request:**

```http
GET /api/builder/page/home
Authorization: Bearer {token}
```

**Response:**

```json
{
  "success": true,
  "data": {
    "pageName": "home",
    "sections": [
      {
        "id": "section-1",
        "type": "Hero",
        "variant": "centered",
        "data": {
          "title": "Welcome to Our Site",
          "subtitle": "Build amazing experiences",
          "buttonText": "Get Started",
          "buttonLink": "/signup",
          "backgroundImage": "https://example.com/hero-bg.jpg"
        }
      },
      {
        "id": "section-2",
        "type": "Features",
        "variant": "grid",
        "data": {
          "title": "Our Features",
          "features": [
            {
              "icon": "star",
              "title": "Fast",
              "description": "Lightning fast performance"
            }
          ]
        }
      }
    ],
    "updatedAt": "2024-01-06T10:00:00Z",
    "isDraft": true,
    "isDynamic": false
  }
}
```

**Dynamic Page Response (Template):**

```json
{
  "success": true,
  "data": {
    "pageName": "blog-post",
    "sections": [
      {
        "id": "section-1",
        "type": "BlogPost",
        "variant": "default",
        "data": {
          "title": "{{title}}",
          "content": "{{content}}",
          "author": "{{author}}",
          "publishedDate": "{{publishedDate}}",
          "image": "{{featuredImage}}"
        }
      }
    ],
    "updatedAt": "2024-01-06T10:00:00Z",
    "isDraft": true,
    "isDynamic": true,
    "dynamicConfig": {
      "routePattern": "blog/:slug",
      "paramName": "slug",
      "dataSource": "/api/mock/posts",
      "dataMatchField": "slug"
    }
  }
}
```

**Notes:**

- Dynamic pages contain `{{placeholder}}` syntax that gets replaced with actual data
- The frontend will fetch data from `dataSource` and interpolate values

---

### 4. Save Page Data

**Endpoint:** `PUT /api/builder/page/:pageName`

**Description:** Save page sections as draft (not published).

**Request:**

```http
PUT /api/builder/page/home
Authorization: Bearer {token}
Content-Type: application/json

{
  "sections": [
    {
      "id": "section-1",
      "type": "Hero",
      "variant": "centered",
      "data": {
        "title": "Updated Welcome",
        "subtitle": "New subtitle"
      }
    }
  ]
}
```

**Response:**

```json
{
  "success": true,
  "message": "Page saved successfully",
  "data": {
    "pageName": "home",
    "updatedAt": "2024-01-06T10:30:00Z"
  }
}
```

---

### 5. Publish Page

**Endpoint:** `POST /api/builder/page/:pageName/publish`

**Description:** Publish the current draft version of a page to make it live.

**Request:**

```http
POST /api/builder/page/home/publish
Authorization: Bearer {token}
```

**Response:**

```json
{
  "success": true,
  "message": "Page published successfully",
  "publishedAt": "2024-01-06T10:35:00Z"
}
```

**Notes:**

- This should copy the draft page data to the published storage
- Published content should be available via `/api/published/page/:pageName`

---

### 6. Publish All Pages

**Endpoint:** `POST /api/builder/publish`

**Description:** Publish all draft changes (all pages, header, footer) to production.

**Request:**

```http
POST /api/builder/publish
Authorization: Bearer {token}
```

**Response:**

```json
{
  "success": true,
  "message": "All changes published successfully",
  "publishedAt": "2024-01-06T10:40:00Z",
  "publishedItems": {
    "pages": ["home", "about", "contact"],
    "header": true,
    "footer": true
  }
}
```

---

### 7. Save Header Layout

**Endpoint:** `PUT /api/builder/header`

**Description:** Save navigation/header layout as draft.

**Request:**

```http
PUT /api/builder/header
Authorization: Bearer {token}
Content-Type: application/json

{
  "logo": "http://localhost/assets/logo/logo-v2.svg",
  "menuItems": [
      {
          "label": "item1",
          "href": "/item1",
          "isExternal": false,
          "icon": "box"
      }
  ],
  "navbarStyle": "style2"
}
```

**Response:**

```json
{
  "success": true,
  "message": "Header saved successfully"
}
```

---

### 8. Publish Header

**Endpoint:** `POST /api/builder/header/publish`

**Description:** Publish header/navigation changes to production.

**Request:**

```http
POST /api/builder/header/publish
Authorization: Bearer {token}
```

**Response:**

```json
{
  "success": true,
  "message": "Header published successfully"
}
```

---

### 9. Save Footer Layout

**Endpoint:** `PUT /api/builder/footer`

**Description:** Save footer layout as draft.

**Request:**

```http
PUT /api/builder/footer
Authorization: Bearer {token}
Content-Type: application/json

{
  "columns": [
    {
      "title": "Company",
      "links": [
        { "label": "About", "href": "/about" },
        { "label": "Contact", "href": "/contact" }
      ]
    },
    {
      "title": "Legal",
      "links": [
        { "label": "Privacy", "href": "/privacy" },
        { "label": "Terms", "href": "/terms" }
      ]
    }
  ],
  "copyright": "© 2024 Company. All rights reserved.",
  "socialLinks": [
    { "platform": "twitter", "url": "https://twitter.com/company" },
    { "platform": "linkedin", "url": "https://linkedin.com/company/company" }
  ]
}
```

**Response:**

```json
{
  "success": true,
  "message": "Footer saved successfully"
}
```

---

### 10. Publish Footer

**Endpoint:** `POST /api/builder/footer/publish`

**Description:** Publish footer changes to production.

**Request:**

```http
POST /api/builder/footer/publish
Authorization: Bearer {token}
```

**Response:**

```json
{
  "success": true,
  "message": "Footer published successfully"
}
```

---

## 🌐 Published API Endpoints

Used by: `/` root route (live public site)

These endpoints serve the **published/live** content to end users.

### 1. Get Published Metadata

**Endpoint:** `GET /api/published/meta`

**Description:** Fetch published tenant metadata for the live site.

**Request:**

```http
GET /api/published/meta
```

**Response:**

```json
{
  "success": true,
  "data": {
    "tenantId": "tenant1",
    "theme": "theme1",
    "mode": "light",
    "layout": {
      "nav": { ... },
      "footer": { ... }
    },
    "pages": [
      {
        "name": "home",
        "title": "Home Page",
        "isPublished": true,
        "updatedAt": "2024-01-06T10:00:00Z",
        "isDynamic": false
      }
    ],
    "updatedAt": "2024-01-06T10:00:00Z"
  }
}
```

**Notes:**

- This endpoint is **public** (no authentication required)
- Should only return published pages where `isPublished: true`
- Must include `isDynamic` and `dynamicConfig` for dynamic pages

---

### 2. Get Published Page

**Endpoint:** `GET /api/published/page/:pageName`

**Description:** Fetch a published page's section data.

**Request:**

```http
GET /api/published/page/home
```

**Response:**

```json
{
  "success": true,
  "data": {
    "pageName": "home",
    "sections": [ ... ],
    "updatedAt": "2024-01-06T10:00:00Z",
    "isDraft": false,
    "isDynamic": false
  }
}
```

**Dynamic Page Response:**

```json
{
  "success": true,
  "data": {
    "pageName": "blog-post",
    "sections": [
      {
        "id": "section-1",
        "type": "BlogPost",
        "data": {
          "title": "{{title}}",
          "content": "{{content}}",
          "author": "{{author}}"
        }
      }
    ],
    "isDraft": false,
    "isDynamic": true,
    "dynamicConfig": {
      "routePattern": "blog/:slug",
      "paramName": "slug",
      "dataSource": "/api/mock/posts",
      "dataMatchField": "slug"
    }
  }
}
```

**Notes:**

- This endpoint is **public** (no authentication required)
- For dynamic pages, return the template with `{{placeholders}}`
- Include `dynamicConfig` so frontend knows how to fetch and interpolate data

---

## 📊 Dynamic Data Endpoints

These endpoints provide data for dynamic routes (blogs, products, etc.)

### 1. Get Menu Items

**Endpoint:** `GET /api/menus`

**Description:** Fetch dynamic menu items for navigation.

**Request:**

```http
GET /api/menus?scheme=products
```

**Response:**

```json
{
  "success": true,
  "data": {
    "menuItems": [
      {
        "label": "Product A",
        "href": "/products/product-a",
        "icon": "box"
      },
      {
        "label": "Product B",
        "href": "/products/product-b",
        "icon": "box"
      }
    ]
  }
}
```

**Notes:**

- This endpoint is **public**
- Used to populate dynamic navigation menus

---

### 2. Get Blog Posts (Example)

**Endpoint:** `GET /api/mock/posts`

**Description:** Fetch blog posts data for dynamic blog pages.

**Request:**

```http
GET /api/mock/posts?slug=my-first-post
```

**Response (Single Post):**

```json
{
  "success": true,
  "data": {
    "slug": "my-first-post",
    "title": "My First Post",
    "content": "<p>This is the full post content...</p>",
    "author": "John Doe",
    "publishedDate": "2024-01-05",
    "featuredImage": "https://example.com/post-image.jpg",
    "tags": ["react", "nextjs"]
  }
}
```

**Response (All Posts):**

```json
{
  "success": true,
  "data": [
    {
      "slug": "my-first-post",
      "title": "My First Post",
      "excerpt": "Short description...",
      "author": "John Doe",
      "publishedDate": "2024-01-05"
    },
    {
      "slug": "second-post",
      "title": "Second Post",
      "excerpt": "Another post...",
      "author": "Jane Smith",
      "publishedDate": "2024-01-04"
    }
  ]
}
```

**Notes:**

- This endpoint is **public**
- When `?slug=value` is provided, return single matching item
- When no params, return array of all items
- Field names must match those used in page templates (e.g., `{{slug}}`, `{{title}}`)

---

### 3. Get Products (Example)

**Endpoint:** `GET /api/mock/products`

**Description:** Fetch products data for dynamic product pages.

**Request:**

```http
GET /api/mock/products?id=product-123
```

**Response:**

```json
{
  "success": true,
  "data": {
    "id": "product-123",
    "name": "Awesome Product",
    "description": "Product description here",
    "price": 99.99,
    "image": "https://example.com/product.jpg",
    "category": "Electronics"
  }
}
```

---

## 🔐 Authentication Endpoints

### 1. Login

**Endpoint:** `POST /api/auth/login`

**Description:** Authenticate user and return auth token.

**Request:**

```http
POST /api/auth/login
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "securepassword"
}
```

**Response:**

```json
{
  "success": true,
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "id": "user-123",
    "email": "user@example.com",
    "name": "John Doe",
    "role": "admin"
  }
}
```

**Notes:**

- Frontend stores token in `taskco_auth_token` cookie
- Token should be JWT with reasonable expiration (e.g., 7 days)

---

### 2. Logout

**Endpoint:** `POST /api/auth/logout`

**Description:** Invalidate user session/token.

**Request:**

```http
POST /api/auth/logout
Authorization: Bearer {token}
```

**Response:**

```json
{
  "success": true,
  "message": "Logged out successfully"
}
```

---

### 3. Get Current User

**Endpoint:** `GET /api/auth/me`

**Description:** Get currently authenticated user details.

**Request:**

```http
GET /api/auth/me
Authorization: Bearer {token}
```

**Response:**

```json
{
  "success": true,
  "user": {
    "id": "user-123",
    "email": "user@example.com",
    "name": "John Doe",
    "role": "admin"
  },
  "tenant": "tenant1"
}
```

---

## ⚠️ Error Responses

All endpoints should return consistent error responses:

### 400 Bad Request

```json
{
  "success": false,
  "error": "Invalid page name"
}
```

### 401 Unauthorized

```json
{
  "success": false,
  "error": "Authentication required"
}
```

### 403 Forbidden

```json
{
  "success": false,
  "error": "Access denied"
}
```

### 404 Not Found

```json
{
  "success": false,
  "error": "Page not found"
}
```

### 500 Internal Server Error

```json
{
  "success": false,
  "error": "Internal server error",
  "message": "Detailed error message"
}
```

---

## 🔄 Data Flow for Dynamic Routes

### How Dynamic Pages Work:

1. **Frontend requests published meta:**

   ```
   GET /api/published/meta
   ```

2. **Backend returns pages including dynamic config:**

   ```json
   {
     "pages": [
       {
         "name": "blog-post",
         "isDynamic": true,
         "dynamicConfig": {
           "routePattern": "blog/:slug",
           "paramName": "slug",
           "dataSource": "/api/mock/posts",
           "dataMatchField": "slug"
         }
       }
     ]
   }
   ```

3. **User visits `/blog/my-first-post`**

4. **Frontend matches route pattern and extracts `slug=my-first-post`**

5. **Frontend fetches page template:**

   ```
   GET /api/published/page/blog-post
   ```

6. **Backend returns template with placeholders:**

   ```json
   {
     "sections": [
       {
         "data": {
           "title": "{{title}}",
           "content": "{{content}}"
         }
       }
     ]
   }
   ```

7. **Frontend fetches actual data:**

   ```
   GET /api/mock/posts?slug=my-first-post
   ```

8. **Backend returns actual post data:**

   ```json
   {
     "data": {
       "slug": "my-first-post",
       "title": "My First Post",
       "content": "<p>Content here...</p>"
     }
   }
   ```

9. **Frontend replaces `{{title}}` with "My First Post", `{{content}}` with actual content**

10. **Page is rendered with actual data**

---

## 📝 Implementation Notes

### Storage Structure

You should maintain two separate storage areas:

**1. Draft Storage** (for `/api/builder/*`)

```
/builder/tenant1/
  ├── meta.json         (metadata + pages list)
  ├── header.json       (draft header)
  ├── footer.json       (draft footer)
  └── pages/
      ├── home.json
      ├── about.json
      └── blog-post.json
```

**2. Published Storage** (for `/api/published/*`)

```
/published/tenant1.json  (merged published config)
```

### Publishing Process

When publishing:

1. Copy draft data from builder storage
2. Merge into published storage
3. Update `isPublished` flags
4. Update `updatedAt` timestamps

### Performance Considerations

- **Cache published data** aggressively (it changes rarely)
- **Meta endpoints** should be fast (<50ms) - they're called on every page load
- **Page endpoints** can be slightly slower but should still be fast (<200ms)
- Consider CDN for published content

### Security

- **Builder endpoints** require authentication
- **Published endpoints** are public
- Validate all input data
- Sanitize section data to prevent XSS
- Rate limit API endpoints

---

## 🧪 Testing Checklist

### Builder API

- [ ] Can fetch metadata with auth
- [ ] Can update theme/mode
- [ ] Can save page as draft
- [ ] Can fetch page data
- [ ] Can publish single page
- [ ] Can publish all changes
- [ ] Can save/publish header
- [ ] Can save/publish footer
- [ ] Returns 401 without auth token

### Published API

- [ ] Can fetch published metadata without auth
- [ ] Can fetch published pages without auth
- [ ] Returns only published pages
- [ ] Dynamic pages include correct config
- [ ] Returns 404 for unpublished pages

### Dynamic Data

- [ ] Menu endpoints return correct data
- [ ] Blog/Product endpoints work with query params
- [ ] Returns single item when filtered
- [ ] Returns array when no filter
- [ ] Field names match template placeholders

### Authentication

- [ ] Login returns valid token
- [ ] Token works in Authorization header
- [ ] Logout invalidates token
- [ ] Get user returns correct data
- [ ] 401 on expired/invalid token

---

## 📞 Support

If you have questions about any endpoint or need clarification on the data structure, please reach out to shakib.

**Frontend Implementation Files:**

- `/src/lib/api.ts` - API client and endpoint definitions
- `/src/hooks/useTenantConfig.ts` - Builder hook implementation
- `/src/hooks/useLiveSite.ts` - Live site hook implementation
- `/src/components/builder/Builder.tsx` - Builder interface
- `/src/components/TenantSite.tsx` - Live site component
