# Lilith Domain API Overview

Lilith is the consciousness and spiritual exploration domain of the Oshun
platform. It is a large-scale microservice architecture with 80+ services that
communicate through a central **BFF (Backend-for-Frontend)** gateway. The BFF
aggregates, orchestrates, and proxies requests to downstream services, providing
a unified API surface for web, mobile, and CLI clients.

---

## Architecture Summary

### BFF Gateway

| Property     | Value                                  |
| ------------ | -------------------------------------- |
| Service      | `@lilith/bff`                          |
| Framework    | Fastify                                |
| Default Port | 3001                                   |
| GraphQL      | Mercurius (at `/graphql`)              |
| Auth         | JWT Bearer tokens + test token support |
| Source       | `apps/lilith/bff/src/`                 |

The BFF is the **only** service that external clients communicate with directly.
All other microservices are internal and reachable only through the BFF's
service proxy layer.

### Backend Service Registry

The BFF routes requests to the following backend services:

| Service        | Default Port | Timeout | Retries | Purpose                               |
| -------------- | ------------ | ------- | ------- | ------------------------------------- |
| `auth`         | 3003         | 5s      | 3       | Authentication, authorization, tokens |
| `conversation` | 3002         | 5s      | 3       | Conversation threads and history      |
| `ai`           | 3004         | 30s     | 1       | LLM inference and AI processing       |
| `rag`          | 3005         | 10s     | 2       | Retrieval-Augmented Generation        |
| `knowledge`    | 3006         | 5s      | 3       | Knowledge graph and ontology          |
| `tts`          | 3007         | 15s     | 1       | Text-to-speech synthesis              |
| `stt`          | 3008         | 15s     | 1       | Speech-to-text recognition            |
| `media`        | 3009         | 5s      | 3       | Media asset storage and retrieval     |
| `content`      | 3010         | 5s      | 3       | Scholarly content management          |
| `moderation`   | 3011         | 5s      | 2       | Content moderation and safety         |
| `notification` | 3012         | 5s      | 3       | Push and email notifications          |

Service URLs can be overridden via environment variables (e.g.,
`AUTH_SERVICE_URL`, `AI_SERVICE_TIMEOUT`). Each service also supports regional
URL configuration for geo-sharding via `<SERVICE>_SERVICE_REGIONAL_URLS` (JSON)
and `<SERVICE>_SERVICE_DEFAULT_REGION`.

---

## Authentication

The BFF uses JWT Bearer tokens for authentication:

```
Authorization: Bearer <jwt_token>
```

Protected endpoints use the `requireAuth` pre-handler hook. Test tokens
(`playwright-test`, `test-token`, `test-*`) are recognized in non-production
environments and map to a default test user.

---

## REST API Endpoints

### Health & Observability

| Method | Path              | Auth | Description                                |
| ------ | ----------------- | ---- | ------------------------------------------ |
| GET    | `/health`         | No   | Basic health check                         |
| GET    | `/v1/health`      | No   | Extended health with dependency checks     |
| GET    | `/v1/health/deep` | No   | Deep health probing downstream services    |
| GET    | `/metrics`        | No   | JSON or Prometheus metrics (Accept header) |
| GET    | `/v1/metrics`     | No   | Detailed BFF metrics                       |

### Authentication (Proxy to `auth` service)

| Method | Path                | Auth | Description                |
| ------ | ------------------- | ---- | -------------------------- |
| POST   | `/v1/auth/register` | No   | Register a new user        |
| POST   | `/v1/auth/login`    | No   | Login with credentials     |
| POST   | `/v1/auth/refresh`  | No   | Refresh JWT token          |
| POST   | `/v1/auth/logout`   | Yes  | Invalidate current session |

#### Login Request Example

```json
{
  "email": "user@example.com",
  "password": "secure-password"
}
```

#### Login Response

```json
{
  "token": "eyJhbGciOiJSUzI1NiIs...",
  "refreshToken": "rt_abc123...",
  "user": {
    "id": "usr_001",
    "email": "user@example.com",
    "role": "user"
  }
}
```

