agmission/Development/server/docs/archived/API_SPECIFICATION.md

1184 lines
24 KiB
Markdown

# API Specification for Partner Integration
## Overview
This document defines the REST API endpoints for the multi-partner integration system, including enhanced job assignment, partner management, and data synchronization capabilities.
## Base URL
```
Production: https://api.agmission.com/v1
Staging: https://staging-api.agmission.com/v1
Development: http://localhost:3000/api
```
## Authentication
All API endpoints require authentication using Bearer tokens:
```http
Authorization: Bearer <jwt_token>
```
## Partner Management APIs
### List All Partners
```http
GET /api/partners
```
**Response:**
```json
{
"partners": [
{
"_id": "partner_id_1",
"code": "satloc",
"name": "Satloc",
"description": "Satloc partner account for managing SatLoc customer accounts",
"active": true,
"capabilities": [
"job_upload",
"data_download",
"real_time_sync"
],
"apiVersion": "v2.1",
"status": "online",
"lastHealthCheck": "2025-07-18T10:30:00Z",
"createdAt": "2025-01-15T08:00:00Z",
"updatedAt": "2025-07-18T10:30:00Z"
}
],
"total": 1
}
```
### Get Partner Details
```http
GET /api/partners/{id}
```
**Path Parameters:**
- `id` (string, required): The unique identifier of the partner
**Response:**
```json
{
"_id": "partner_id_1",
"code": "satloc",
"name": "Satloc",
"description": "Satloc integration for precision agriculture",
"active": true,
"capabilities": ["job_upload", "data_download", "real_time_sync"],
"apiConfig": {
"baseUrl": "https://api.satloc.com",
"version": "v2.1",
"rateLimit": {
"requestsPerSecond": 10,
"burstLimit": 50
}
},
"integrationSettings": {
"syncInterval": 60000,
"batchSize": 100,
"maxRetries": 3
},
"monitoring": {
"status": "online",
"lastHealthCheck": "2025-07-18T10:30:00Z",
"responseTime": 250,
"errorRate": 0.02
}
}
```
### Create Partner
```http
POST /api/partners
```
**Request Body:**
```json
{
"name": "New Partner",
"code": "NEWPARTNER",
"description": "Integration with new partner system",
"capabilities": ["job_upload", "data_download"],
"apiConfig": {
"baseUrl": "https://api.newpartner.com",
"version": "v1.0"
}
}
```
**Response:**
```json
{
"_id": "new_partner_id",
"name": "New Partner",
"code": "NEWPARTNER",
"description": "Integration with new partner system",
"active": true,
"capabilities": ["job_upload", "data_download"],
"createdAt": "2025-07-18T11:00:00Z",
"updatedAt": "2025-07-18T11:00:00Z"
}
```
### Update Partner
```http
PUT /api/partners/{id}
```
**Path Parameters:**
- `id` (string, required): The unique identifier of the partner
**Request Body (partial updates supported):**
```json
{
"name": "Updated Partner Name",
"description": "Updated partner description",
"capabilities": ["job_upload", "data_download", "real_time_sync"]
}
```
**Response:**
```json
{
"_id": "partner_id_1",
"name": "Updated Partner Name",
"code": "SATLOC",
"description": "Updated partner description",
"active": true,
"capabilities": ["job_upload", "data_download", "real_time_sync"],
"updatedAt": "2025-07-18T11:00:00Z"
}
```
### Delete Partner (Soft Delete)
```http
DELETE /api/partners/{id}
```
**Path Parameters:**
- `id` (string, required): The unique identifier of the partner
**Response:**
```json
{
"ok": true
}
```
**Note:** This endpoint performs a soft delete by setting `active: false`. The partner record remains in the database for audit purposes and existing relationships are preserved.
### Get Partner Status
```http
POST /api/partners/getPartnerStatus
```
**Request Body:**
```json
{
"partner": "partner_id_1"
}
```
**Response:**
```json
{
"partner": "satloc",
"status": "online",
"lastSync": "2025-07-18T10:30:00Z",
"activeJobs": 15,
"pendingSyncs": 2,
"metrics": {
"responseTime": {
"average": 250,
"p95": 500,
"p99": 1000
},
"errorRate": 0.02,
"successRate": 0.98,
"dataVolume": {
"uploaded": "1.2GB",
"downloaded": "850MB"
}
},
"recentErrors": [
{
"timestamp": "2025-07-18T09:45:00Z",
"operation": "data_poll",
"error": "Network timeout",
"retryAttempt": 2
}
]
}
```
## Partner System User Management APIs
### List All Partner System Users
```http
GET /api/partners/systemUsers
```
**Query Parameters:**
- `partner` (string, optional): Filter by partner ID
**Response:**
```json
[
{
"_id": "systemuser_id_1",
"username": "customer123_satloc",
"name": "Customer 123 SatLoc Integration",
"active": true,
"partner": {
"_id": "partner_id_1",
"name": "SatLoc",
"partnerCode": "SATLOC"
},
"customer": {
"_id": "customer_id_1",
"name": "John's Farm",
"username": "johnsfarm"
},
"companyId": "36c0f342-e4e2-4fcb-b219-9cd1fad2c1ff",
"apiKey": "satloc_api_key_encrypted",
"createdAt": "2025-01-15T08:00:00Z",
"updatedAt": "2025-07-18T10:30:00Z"
}
]
```
### Create Partner System User
```http
POST /api/partners/systemUsers
```
**Request Body:**
```json
{
"partnerId": "partner_id_1",
"customerId": "customer_id_1",
"username": "customer123_satloc",
"password": "secure_password",
"name": "Customer 123 SatLoc Integration",
"active": true,
"companyId": "36c0f342-e4e2-4fcb-b219-9cd1fad2c1ff",
"apiKey": "partner_api_key",
"apiSecret": "partner_api_secret",
"metadata": {
"integrationVersion": "v2.1",
"capabilities": ["job_upload", "data_sync"]
}
}
```
**Response:**
```json
{
"_id": "systemuser_id_1",
"username": "customer123_satloc",
"name": "Customer 123 SatLoc Integration",
"active": true,
"partner": "partner_id_1",
"customer": "customer_id_1",
"companyId": "36c0f342-e4e2-4fcb-b219-9cd1fad2c1ff",
"apiKey": "satloc_api_key_encrypted",
"createdAt": "2025-07-18T10:30:00Z",
"updatedAt": "2025-07-18T10:30:00Z"
}
```
### Get Partner System User by ID
```http
GET /api/partners/systemUsers/{id}
```
**Path Parameters:**
- `id` (string, required): The unique identifier of the partner system user
**Response:**
```json
{
"_id": "systemuser_id_1",
"username": "customer123_satloc",
"name": "Customer 123 SatLoc Integration",
"active": true,
"partner": {
"_id": "partner_id_1",
"name": "SatLoc",
"partnerCode": "SATLOC"
},
"customer": {
"_id": "customer_id_1",
"name": "John's Farm",
"username": "johnsfarm"
},
"companyId": "36c0f342-e4e2-4fcb-b219-9cd1fad2c1ff",
"apiKey": "satloc_api_key_encrypted",
"metadata": {
"integrationVersion": "v2.1",
"capabilities": ["job_upload", "data_sync"]
},
"createdAt": "2025-01-15T08:00:00Z",
"updatedAt": "2025-07-18T10:30:00Z"
}
```
### Update Partner System User
```http
PUT /api/partners/systemUsers/{id}
```
**Path Parameters:**
- `id` (string, required): The unique identifier of the partner system user
**Request Body (partial updates supported):**
```json
{
"name": "Updated Customer Integration Name",
"active": false,
"apiKey": "new_encrypted_api_key",
"metadata": {
"integrationVersion": "v2.2",
"capabilities": ["job_upload", "data_sync", "real_time_monitoring"]
}
}
```
**Response:**
```json
{
"_id": "systemuser_id_1",
"username": "customer123_satloc",
"name": "Updated Customer Integration Name",
"active": false,
"partner": "partner_id_1",
"customer": "customer_id_1",
"companyId": "36c0f342-e4e2-4fcb-b219-9cd1fad2c1ff",
"apiKey": "new_encrypted_api_key",
"metadata": {
"integrationVersion": "v2.2",
"capabilities": ["job_upload", "data_sync", "real_time_monitoring"]
},
"updatedAt": "2025-07-18T11:00:00Z"
}
```
### Delete Partner System User (Soft Delete)
```http
DELETE /api/partners/systemUsers/{id}
```
**Path Parameters:**
- `id` (string, required): The unique identifier of the partner system user
**Response:**
```json
{
"ok": true
}
```
**Note:** This endpoint performs a soft delete by setting `active: false`. The record remains in the database for audit purposes.
### Get Partner Customers
```http
GET /api/partners/customers
```
**Query Parameters:**
- `partnerId` (string, required): The unique identifier of the partner
**Description:** Retrieves all customers associated with a specific partner along with their subscription package information.
**Response:**
```json
[
{
"_id": "customer_id_1",
"name": "John Doe",
"email": "john@example.com",
"username": "johndoe",
"contact": "+1234567890",
"active": true,
"country": "US",
"createdAt": "2025-01-15T08:00:00Z",
"updatedAt": "2025-07-18T10:30:00Z",
"packageInfo": [
{
"packageName": "price_1Qs3w1JxyI1MWs2Te7a45wBX",
"status": "active",
"startDate": "2025-01-01T00:00:00.000Z",
"endDate": "2025-12-31T23:59:59.000Z",
"recurring": true
}
]
}
]
```
### Test Partner System User Authentication
```http
POST /api/partners/systemUsers/testAuth
```
**Description:** Tests authentication credentials for a partner system user by calling the partner's authentication API.
**Request Body:**
```json
{
"customerId": "customer_id_1",
"partnerId": "partner_id_1",
"username": "partner_username",
"password": "partner_password"
}
```
**Response:**
```json
{
"_id": "system_user_id",
"username": "partner_username",
"active": true,
"partner": {
"_id": "partner_id_1",
"name": "Satloc",
"partnerCode": "satloc"
},
"customer": {
"_id": "customer_id_1",
"name": "John Doe",
"username": "johndoe"
},
"companyId": "123",
"lastSyncAt": "2025-07-18T10:30:00Z",
"syncStatus": "success",
"authSuccess": true,
"partnerApiResponse": {
"authenticated": true,
"userId": "partner_user_123",
"companyId": "partner_company_123",
"sessionToken": "abc123...",
"expiresAt": "2025-07-18T14:30:00Z",
"userDetails": {
"userId": "partner_user_123",
"permissions": ["read", "write"]
}
}
}
```
**Error Response:**
```json
{
"_id": "system_user_id",
"username": "partner_username",
"active": true,
"partner": {
"_id": "partner_id_1",
"name": "Satloc",
"partnerCode": "satloc"
},
"customer": {
"_id": "customer_id_1",
"name": "John Doe",
"username": "johndoe"
},
"authSuccess": false,
"error": "Invalid credentials",
"partnerApiResponse": null
}
```
## Enhanced Job Assignment APIs
### Assign Job to Aircraft/Partners
```http
POST /jobs/{jobId}/assign
```
**Request Body:**
```json
{
"dlOp": {
"type": 1,
"mapOp": {
"width": 1024,
"height": 768,
"zoom": 15
}
},
"asUsers": [
{
"uid": "internal_user_id_1", // Always use internal user IDs
"partnerType": "internal"
},
{
"uid": "internal_user_id_2", // Internal user ID, not partner system user ID
"partnerType": "satloc",
"partnerConfig": {
"aircraftId": "AC001",
"priority": "high",
"syncImmediate": true,
"customFields": {
"flightAltitude": 100,
"sprayPattern": "overlap_20"
}
}
}
],
"avUsers": [
{
"uid": "internal_user_id_3", // Internal user ID
"partnerType": "dji"
}
]
}
```
**Response:**
```json
{
"ok": true,
"assignments": [
{
"assignmentId": "assign_123",
"userId": "user_id_1",
"partnerType": "internal",
"status": "assigned",
"syncStatus": "synced"
},
{
"assignmentId": "assign_124",
"userId": "user_id_2",
"partnerType": "satloc",
"externalJobId": "satloc_job_456",
"status": "assigned",
"syncStatus": "syncing",
"estimatedSyncTime": "2025-07-18T10:35:00Z"
}
],
"errors": [],
"summary": {
"totalAssignments": 2,
"successfulAssignments": 2,
"failedAssignments": 0,
"partnerAssignments": 1,
"internalAssignments": 1
}
}
```
### Get Job Assignments
```http
GET /jobs/{jobId}/assignments
```
**Response:**
```json
{
"jobId": 123,
"assignments": [
{
"assignmentId": "assign_123",
"user": {
"_id": "user_id_1",
"name": "Aircraft 001",
"username": "AC001"
},
"partnerType": "internal",
"status": 1,
"date": "2025-07-18T09:00:00Z",
"syncState": {
"jobUpload": {
"status": "synced",
"lastSuccess": "2025-07-18T09:00:00Z"
},
"dataPolling": {
"status": "idle"
}
}
},
{
"assignmentId": "assign_124",
"user": {
"_id": "user_id_2",
"name": "Satloc Aircraft 002",
"username": "SAT002"
},
"partnerType": "satloc",
"externalJobId": "satloc_job_456",
"status": 0,
"date": "2025-07-18T09:15:00Z",
"syncState": {
"jobUpload": {
"status": "synced",
"lastSuccess": "2025-07-18T09:16:00Z"
},
"dataPolling": {
"status": "polling",
"lastAttempt": "2025-07-18T10:30:00Z",
"nextPoll": "2025-07-18T10:31:00Z"
}
},
"metrics": {
"syncDuration": 1250,
"uploadTime": 800
}
}
],
"summary": {
"total": 2,
"pending": 1,
"downloaded": 0,
"completed": 1,
"byPartner": {
"internal": 1,
"satloc": 1
}
}
}
```
### Bulk Assign Jobs
```http
POST /jobs/bulk-assign
```
**Request Body:**
```json
{
"jobs": [
{
"jobId": 123,
"assignments": [
{
"uid": "user_id_1",
"partnerType": "satloc"
}
]
},
{
"jobId": 124,
"assignments": [
{
"uid": "user_id_2",
"partnerType": "dji"
}
]
}
],
"options": {
"syncImmediate": false,
"validateOnly": false
}
}
```
### Get Available and Assigned Aircraft for Job
```http
POST /jobs/assignments
```
**Description:** Retrieves available and assigned aircraft for a specific job, including aircraft details and assignment status.
**Request Body:**
```json
{
"jobId": 123
}
```
**Response:**
```json
{
"avUsers": [
{
"uid": "aircraft_id_1",
"name": "Sprayer 001",
"username": "SPR001",
"active": true,
"pkgActive": true,
"tailNumber": "N123AB"
},
{
"uid": "aircraft_id_2",
"name": "Helicopter 002",
"username": "HELI002",
"active": true,
"pkgActive": true,
"tailNumber": "N456CD"
}
],
"asUsers": [
{
"uid": "aircraft_id_3",
"name": "Drone 003",
"username": "DRN003",
"active": true,
"pkgActive": true,
"tailNumber": "N789EF",
"assignStatus": 1
}
]
}
```
**Field Descriptions:**
- `avUsers`: Array of available aircraft that can be assigned to the job
- `asUsers`: Array of aircraft already assigned to the job
- `tailNumber`: Aircraft tail number (always present, empty string if not set)
- `assignStatus`: Assignment status for assigned aircraft (0=NEW, 1=DOWNLOADED, 2=UPLOADED)
## Enhanced Job Download APIs
### Get Available Jobs (Enhanced)
```http
GET /export/newJobs
```
**Query Parameters:**
- `partnerType` (optional): Filter by partner type
- `includeMetadata` (optional): Include sync metadata in response
**Response:**
```json
{
"internal": [
{
"assignmentId": "assign_123",
"job": {
"_id": 123,
"name": "Field A Spraying",
"startDate": "2025-07-18T08:00:00Z",
"endDate": "2025-07-18T18:00:00Z"
},
"date": "2025-07-18T09:00:00Z"
}
],
"partners": {
"satloc": [
{
"assignmentId": "assign_124",
"job": {
"_id": 124,
"name": "Field B Application",
"startDate": "2025-07-18T10:00:00Z",
"endDate": "2025-07-18T16:00:00Z"
},
"date": "2025-07-18T09:15:00Z",
"externalJobId": "satloc_job_456",
"syncStatus": "synced",
"partnerMetadata": {
"aircraftId": "SAT002",
"priority": "high"
}
}
],
"dji": []
},
"summary": {
"totalAvailable": 2,
"internal": 1,
"partners": 1,
"lastSync": "2025-07-18T10:30:00Z"
}
}
```
### Download Job (Enhanced)
```http
POST /export/downloadJob
```
**Request Body:**
```json
{
"jobId": 124,
"partnerType": "satloc",
"options": {
"format": "native", // "native" or "converted"
"includeMetadata": true,
"compressionLevel": 6
}
}
```
**Response:**
- For internal jobs: Returns existing ZIP format
- For partner jobs: Returns partner-specific format or converted format
**Headers:**
```
Content-Type: application/zip
Content-Disposition: attachment; filename="job_124_satloc.zip"
X-Partner-Type: satloc
X-External-Job-Id: satloc_job_456
X-Data-Format: native
```
### Check Job Download Status
```http
GET /export/jobs/{jobId}/download-status?partnerType={partnerType}
```
**Response:**
```json
{
"jobId": 124,
"partnerType": "satloc",
"status": "ready", // "pending", "syncing", "ready", "failed"
"downloadUrl": "/export/downloadJob",
"syncMetadata": {
"lastSync": "2025-07-18T10:30:00Z",
"dataSize": 1048576,
"fileCount": 3,
"format": "satloc_v2"
},
"estimatedDownloadTime": 5000 // milliseconds
}
```
## Data Synchronization APIs
### Trigger Manual Sync
```http
POST /sync/assignments/{assignmentId}/sync
```
**Request Body:**
```json
{
"operation": "job_upload", // "job_upload" or "data_poll"
"priority": "high", // "low", "normal", "high"
"force": false // Force sync even if recently attempted
}
```
**Response:**
```json
{
"syncId": "sync_789",
"assignmentId": "assign_124",
"operation": "job_upload",
"status": "queued",
"estimatedCompletion": "2025-07-18T10:35:00Z",
"position": 3 // Position in queue
}
```
### Get Sync Status
```http
GET /sync/assignments/{assignmentId}/status
```
**Response:**
```json
{
"assignmentId": "assign_124",
"currentOperations": [
{
"operation": "data_poll",
"status": "running",
"startTime": "2025-07-18T10:30:00Z",
"progress": 75,
"metadata": {
"filesChecked": 3,
"filesFound": 1,
"dataSize": 524288
}
}
],
"lastSync": {
"operation": "job_upload",
"status": "completed",
"duration": 1250,
"completedAt": "2025-07-18T09:16:00Z"
},
"nextScheduled": {
"operation": "data_poll",
"scheduledTime": "2025-07-18T10:31:00Z"
},
"syncHistory": [
{
"operation": "job_upload",
"status": "completed",
"startTime": "2025-07-18T09:15:00Z",
"endTime": "2025-07-18T09:16:00Z",
"duration": 1250
}
]
}
```
### Bulk Sync Operations
```http
POST /sync/bulk-sync
```
**Request Body:**
```json
{
"operation": "data_poll",
"filters": {
"partnerType": "satloc",
"status": "pending",
"lastSyncBefore": "2025-07-18T08:00:00Z"
},
"options": {
"batchSize": 10,
"priority": "normal",
"maxConcurrent": 3
}
}
```
**Response:**
```json
{
"batchId": "batch_456",
"totalAssignments": 25,
"batches": 3,
"estimatedCompletion": "2025-07-18T11:00:00Z",
"status": "queued"
}
```
## Application Data APIs
### Get Application Data with Partner Info
```http
GET /applications/{applicationId}
```
**Response:**
```json
{
"_id": "app_789",
"jobId": 124,
"fileName": "satloc_flight_data_001.dat",
"fileSize": 1048576,
"status": 3,
"partnerType": "satloc",
"externalJobId": "satloc_job_456",
"assignmentId": "assign_124",
"originalData": {
"format": "satloc",
"version": "2.1",
"encoding": "binary",
"checksum": "sha256:abc123..."
},
"partnerMetadata": {
"aircraftInfo": {
"id": "SAT002",
"model": "Satloc G4",
"firmware": "v3.2.1"
},
"flightInfo": {
"startTime": "2025-07-18T10:00:00Z",
"endTime": "2025-07-18T12:30:00Z",
"duration": 9000,
"altitude": {"min": 95, "max": 105, "avg": 100}
},
"dataQuality": {
"gpsAccuracy": 0.5,
"signalStrength": 98,
"dataCompleteness": 99.2
}
},
"processingStage": "completed",
"processingSteps": [
{
"step": "upload",
"status": "completed",
"duration": 200
},
{
"step": "validate",
"status": "completed",
"duration": 150
},
{
"step": "convert",
"status": "completed",
"duration": 3000
}
],
"conversionMetrics": {
"recordsInput": 15000,
"recordsOutput": 14987,
"dataLossPercentage": 0.09,
"conversionTime": 3000
},
"qualityChecks": [
{
"checkType": "gps_continuity",
"status": "passed",
"score": 98
},
{
"checkType": "spray_coverage",
"status": "passed",
"score": 95
}
]
}
```
### Get Processing Status
```http
GET /applications/{applicationId}/processing-status
```
**Response:**
```json
{
"applicationId": "app_789",
"currentStage": "completed",
"progress": 100,
"totalSteps": 6,
"completedSteps": 6,
"currentStep": null,
"estimatedTimeRemaining": 0,
"processingStarted": "2025-07-18T10:35:00Z",
"processingCompleted": "2025-07-18T10:38:00Z",
"totalDuration": 180000,
"stepDetails": [
{
"step": "upload",
"status": "completed",
"progress": 100,
"duration": 200,
"startTime": "2025-07-18T10:35:00Z",
"endTime": "2025-07-18T10:35:00Z"
}
]
}
```
## Error Handling
All API endpoints follow consistent error response format:
```json
{
"error": {
"code": "PARTNER_SYNC_FAILED",
"message": "Failed to sync job with Satloc partner",
"details": {
"partnerId": "satloc",
"operation": "job_upload",
"cause": "Network timeout after 30s",
"retryable": true,
"nextRetry": "2025-07-18T10:40:00Z"
},
"requestId": "req_123456789",
"timestamp": "2025-07-18T10:30:00Z"
}
}
```
### Error Codes
| Code | Description | HTTP Status | Retryable |
|------|-------------|-------------|-----------|
| `PARTNER_NOT_FOUND` | Partner configuration not found | 404 | No |
| `PARTNER_UNAVAILABLE` | Partner API is temporarily unavailable | 503 | Yes |
| `PARTNER_SYNC_FAILED` | Failed to sync with partner | 500 | Yes |
| `INVALID_PARTNER_CONFIG` | Partner configuration is invalid | 400 | No |
| `RATE_LIMIT_EXCEEDED` | Partner rate limit exceeded | 429 | Yes |
| `AUTHENTICATION_FAILED` | Partner authentication failed | 401 | No |
| `DATA_FORMAT_ERROR` | Data format conversion failed | 422 | No |
| `ASSIGNMENT_NOT_FOUND` | Assignment not found | 404 | No |
| `SYNC_IN_PROGRESS` | Sync operation already in progress | 409 | No |
## Rate Limiting
API endpoints are rate limited based on the operation type:
- **Job Assignment**: 100 requests per minute
- **Data Download**: 50 requests per minute
- **Sync Operations**: 200 requests per minute
- **Status Queries**: 1000 requests per minute
Rate limit headers are included in all responses:
```
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1642608000
X-RateLimit-Retry-After: 60
```
## Webhooks
### Partner Status Notifications
Partners can register webhooks to receive notifications:
```http
POST /webhooks/partner-events
```
**Request Body:**
```json
{
"url": "https://partner.example.com/webhooks/agmission",
"events": ["job_assigned", "data_processed", "sync_failed"],
"secret": "webhook_secret_key"
}
```
### Webhook Payload Example
```json
{
"event": "job_assigned",
"timestamp": "2025-07-18T10:30:00Z",
"data": {
"assignmentId": "assign_124",
"jobId": 124,
"partnerType": "satloc",
"externalJobId": "satloc_job_456",
"userId": "user_id_2"
},
"signature": "sha256=webhook_signature"
}
```
This API specification provides comprehensive coverage of all partner integration functionality while maintaining backward compatibility with existing internal workflows.