# Client SDK Usage Guide

This project uses an auto-generated SDK powered by `@hey-api/openapi-ts` to interact with the PayloadCMS multi-tenant backend.

## SDK Structure

- **Core Methods**: `src/clientsdk/sdk.gen.ts` (Contains classes like `Posts`, `Categories`, `Pages`, `Media`)
- **Type Definitions**: `src/clientsdk/types.gen.ts` (Contains interfaces like `Post`, `Category`, `Media`)
- **Query Serializer**: `src/clientsdk/querySerializer.ts` (Handles nested object serialization for PayloadCMS queries)
- **Client Factory**: `src/clientsdk/client/index.ts` (Use `createClient` to initialize a client instance)

## 1. Initialization

You must initialize the client with the correct `baseUrl`, `querySerializer`, and tenant headers.

```typescript
import { createClient } from '../clientsdk/client';
import { customQuerySerializer } from '../clientsdk/querySerializer';
import { TENANT_SLUG, TENANT_API_KEY, API_URL } from '../config';

const client = createClient({
  baseUrl: API_URL,
  querySerializer: customQuerySerializer, // CRITICAL: Required for nested where queries
  headers: {
    'X-Tenant-Slug': TENANT_SLUG,
    'X-API-Key': TENANT_API_KEY,
  },
});
```

## 2. Common Operations

### Fetching a List (with Sorting & Limits)
```typescript
import { Posts } from '../clientsdk/sdk.gen';

const response = await Posts.listPosts({
  client,
  query: {
    limit: 10,
    sort: '-createdAt', // Prefix with '-' for descending
  },
});

// Access the data
const posts = response.data?.docs || [];
```

### Fetching a Single Document by Slug (Filtering)
PayloadCMS uses a specific `where` query syntax. The `customQuerySerializer` handles the translation to `where[slug][equals]=my-slug`.

```typescript
const response = await Posts.listPosts({
  client,
  query: {
    where: {
      slug: {
        equals: 'my-article-slug',
      },
    },
    limit: 1,
  },
});

const post = response.data?.docs?.[0];
```

### Filtering by Category Slug
```typescript
const response = await Posts.listPosts({
  client,
  query: {
    where: {
      'categories.slug': {
        equals: 'news',
      },
    },
  },
});
```

## 3. Data Patterns

### Relationships
- **Categories**: In this project, categories are a **many-to-many** relationship. Always treat `post.categories` as an array.
  - Correct: `post.categories?.[0]?.title`
  - Incorrect: `post.category.title`
- **Media**: Images (like `heroImage`) are objects containing `url`, `alt`, and `sizes`.
  - Example: `<img src={post.heroImage?.url} alt={post.heroImage?.alt} />`

### Rich Text (Lexical)
PayloadCMS provides Lexical rich text. We typically use `post.content_html` which is pre-rendered to HTML on the server.
- **React**: `<div dangerouslySetInnerHTML={{ __html: post.content_html }} />`
- **Vue**: `<div v-html="post.content_html" />`
- **Astro**: `<div set:html={post.content_html} />`

## 4. TypeScript Usage

Always use the generated types for better DX and safety.

```typescript
import type { Post, Category, Media } from '../clientsdk/types.gen';

function formatPost(post: Post) {
  return {
    title: post.title,
    date: new Date(post.createdAt).toLocaleDateString()
  };
}
```

## 5. Troubleshooting

- **CORS Issues**: Ensure `API_URL` in `config.ts` matches the backend port (default 3000).
- **Empty Results**: Check if the `X-Tenant-Slug` header matches the slug assigned to your content in the CMS admin panel.
- **Nested Query Error**: If you see "Deeply-nested arrays/objects aren’t supported", verify that you are passing the `customQuerySerializer` to the `createClient` options.