### Chat & AI Conversation

The chat endpoints are the core of the Lilith experience. They support JSON
responses, SSE streaming, personalized responses via personas, and comparative
multi-persona queries.

| Method | Path                    | Auth | Description                                    |
| ------ | ----------------------- | ---- | ---------------------------------------------- |
| POST   | `/v1/chat`              | Yes  | Send a chat message (JSON response)            |
| POST   | `/v1/chat/stream`       | Yes  | Send a chat message (SSE streaming response)   |
| POST   | `/v1/chat/personalized` | No   | Get a persona-personalized response            |
| POST   | `/v1/chat/comparative`  | No   | Query 2-5 personas simultaneously              |
| POST   | `/v1/chat/audio`        | Yes  | Audio-based chat (speech-to-text -> AI -> TTS) |

#### Chat Request Example

```json
{
  "message": "What does the Bhagavad Gita say about dharma?",
  "personaId": "persona_krishna",
  "conversationId": "conv_001",
  "options": {
    "model": "claude-3-opus",
    "temperature": 0.7,
    "maxTokens": 2000,
    "stream": false
  }
}
```

#### Comparative Chat Request

```json
{
  "question": "What is the nature of suffering?",
  "personaIds": ["persona_buddha", "persona_seneca", "persona_rumi"],
  "options": {
    "maxTokens": 1500
  }
}
```

Requires 2-5 persona IDs. Returns parallel responses from each persona.

#### SSE Streaming Response

When using `/v1/chat/stream`, the response uses Server-Sent Events:

```
data: {"type":"start","conversationId":"conv_001"}

data: {"type":"token","content":"The"}

data: {"type":"token","content":" Bhagavad"}

data: {"type":"done","usage":{"promptTokens":150,"completionTokens":800}}
```

Streaming supports backpressure handling and idempotency caching for
non-streaming responses.

### Personas

Personas represent spiritual, philosophical, and intellectual archetypes that
shape AI responses (e.g., Buddha, Rumi, Seneca, Krishna).

| Method | Path                        | Auth | Description                          |
| ------ | --------------------------- | ---- | ------------------------------------ |
| GET    | `/v1/personas`              | No   | List all personas                    |
| GET    | `/v1/personas/:id`          | No   | Get persona details                  |
| GET    | `/v1/personas/categories`   | No   | List personas grouped by category    |
| GET    | `/v1/personas/personalized` | No   | Get personalized persona suggestions |

### Users & Preferences

| Method | Path                                     | Auth | Description                   |
| ------ | ---------------------------------------- | ---- | ----------------------------- |
| GET    | `/v1/users/:userId/language-preferences` | No   | Get user language preferences |
| POST   | `/v1/users/:userId/language-preferences` | No   | Update language preferences   |

Supported languages: en, es, fr, de, it, pt, zh, ja, ko, ar, hi, ru.

### Conversation Context & History

| Method | Path                          | Auth | Description                          |
| ------ | ----------------------------- | ---- | ------------------------------------ |
| GET    | `/v1/conversations/:threadId` | Yes  | Get conversation context and history |
| POST   | `/v1/conversations`           | Yes  | Create a new conversation thread     |

### Content Management

The content API provides CRUD operations for scholarly and spiritual texts,
commentaries, translations, lectures, and multimedia content. Mounted at
`/api/v1/content`.

| Method | Path                               | Auth | Description                         |
| ------ | ---------------------------------- | ---- | ----------------------------------- |
| GET    | `/api/v1/content`                  | No   | List content with pagination/filter |
| POST   | `/api/v1/content`                  | Yes  | Create content                      |
| GET    | `/api/v1/content/:id`              | No   | Get content by ID                   |
| PUT    | `/api/v1/content/:id`              | Yes  | Update content                      |
| DELETE | `/api/v1/content/:id`              | Yes  | Delete content                      |
| POST   | `/api/v1/content/:id/publish`      | Yes  | Publish content                     |
| POST   | `/api/v1/content/:id/archive`      | Yes  | Archive content                     |
| GET    | `/api/v1/content/:id/versions`     | No   | Get version history                 |
| POST   | `/api/v1/content/:id/restore/:ver` | Yes  | Restore a previous version          |
| GET    | `/api/v1/content/search`           | No   | Full-text search with facets        |
| POST   | `/api/v1/content/bulk`             | Yes  | Bulk operations                     |

