> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/AllianceBioversityCIAT/alliance-risk-analysis-tool/llms.txt
> Use this file to discover all available pages before exploring further.

# Risk Assessments

> Create and manage risk assessments with full CRUD operations, status tracking, and document management

## Overview

Assessments are the core entity in the CGIAR Risk Intelligence Tool. Each assessment represents a comprehensive risk evaluation for a specific company or partner organization. The platform supports multiple intake modes and tracks assessments through a complete lifecycle from draft to completion.

## Assessment Lifecycle

Assessments progress through four distinct statuses:

<Steps>
  <Step title="DRAFT">
    Initial state when an assessment is created. Users can configure basic details and choose an intake mode.
  </Step>

  <Step title="ANALYZING">
    Document parsing and AI analysis are in progress. Background jobs are running to extract information.
  </Step>

  <Step title="ACTION_REQUIRED">
    Gap detection has identified missing or incomplete data fields that need user review and correction.
  </Step>

  <Step title="COMPLETE">
    Risk analysis is finished. All 7 risk categories have been scored and the final report is available.
  </Step>
</Steps>

## Intake Modes

The platform supports three intake modes for gathering assessment data:

<CardGroup cols={3}>
  <Card title="Upload" icon="upload">
    Upload PDF documents (business plans, financial statements) for automated extraction using AWS Textract
  </Card>

  <Card title="Guided Interview" icon="comments">
    Step-by-step questionnaire that collects information through structured questions
  </Card>

  <Card title="Manual Entry" icon="keyboard">
    Direct data entry into structured forms organized by risk category
  </Card>
</CardGroup>

## Creating an Assessment

<CodeGroup>
  ```typescript POST /api/assessments theme={null}
  {
    "name": "Q1 2026 Partnership Assessment",
    "companyName": "Green Valley Agritech",
    "companyType": "Agricultural Cooperative",
    "country": "Kenya",
    "intakeMode": "UPLOAD"
  }
  ```

  ```typescript Response theme={null}
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Q1 2026 Partnership Assessment",
    "companyName": "Green Valley Agritech",
    "companyType": "Agricultural Cooperative",
    "country": "Kenya",
    "status": "DRAFT",
    "intakeMode": "UPLOAD",
    "progress": 0,
    "version": 1,
    "overallRiskScore": null,
    "overallRiskLevel": null,
    "userId": "user-123",
    "createdAt": "2026-03-04T10:30:00Z",
    "updatedAt": "2026-03-04T10:30:00Z"
  }
  ```
</CodeGroup>

### Required Fields

| Field         | Type   | Description                                          |
| ------------- | ------ | ---------------------------------------------------- |
| `name`        | string | Assessment name (max 200 chars)                      |
| `companyName` | string | Company being assessed (max 200 chars)               |
| `intakeMode`  | enum   | One of: `UPLOAD`, `GUIDED_INTERVIEW`, `MANUAL_ENTRY` |
| `companyType` | string | Optional. Type of organization (max 100 chars)       |
| `country`     | string | Optional. Defaults to "Kenya" (max 100 chars)        |

<Info>
  All assessments are user-scoped. Users can only access assessments they created.
</Info>

## Updating an Assessment

Assessments support optimistic locking to prevent concurrent modification conflicts:

<CodeGroup>
  ```typescript PUT /api/assessments/:id theme={null}
  {
    "name": "Q1 2026 Partnership Assessment - Updated",
    "status": "ANALYZING",
    "progress": 25,
    "version": 1  // Current version for conflict detection
  }
  ```

  ```typescript Success Response theme={null}
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Q1 2026 Partnership Assessment - Updated",
    "status": "ANALYZING",
    "progress": 25,
    "version": 2,  // Version incremented
    ...
  }
  ```

  ```typescript Conflict Response (409) theme={null}
  {
    "statusCode": 409,
    "message": "Assessment was modified by another user. Please refresh and try again.",
    "error": "Conflict"
  }
  ```
</CodeGroup>

### Updatable Fields

* `name` - Assessment name
* `companyName` - Company name
* `companyType` - Company type
* `status` - Assessment status (transitions managed by system in most cases)
* `progress` - Completion percentage (0-100, managed by system)
* `version` - Current version for optimistic locking

