# UI Handoff Document: `get_decrypted_chat_history` Function

## Overview
This document provides the UI team with the input/output specifications for the `get_decrypted_chat_history` function, which retrieves and decrypts all chat history for a given user.

---

## Function Details

### Function Name
`get_decrypted_chat_history`

### Purpose
Retrieves all encrypted chat messages for a user, decrypts them, and organizes them by conversation context with prompts and responses properly paired.

### Location
- **Rust Module**: `rag_module::RagModule`
- **Example Usage**: `examples/test_decrypt_function.rs`

---

## Input Specification

### Parameter

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `user_id` | `String` | Yes | The unique identifier for the user whose chat history should be retrieved |

### Example Input
```rust
let user_id = "cudewvsbxakj1n";
let decrypted_history = rag_module.get_decrypted_chat_history(user_id).await?;
```

---

## Output Specification

### Return Type
`Result<serde_json::Value>`

### Success Response Structure

```json
{
  "user_id": "string",
  "contexts": {
    "context_id_1": {
      "context_id": "string",
      "session_id": "string",
      "chat_title": "string | null",
      "conversations": [
        {
          "prompt": {
            "role": "user",
            "content": "string",
            "timestamp": "ISO8601 timestamp",
            "document_id": "uuid"
          },
          "response": {
            "role": "assistant",
            "content": "string",
            "timestamp": "ISO8601 timestamp",
            "document_id": "uuid"
          }
        }
      ]
    },
    "context_id_2": {
      // Same structure as context_id_1
    }
  }
}
```

### Field Descriptions

#### Top Level
- **`user_id`** (`string`): The user ID that was queried
- **`contexts`** (`object`): Map of context IDs to conversation data

#### Context Level
Each context represents a separate conversation or chat session:

- **`context_id`** (`string`): Unique identifier for this conversation thread
- **`session_id`** (`string`): Session identifier associated with this context
- **`chat_title`** (`string | null`): Human-readable title for the conversation. May be `null` for older conversations created before chat title support was added
- **`conversations`** (`array`): Array of prompt/response pairs

#### Conversation Pair
Each conversation pair contains:

- **`prompt`** (`object`): The user's message
  - **`role`** (`string`): Always `"user"`
  - **`content`** (`string`): The actual message text
  - **`timestamp`** (`string`): ISO8601 formatted timestamp (e.g., `"2025-11-03T05:54:37.207866Z"`)
  - **`document_id`** (`string`): Unique UUID for this message document

- **`response`** (`object`): The assistant's reply
  - **`role`** (`string`): Always `"assistant"`
  - **`content`** (`string`): The actual response text
  - **`timestamp`** (`string`): ISO8601 formatted timestamp
  - **`document_id`** (`string`): Unique UUID for this message document

---

## Example Output

### Example 1: Successful Retrieval with Multiple Conversations