### Webhooks

| Method | Path                   | Auth | Description                 |
| ------ | ---------------------- | ---- | --------------------------- |
| GET    | `/api/v1/webhooks`     | Yes  | List webhook subscriptions  |
| POST   | `/api/v1/webhooks`     | Yes  | Create webhook subscription |
| GET    | `/api/v1/webhooks/:id` | Yes  | Get webhook details         |
| PUT    | `/api/v1/webhooks/:id` | Yes  | Update webhook              |
| DELETE | `/api/v1/webhooks/:id` | Yes  | Delete webhook              |

### Curricula & Learning Paths

| Method | Path                | Auth | Description            |
| ------ | ------------------- | ---- | ---------------------- |
| GET    | `/v1/curricula`     | No   | List curricula         |
| GET    | `/v1/curricula/:id` | No   | Get curriculum details |
| POST   | `/v1/curricula`     | Yes  | Create curriculum      |

### Scholar Notes

| Method | Path                    | Auth | Description               |
| ------ | ----------------------- | ---- | ------------------------- |
| GET    | `/v1/scholar-notes`     | Yes  | List user's scholar notes |
| POST   | `/v1/scholar-notes`     | Yes  | Create a note             |
| GET    | `/v1/scholar-notes/:id` | Yes  | Get a note                |
| PUT    | `/v1/scholar-notes/:id` | Yes  | Update a note             |
| DELETE | `/v1/scholar-notes/:id` | Yes  | Delete a note             |

### Reflections

| Method | Path                  | Auth | Description             |
| ------ | --------------------- | ---- | ----------------------- |
| GET    | `/v1/reflections`     | Yes  | List user's reflections |
| POST   | `/v1/reflections`     | Yes  | Create a reflection     |
| GET    | `/v1/reflections/:id` | Yes  | Get a reflection        |

### Experiments & A/B Testing

| Method | Path                     | Auth | Description               |
| ------ | ------------------------ | ---- | ------------------------- |
| GET    | `/v1/experiments`        | No   | List active experiments   |
| POST   | `/v1/experiments/assign` | No   | Assign experiment variant |

### AI Models

| Method | Path                   | Auth | Description                      |
| ------ | ---------------------- | ---- | -------------------------------- |
| GET    | `/v1/models`           | No   | List available AI models         |
| POST   | `/v1/models/negotiate` | No   | Negotiate best model for request |

### Dashboard & Aggregation

| Method | Path              | Auth | Description                              |
| ------ | ----------------- | ---- | ---------------------------------------- |
| GET    | `/v1/dashboard`   | Yes  | Aggregated dashboard data                |
| POST   | `/v1/aggregation` | Yes  | Custom aggregation query                 |
| POST   | `/v1/bulk`        | Yes  | Bulk operations across multiple entities |

### Circuit Breaker & Error Management

| Method | Path                               | Auth | Description                      |
| ------ | ---------------------------------- | ---- | -------------------------------- |
| GET    | `/v1/circuit-breaker`              | No   | Overview of all circuit breakers |
| GET    | `/v1/circuit-breaker/:serviceName` | No   | Details for a specific service   |
| GET    | `/v1/errors`                       | No   | Error normalization status       |
| POST   | `/v1/errors/test`                  | No   | Test error normalization         |

### ComfyUI Integration

| Method | Path                    | Auth | Description                          |
| ------ | ----------------------- | ---- | ------------------------------------ |
| POST   | `/v1/comfyui/generate`  | Yes  | Submit a ComfyUI generation workflow |
| GET    | `/v1/comfyui/workflows` | No   | List available workflows             |