<Warning>
  The `version` field is critical for preventing data loss. Always include the current version when updating. The API will return a 409 Conflict if another user has modified the assessment.
</Warning>

## Document Upload

For assessments using the `UPLOAD` intake mode, documents are uploaded via presigned S3 URLs:

<Steps>
  <Step title="Request Upload URL">
    ```typescript POST /api/assessments/:id/documents theme={null}
    {
      "fileName": "business-plan.pdf",
      "mimeType": "application/pdf",
      "fileSize": 2048576
    }
    ```

    Response includes a presigned URL and document ID:

    ```typescript theme={null}
    {
      "presignedUrl": "https://s3.amazonaws.com/...",
      "documentId": "doc-550e8400"
    }
    ```
  </Step>

  <Step title="Upload to S3">
    Upload the file directly to the presigned URL using a PUT request:

    ```typescript theme={null}
    await fetch(presignedUrl, {
      method: 'PUT',
      headers: { 'Content-Type': 'application/pdf' },
      body: fileBuffer
    });
    ```
  </Step>

  <Step title="Trigger Parse">
    After upload completes, trigger document parsing:

    ```typescript POST /api/assessments/:id/documents/:documentId/parse theme={null}
    {
      "jobId": "job-550e8400"
    }
    ```

    This creates a background job and updates the assessment status to `ANALYZING`.
  </Step>
</Steps>

<Note>
  Only PDF files are supported. The maximum file size and MIME type validation is enforced at the API level.
</Note>

## Listing Assessments

Retrieve assessments with cursor-based pagination, filtering, and search:

<CodeGroup>
  ```typescript GET /api/assessments theme={null}
  GET /api/assessments?status=COMPLETE&limit=20
  GET /api/assessments?search=Green+Valley&cursor=next-cursor-token
  ```

  ```typescript Response theme={null}
  {
    "data": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "name": "Q1 2026 Partnership Assessment",
        "companyName": "Green Valley Agritech",
        "status": "COMPLETE",
        "progress": 100,
        "overallRiskScore": 42,
        "overallRiskLevel": "MODERATE",
        "createdAt": "2026-03-04T10:30:00Z",
        "updatedAt": "2026-03-04T14:30:00Z"
      }
    ],
    "nextCursor": "cursor-token-for-next-page",
    "total": 156
  }
  ```
</CodeGroup>

### Query Parameters

| Parameter | Type   | Description                                                    |
| --------- | ------ | -------------------------------------------------------------- |
| `status`  | enum   | Filter by: `DRAFT`, `ANALYZING`, `ACTION_REQUIRED`, `COMPLETE` |
| `search`  | string | Search in assessment name or company name (case-insensitive)   |
| `limit`   | number | Results per page (default: 10, max: 100)                       |
| `cursor`  | string | Pagination cursor from previous response                       |

## Assessment Statistics

Get aggregated counts by status:

<CodeGroup>
  ```typescript GET /api/assessments/stats theme={null}
  ```

  ```typescript Response theme={null}
  {
    "active": 12,      // ANALYZING status
    "drafts": 8,       // DRAFT status
    "completed": 156,  // COMPLETE status
    "total": 176       // All assessments
  }
  ```
</CodeGroup>

## Comments

Assessments support threaded comments for collaboration:

<CodeGroup>
  ```typescript POST /api/assessments/:id/comments theme={null}
  {
    "content": "Please review the financial risk category - the revenue figures need verification."
  }
  ```

  ```typescript GET /api/assessments/:id/comments theme={null}
  [
    {
      "id": "comment-123",
      "assessmentId": "550e8400-e29b-41d4-a716-446655440000",
      "userId": "user-123",
      "user": {
        "email": "analyst@cgiar.org"
      },
      "content": "Please review the financial risk category...",
      "createdAt": "2026-03-04T11:00:00Z"
    }
  ]
  ```
</CodeGroup>

## Deleting an Assessment

<Warning>
  Deletion is permanent and cascades to all related data (documents, gap fields, risk scores, recommendations, comments).
</Warning>

```typescript DELETE /api/assessments/:id theme={null}
// Response: 204 No Content
```

## Complete API Reference