```json
{
  "user_id": "cudewvsbxakj1n",
  "contexts": {
    "test2": {
      "context_id": "test2",
      "session_id": "session_123",
      "chat_title": "REST vs GraphQL Discussion",
      "conversations": [
        {
          "prompt": {
            "role": "user",
            "content": "What is the difference between REST and GraphQL APIs?",
            "timestamp": "2025-11-03T05:54:37.207866Z",
            "document_id": "5f71f8ed-5acf-41d0-ab27-b37c293b0af5"
          },
          "response": {
            "role": "assistant",
            "content": "Great question! Here are the key differences between REST and GraphQL:\n**REST (Representational State Transfer):**\n- Uses multiple endpoints (e.g., /users, /posts, /comments)\n- Fixed data structure per endpoint\n- Uses HTTP methods (GET, POST, PUT, DELETE)\n- Can lead to over-fetching or under-fetching data\n- Simpler caching\n**GraphQL:**\n- Single endpoint (/graphql)\n- Flexible queries - request exactly what you need\n- Strong type system with schema\n- Solves over-fetching problem\n- More complex caching\n- Real-time subscriptions built-in\n**When to use**:\n- REST: Simple APIs, caching important, team familiar with REST\n- GraphQL: Complex data relationships, mobile apps, need flexible queries",
            "timestamp": "2025-11-03T05:54:37.208889Z",
            "document_id": "3130e959-6e6d-4aaa-badf-fe15d20288af"
          }
        },
        {
          "prompt": {
            "role": "user",
            "content": "Can you give me a practical example of the over-fetching problem you mentioned?",
            "timestamp": "2025-11-03T05:54:37.209947Z",
            "document_id": "6dcdcca8-3407-482a-aedf-555703fd2843"
          },
          "response": {
            "role": "assistant",
            "content": "Perfect example of REST over-fetching!\n**Scenario**: Mobile app showing user profile\n**REST API Response** from /users/123:\n```json\n{\n  \"id\": 123,\n  \"name\": \"John Doe\",\n  \"email\": \"john@example.com\",\n  \"bio\": \"Long biography...\",\n  \"posts\": [...50 recent posts...],\n  \"followers\": [...200 followers...],\n  \"following\": [...150 following...],\n  \"preferences\": {...},\n  \"lastLogin\": \"2024-01-15\"\n}\n```\n**Problem**: Mobile app only needs name and email, but gets 50 posts + 200 followers + 150 following = huge payload!\n**GraphQL Solution**:\n```graphql\nquery {\n  user(id: 123) {\n    name\n    email\n  }\n}\n```\n**Result**: Only name and email returned - much faster on mobile!\nThis directly addresses the over-fetching issue I mentioned in my previous explanation about REST vs GraphQL.",
            "timestamp": "2025-11-03T05:54:37.210927Z",
            "document_id": "63dd0e79-06cd-48b4-aad1-2a7a9bd3a536"
          }
        }
      ]
    },
    "context_abc123": {
      "context_id": "context_abc123",
      "session_id": "session_456",
      "chat_title": "Python Programming Help",
      "conversations": [
        {
          "prompt": {
            "role": "user",
            "content": "How do I read a CSV file in Python?",
            "timestamp": "2025-11-02T10:30:00.000000Z",
            "document_id": "abc-123-def-456"
          },
          "response": {
            "role": "assistant",
            "content": "You can read a CSV file in Python using the pandas library or the built-in csv module...",
            "timestamp": "2025-11-02T10:30:05.000000Z",
            "document_id": "def-456-ghi-789"
          }
        }
      ]
    }
  }
}
```

### Example 2: User with No Chat History

```json
{
  "user_id": "new_user_123",
  "contexts": {}
}
```

### Example 3: Error Scenario

```json
{
  "user_id": "problematic_user",
  "contexts": {},
  "error": "Could not load documents: File not found"
}
```

---

## UI Implementation Guidelines

### 1. Display Multiple Conversations
- The response contains multiple conversation contexts
- Each context should be displayed as a separate chat thread
- Use `chat_title` (if available) as the conversation header
- Fall back to `context_id` if `chat_title` is `null`

### 2. Conversation Ordering
- Messages within each conversation are pre-sorted by timestamp
- Display conversations in the order they appear in the array
- Consider showing the most recent conversation first (reverse order of contexts)

### 3. Message Pairing
- Each conversation pair has a `prompt` and `response`
- Display them together as a Q&A unit
- Show prompts on the left/user side
- Show responses on the right/assistant side

### 4. Timestamp Handling
- Timestamps are in ISO8601 format with UTC timezone
- Convert to user's local timezone for display
- Consider relative time (e.g., "2 hours ago") for recent messages
- Use full date/time for older messages

### 5. Empty State
- If `contexts` is empty, show "No chat history" message
- If there's an `error` field, display it to the user

### 6. Chat Title Display
- Show `chat_title` prominently at the top of each conversation
- Handle `null` values gracefully (e.g., show "Untitled Conversation" or use the first user message as title)

---

## Sample UI Component Structure

```typescript
interface ConversationPair {
  prompt: {
    role: "user";
    content: string;
    timestamp: string;
    document_id: string;
  };
  response: {
    role: "assistant";
    content: string;
    timestamp: string;
    document_id: string;
  };
}

interface Context {
  context_id: string;
  session_id: string;
  chat_title: string | null;
  conversations: ConversationPair[];
}

interface ChatHistoryResponse {
  user_id: string;
  contexts: Record<string, Context>;
  error?: string;
}
```

---

## Testing

### Test Command
```bash
cargo run --example test_decrypt_function
```

### Expected Behavior
1. Initializes RAG module
2. Calls `get_decrypted_chat_history` with user ID
3. Prints formatted JSON output
4. All content is decrypted and readable

---

## Security Notes

1. **Encryption**: All chat data is stored encrypted using AES-256-GCM
2. **Keys**: Encryption keys are stored in macOS Keychain
3. **Decryption**: Happens automatically on retrieval
4. **User Isolation**: Each user's data is stored separately and can only be accessed with their user ID

---

## API Endpoint Recommendation

When exposing this to the frontend, create an endpoint like:

```
GET /api/chat/history/:user_id
```

**Response:**
```json
{
  "user_id": "cudewvsbxakj1n",
  "contexts": { ... }
}
```

---

## Contact

For questions or clarifications about this API:
- **Backend Team**: Refer to `src/lib.rs:1485` for implementation details
- **Example Code**: `examples/test_decrypt_function.rs`
- **Additional Example**: `examples/view_encrypted_chat_data.rs` (shows both encrypted and decrypted formats)

---

## Changelog

| Date | Version | Changes |
|------|---------|---------|
| 2025-11-03 | 1.0 | Initial handoff document created with chat_title support |
