302 lines
8.1 KiB
Markdown
302 lines
8.1 KiB
Markdown
|
|
# Enrich Questions API Documentation
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
The `enrich-questions` endpoint is a reverse API that takes existing questions and assigns them to specific areas and members. This endpoint returns the exact same response structure as `generate_questions_from_sop_v3`. Each question is intelligently assigned to the most relevant area_tag and member using OpenAI analysis.
|
||
|
|
|
||
|
|
## Endpoint
|
||
|
|
|
||
|
|
```
|
||
|
|
POST /api/v1/common/enrich-questions
|
||
|
|
```
|
||
|
|
|
||
|
|
## Authentication
|
||
|
|
|
||
|
|
Requires Bearer token authentication:
|
||
|
|
|
||
|
|
```
|
||
|
|
Authorization: Bearer <your-api-key>
|
||
|
|
```
|
||
|
|
|
||
|
|
## Request Format
|
||
|
|
|
||
|
|
### Headers
|
||
|
|
|
||
|
|
```
|
||
|
|
Content-Type: application/json
|
||
|
|
Authorization: Bearer <your-api-key>
|
||
|
|
```
|
||
|
|
|
||
|
|
### Request Body
|
||
|
|
|
||
|
|
The request body should be a JSON array of question objects. Each question object must contain:
|
||
|
|
|
||
|
|
- `question` (string): The question text
|
||
|
|
- `role` (string): The role associated with the question
|
||
|
|
- `position_id` (integer): The position ID (used as role ID in response)
|
||
|
|
- `area_tags` (array): Array of area tag objects with `name` and `id` (OpenAI selects the most relevant one)
|
||
|
|
- `members` (array): Array of member objects with `id` (algorithm selects the most appropriate one)
|
||
|
|
|
||
|
|
### Example Request
|
||
|
|
|
||
|
|
```json
|
||
|
|
[
|
||
|
|
{
|
||
|
|
"question": "Is the system monitoring working properly?",
|
||
|
|
"role": "IT Expert",
|
||
|
|
"position_id": 522,
|
||
|
|
"area_tags": [
|
||
|
|
{
|
||
|
|
"name": "IT Operations",
|
||
|
|
"id": 1276
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "Communication & Coordination",
|
||
|
|
"id": 1426
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "Quality Assurance",
|
||
|
|
"id": 1427
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"members": [
|
||
|
|
{
|
||
|
|
"id": 159
|
||
|
|
}
|
||
|
|
]
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"question": "Are safety protocols being followed?",
|
||
|
|
"role": "IT Expert",
|
||
|
|
"position_id": 522,
|
||
|
|
"area_tags": [
|
||
|
|
{
|
||
|
|
"name": "IT Operations",
|
||
|
|
"id": 1276
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "Safety Protocols",
|
||
|
|
"id": 1436
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"members": [
|
||
|
|
{
|
||
|
|
"id": 159
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
]
|
||
|
|
```
|
||
|
|
|
||
|
|
## Response Format
|
||
|
|
|
||
|
|
### Success Response (200 OK)
|
||
|
|
|
||
|
|
The response structure is identical to `generate_questions_from_sop_v3`. Each question is assigned to ONE area_tag and ONE member:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"questions": {
|
||
|
|
"items": [
|
||
|
|
{
|
||
|
|
"area_tag": 1276,
|
||
|
|
"area_name": "IT Operations",
|
||
|
|
"assigned_to": 159,
|
||
|
|
"questions": "Is the system monitoring working properly?",
|
||
|
|
"role": 522
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"area_tag": 1436,
|
||
|
|
"area_name": "Safety Protocols",
|
||
|
|
"assigned_to": 159,
|
||
|
|
"questions": "Are safety protocols being followed?",
|
||
|
|
"role": 522
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Response Structure Explanation
|
||
|
|
|
||
|
|
- Each question creates exactly ONE item in the response
|
||
|
|
- OpenAI analyzes the question content and selects the most relevant `area_tag` from available options
|
||
|
|
- The algorithm selects the most appropriate `member` from the available members
|
||
|
|
- `area_tag`: The OpenAI-selected area tag ID
|
||
|
|
- `area_name`: The OpenAI-selected area tag name
|
||
|
|
- `assigned_to`: The selected member ID
|
||
|
|
- `questions`: The question text
|
||
|
|
- `role`: The position_id from the request (used as role identifier)
|
||
|
|
|
||
|
|
## AI-Powered Assignment Algorithm
|
||
|
|
|
||
|
|
### OpenAI Area Tag Selection
|
||
|
|
|
||
|
|
The system uses OpenAI's GPT-4o-mini model to intelligently analyze each question and select the most relevant area tag:
|
||
|
|
|
||
|
|
1. **Content Analysis**: OpenAI analyzes the question content, context, and meaning
|
||
|
|
2. **Domain Matching**: Determines which area/domain the question is actually testing or assessing
|
||
|
|
3. **Relevance Scoring**: Considers the purpose and intent of the question
|
||
|
|
4. **Smart Selection**: Chooses the most specific and primary area tag from available options
|
||
|
|
5. **Fallback**: If OpenAI analysis fails, defaults to the first available area tag
|
||
|
|
|
||
|
|
**OpenAI Prompt Guidelines:**
|
||
|
|
|
||
|
|
- Analyze question content and context
|
||
|
|
- Match questions to appropriate area tags based on meaning and purpose
|
||
|
|
- Consider what domain/area the question is actually testing
|
||
|
|
- Choose only ONE area tag per question - the most relevant one
|
||
|
|
- If multiple areas seem relevant, choose the most specific or primary one
|
||
|
|
|
||
|
|
### Member Selection
|
||
|
|
|
||
|
|
Currently uses a simple selection algorithm (first member), but can be enhanced to consider:
|
||
|
|
|
||
|
|
- Member skills and expertise
|
||
|
|
- Current workload distribution
|
||
|
|
- Availability and capacity
|
||
|
|
- Historical performance
|
||
|
|
|
||
|
|
### Error Responses
|
||
|
|
|
||
|
|
#### 400 Bad Request - Invalid Input Format
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"error": "Invalid input",
|
||
|
|
"message": "Input data must be in JSON format."
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
#### 400 Bad Request - Missing Required Fields
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"error": "Invalid data",
|
||
|
|
"message": "Question object at index 0 is missing required field 'question'."
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
#### 400 Bad Request - Invalid Array Structure
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"error": "Invalid input",
|
||
|
|
"message": "Input data must be an array of question objects."
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
#### 401 Unauthorized
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"error": "Unauthorized",
|
||
|
|
"message": "API key is missing or invalid."
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
#### 500 Internal Server Error
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"error": "Internal Server Error",
|
||
|
|
"message": "An unexpected error occurred."
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Usage Examples
|
||
|
|
|
||
|
|
### Basic Usage
|
||
|
|
|
||
|
|
```bash
|
||
|
|
curl -X POST "http://localhost:5402/api/v1/common/enrich-questions" \
|
||
|
|
-H "Authorization: Bearer your-api-key" \
|
||
|
|
-H "Content-Type: application/json" \
|
||
|
|
-d '[
|
||
|
|
{
|
||
|
|
"question": "Is the system performance being monitored?",
|
||
|
|
"role": "Developer",
|
||
|
|
"position_id": 123,
|
||
|
|
"area_tags": [
|
||
|
|
{"name": "Development", "id": 1},
|
||
|
|
{"name": "Performance Monitoring", "id": 2}
|
||
|
|
],
|
||
|
|
"members": [
|
||
|
|
{"id": 456}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
]'
|
||
|
|
```
|
||
|
|
|
||
|
|
### Python Example
|
||
|
|
|
||
|
|
```python
|
||
|
|
import requests
|
||
|
|
import json
|
||
|
|
|
||
|
|
url = "http://localhost:5402/api/v1/common/enrich-questions"
|
||
|
|
headers = {
|
||
|
|
"Authorization": "Bearer your-api-key",
|
||
|
|
"Content-Type": "application/json"
|
||
|
|
}
|
||
|
|
|
||
|
|
payload = [
|
||
|
|
{
|
||
|
|
"question": "Is the system performance being monitored?",
|
||
|
|
"role": "Developer",
|
||
|
|
"position_id": 123,
|
||
|
|
"area_tags": [
|
||
|
|
{"name": "Development", "id": 1},
|
||
|
|
{"name": "Performance Monitoring", "id": 2}
|
||
|
|
],
|
||
|
|
"members": [
|
||
|
|
{"id": 456}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
]
|
||
|
|
|
||
|
|
response = requests.post(url, json=payload, headers=headers)
|
||
|
|
result = response.json()
|
||
|
|
print(result)
|
||
|
|
```
|
||
|
|
|
||
|
|
## Validation Rules
|
||
|
|
|
||
|
|
1. **Input must be a JSON array** of question objects
|
||
|
|
2. **Each question object must contain all required fields**:
|
||
|
|
- `question`: Non-empty string
|
||
|
|
- `role`: Non-empty string
|
||
|
|
- `position_id`: Integer
|
||
|
|
- `area_tags`: Array of objects with `name` and `id`
|
||
|
|
- `members`: Array of objects with `id`
|
||
|
|
3. **Area tags must be valid objects** with both `name` (string) and `id` (integer/string)
|
||
|
|
4. **Members must be valid objects** with `id` (integer/string)
|
||
|
|
5. **Arrays can be empty** but must be present
|
||
|
|
|
||
|
|
## Response Logic
|
||
|
|
|
||
|
|
The endpoint uses AI to intelligently assign each question to the most relevant area and member:
|
||
|
|
|
||
|
|
- **Input**: 2 questions with multiple area_tags and members each
|
||
|
|
- **Output**: 2 items (one per question) with the best area_tag and member selected for each
|
||
|
|
- **AI Analysis**: OpenAI analyzes question content and meaning to find the most relevant area_tag
|
||
|
|
- **Smart Assignment**: Uses natural language understanding to make intelligent assignments
|
||
|
|
- **No Cartesian Product**: Each question gets exactly one area assignment and one member assignment
|
||
|
|
|
||
|
|
## Performance Considerations
|
||
|
|
|
||
|
|
- **Batch Processing**: OpenAI analysis is performed in batches for efficiency
|
||
|
|
- **Caching**: Consider implementing caching for frequently assigned questions
|
||
|
|
- **Fallback**: Robust fallback mechanisms ensure the endpoint always returns valid assignments
|
||
|
|
- **Error Handling**: Comprehensive error handling for OpenAI API failures
|
||
|
|
|
||
|
|
## Integration with Existing System
|
||
|
|
|
||
|
|
This endpoint complements the existing question generation APIs:
|
||
|
|
|
||
|
|
- `POST /api/v1/qs/generate_questions_from_sop` - Generates questions from SOPs
|
||
|
|
- `POST /api/v1/qs/generate_questions_from_sop-latest` - Enhanced question generation
|
||
|
|
- `POST /api/v1/common/enrich-questions` - Enriches existing questions (NEW)
|
||
|
|
|
||
|
|
The enrich-questions endpoint returns the **exact same structure** as `generate_questions_from_sop_v3`, with AI-powered intelligent assignment of questions to the most relevant areas and members, making it seamlessly interchangeable in your application workflow.
|