<AccordionGroup>
  <Accordion title="POST /api/assessments - Create assessment">
    **Request Body:**

    ```typescript theme={null}
    {
      name: string;           // Max 200 chars
      companyName: string;    // Max 200 chars
      companyType?: string;   // Max 100 chars
      country?: string;       // Max 100 chars, default: "Kenya"
      intakeMode: 'UPLOAD' | 'GUIDED_INTERVIEW' | 'MANUAL_ENTRY';
    }
    ```

    **Response:** `Assessment` object with status `DRAFT`
  </Accordion>

  <Accordion title="GET /api/assessments - List assessments">
    **Query Parameters:**

    * `status?: AssessmentStatus`
    * `search?: string`
    * `limit?: number` (default: 10)
    * `cursor?: string`

    **Response:** Paginated list with `data`, `nextCursor`, `total`
  </Accordion>

  <Accordion title="GET /api/assessments/stats - Get statistics">
    **Response:**

    ```typescript theme={null}
    {
      active: number;      // Count with status ANALYZING
      drafts: number;      // Count with status DRAFT
      completed: number;   // Count with status COMPLETE
      total: number;       // Total count
    }
    ```
  </Accordion>

  <Accordion title="GET /api/assessments/:id - Get single assessment">
    **Response:** Complete `Assessment` object

    **Errors:**

    * 404 if assessment not found
    * 403 if user doesn't own the assessment
  </Accordion>

  <Accordion title="PUT /api/assessments/:id - Update assessment">
    **Request Body:** Partial update with optional `version` for optimistic locking

    **Response:** Updated `Assessment` object with incremented version

    **Errors:**

    * 409 if version conflict detected
  </Accordion>

  <Accordion title="DELETE /api/assessments/:id - Delete assessment">
    **Response:** 204 No Content

    **Note:** Cascades to all related entities
  </Accordion>
</AccordionGroup>

## Code Example: Complete Assessment Creation Flow

```typescript theme={null}
import { apiClient } from '@/lib/api-client';

// Step 1: Create assessment
const assessment = await apiClient.post('/api/assessments', {
  name: 'Q1 2026 Partnership Assessment',
  companyName: 'Green Valley Agritech',
  companyType: 'Agricultural Cooperative',
  country: 'Kenya',
  intakeMode: 'UPLOAD'
});

// Step 2: Request upload URL
const { presignedUrl, documentId } = await apiClient.post(
  `/api/assessments/${assessment.id}/documents`,
  {
    fileName: 'business-plan.pdf',
    mimeType: 'application/pdf',
    fileSize: file.size
  }
);

// Step 3: Upload file to S3
await fetch(presignedUrl, {
  method: 'PUT',
  headers: { 'Content-Type': 'application/pdf' },
  body: file
});

// Step 4: Trigger parsing
const { jobId } = await apiClient.post(
  `/api/assessments/${assessment.id}/documents/${documentId}/parse`
);

// Step 5: Poll job status
let job;
do {
  await new Promise(resolve => setTimeout(resolve, 3000));
  job = await apiClient.get(`/api/jobs/${jobId}`);
} while (job.status === 'PENDING' || job.status === 'PROCESSING');

if (job.status === 'COMPLETED') {
  console.log('Document parsed successfully!');
  // Assessment status is now ANALYZING or ACTION_REQUIRED
}
```

## Best Practices

<CardGroup cols={2}>
  <Card title="Always Use Version Control" icon="code-branch">
    Include the `version` field when updating assessments to prevent data loss from concurrent edits
  </Card>

  <Card title="Poll Job Status" icon="rotate">
    After triggering document parsing, poll the job status endpoint every 3-5 seconds until completion
  </Card>

  <Card title="Handle 403 Errors" icon="shield">
    Users can only access their own assessments. Always handle ownership errors gracefully
  </Card>

  <Card title="Validate File Types" icon="file-pdf">
    Only PDF files are supported for upload. Validate on the client before requesting presigned URLs
  </Card>
</CardGroup>

## Related Resources

<CardGroup cols={2}>
  <Card title="Risk Scoring" href="/features/risk-scoring" icon="chart-line">
    Learn how assessments are scored across 7 risk categories
  </Card>

  <Card title="AI Analysis" href="/features/ai-analysis" icon="brain">
    Understand the multi-agent AI pipeline that processes assessments
  </Card>

  <Card title="Report Generation" href="/features/report-generation" icon="file-pdf">
    Generate PDF reports with traffic-light risk indicators
  </Card>
</CardGroup>