### Partner & Mythology Content

| Method | Path            | Auth | Description                   |
| ------ | --------------- | ---- | ----------------------------- |
| GET    | `/v1/partners`  | No   | List partner integrations     |
| GET    | `/v1/mythology` | No   | Browse mythology content      |
| GET    | `/v1/research`  | No   | Browse consciousness research |

### Comparative Views

| Method | Path              | Auth | Description                         |
| ------ | ----------------- | ---- | ----------------------------------- |
| POST   | `/v1/comparative` | No   | Parallel persona query with caching |

### Tracing Configuration

| Method | Path                 | Auth | Description           |
| ------ | -------------------- | ---- | --------------------- |
| POST   | `/v1/config/tracing` | No   | Update tracing config |
| POST   | `/v1/tracing/test`   | No   | Generate test trace   |

---

## GraphQL API

The BFF exposes a GraphQL endpoint via Mercurius at `/graphql`. In
non-production environments, an interactive GraphQL playground is available.
Real-time subscriptions are enabled.

### Schema Overview

The GraphQL schema covers scholarly content management with the following root
types:

#### Queries

| Query                             | Description                              |
| --------------------------------- | ---------------------------------------- |
| `content(id: ID!)`                | Get a single content item                |
| `contentBySlug(slug)`             | Get content by URL slug                  |
| `contents(...)`                   | Paginated content list with filters/sort |
| `searchContent(...)`              | Full-text search with facets             |
| `suggestions(query)`              | Autocomplete suggestions                 |
| `author(id: ID!)`                 | Get an author                            |
| `authors(...)`                    | Paginated author list                    |
| `entity(id: ID!)`                 | Get a knowledge graph entity             |
| `entities(...)`                   | Paginated entity list with type filter   |
| `entityTypes`                     | List all entity types                    |
| `relationship(id)`                | Get a relationship between entities      |
| `relationshipsByEntity(entityId)` | Get all relationships for an entity      |
| `relationshipTypes`               | List all relationship types              |
| `knowledgeGraph(...)`             | Subgraph traversal with depth control    |

#### Mutations

| Mutation                         | Description                 |
| -------------------------------- | --------------------------- |
| `createContent(input)`           | Create a content item       |
| `updateContent(id, input)`       | Update a content item       |
| `deleteContent(id)`              | Delete a content item       |
| `publishContent(id)`             | Publish to public           |
| `archiveContent(id)`             | Archive content             |
| `restoreContentVersion(id, ver)` | Restore a previous version  |
| `bulkContentOperation(input)`    | Bulk publish/archive/delete |
| `createAuthor(input)`            | Create an author            |
| `updateAuthor(id, input)`        | Update an author            |
| `deleteAuthor(id)`               | Delete an author            |
| `createEntity(input)`            | Create a knowledge entity   |
| `updateEntity(id, input)`        | Update an entity            |
| `deleteEntity(id)`               | Delete an entity            |
| `createRelationship(input)`      | Create a relationship       |
| `updateRelationship(id, input)`  | Update a relationship       |
| `deleteRelationship(id)`         | Delete a relationship       |

#### Subscriptions

| Subscription             | Description                          |
| ------------------------ | ------------------------------------ |
| `contentUpdated(filter)` | Notified when content changes        |
| `contentCreated`         | Notified when new content is created |
| `contentPublished`       | Notified when content is published   |
| `entityUpdated(types)`   | Notified when entities change        |

#### Key Types

- **ContentType** enum: TEXT, DOCUMENT, MANUSCRIPT, COMMENTARY, TRANSLATION,
  ARTICLE, LECTURE, AUDIO, VIDEO
- **EntityType** enum: PERSON, PLACE, CONCEPT, EVENT, TEXT, TRADITION, SCHOOL,
  DEITY, SYMBOL
- **RelationshipType** enum: REFERENCES, CITES, RESPONDS_TO, INFLUENCES,
  INFLUENCED_BY, TEACHER_OF, STUDENT_OF, BELONGS_TO, LOCATED_IN,
  CONTEMPORARY_OF, ASSOCIATED_WITH
- **ContentStatus** enum: DRAFT, PENDING_REVIEW, APPROVED, PUBLISHED, ARCHIVED,
  RETRACTED

Pagination uses Relay-style connections with `edges`, `node`, `cursor`, and
`PageInfo`.

#### Example GraphQL Query

```graphql
query SearchContent($query: String!) {
  searchContent(query: $query, first: 10) {
    content {
      edges {
        node {
          id
          title
          type
          authors {
            name
            tradition
          }
          metadata {
            language
            era
            tags
          }
          status
        }
      }
      pageInfo {
        hasNextPage
        endCursor
      }
      totalCount
    }
    facets {
      traditions {
        value
        count
      }
      eras {
        value
        count
      }
    }
  }
}
```

#### Example Mutation

```graphql
mutation CreateContent($input: CreateContentInput!) {
  createContent(input: $input) {
    id
    title
    slug
    status
    version
    createdAt
  }
}
```

Variables:

```json
{
  "input": {
    "type": "COMMENTARY",
    "title": "On the Nature of Consciousness in the Upanishads",
    "authorIds": ["author_001"],
    "description": "A modern commentary on Mandukya Upanishad",
    "metadata": {
      "language": "en",
      "tradition": "Hindu",
      "era": "Modern",
      "tags": ["upanishads", "consciousness", "mandukya"]
    },
    "status": "DRAFT",
    "visibility": "AUTHENTICATED"
  }
}
```

---

## Middleware Stack

The BFF applies the following middleware in order:

1. **Security & Auth** -- JWT validation, permission levels, IP filtering, WAF,
   bot detection
2. **Experiment Headers** -- A/B test assignment via request headers
3. **Response Shaping** -- Per-client response optimization (mobile vs desktop)
4. **Compression** -- Adaptive response compression
5. **Request Hooks** -- Request counting, duration tracking, route-level metrics
6. **Geo-Sharding** -- Region-aware routing to closest service instance
7. **Error Normalization** -- Consistent error format across all upstream
   services

### Circuit Breaker

Every upstream service call passes through a circuit breaker. When a service
fails repeatedly, the circuit opens and subsequent requests receive mock
fallback responses instead of timing out. Circuit breaker state is observable
via the `/v1/circuit-breaker` endpoint.

### Mock Fallbacks

When a downstream service is unavailable, the BFF can return curated mock
responses for critical paths. Mock fallback domains include:

- Collaborative mythology
- Collective unconscious
- ComfyUI generation
- Consciousness research
- Digital immortality
- Divination & oracles
- Ego death exploration
- Noosphere networks
- Simulation probes
- Vision quest (Lakota, Plains traditions)

### Streaming & Backpressure

SSE streaming responses implement backpressure handling to prevent memory
exhaustion when clients consume data slowly. The streaming utilities provide:

- `initializeStreamingResponse` -- Set SSE headers and prepare the stream
- `writeSseEventWithBackpressure` -- Write events with flow control
- `streamItemsWithBackpressure` -- Stream collections with per-item events
- `endStreamingResponse` -- Clean up and close the stream

### Idempotency

Non-streaming chat responses are cached with a TTL of 5 minutes using an
in-memory idempotency cache keyed by request hash. This prevents duplicate
processing of identical requests.

---

## Additional Lilith Services (Non-BFF)

Beyond the BFF, the Lilith ecosystem includes many specialized services. Notable
examples:

| Service Area                                  | Description                                                    |
| --------------------------------------------- | -------------------------------------------------------------- |
| **CLI** (`apps/lilith/cli`)                   | Command-line interface for interacting with Lilith             |
| **Smart Contracts** (`apps/lilith/contracts`) | Ethereum/EVM contracts for NFTs, governance, royalties         |

The CLI provides commands for chat, content management, and service
administration from the terminal.
