mirror of
https://github.com/azaion/detections.git
synced 2026-04-22 12:56:31 +00:00
[AZ-137] [AZ-138] Decompose test tasks and scaffold E2E test infrastructure
Made-with: Cursor
This commit is contained in:
@@ -69,10 +69,63 @@ Error mapping: RuntimeError("not available") → 503, RuntimeError → 422, Valu
|
||||
|
||||
### Annotations Service Integration
|
||||
|
||||
- POST to `{ANNOTATIONS_URL}/annotations` with:
|
||||
- `mediaId`, `source: 0`, `videoTime` (formatted from ms), `detections` (list of dto dicts)
|
||||
- Optional base64-encoded `image`
|
||||
- Bearer token in Authorization header
|
||||
Detections posts results to the Annotations service (`POST {ANNOTATIONS_URL}/annotations`) server-to-server during async media detection (F3). This only happens when an auth token is present in the original request.
|
||||
|
||||
**Endpoint:** `POST {ANNOTATIONS_URL}/annotations`
|
||||
|
||||
**Headers:**
|
||||
|
||||
| Header | Value |
|
||||
|--------|-------|
|
||||
| Authorization | `Bearer {accessToken}` (forwarded from the original client request) |
|
||||
| Content-Type | `application/json` |
|
||||
|
||||
**Request body — payload sent by Detections:**
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| mediaId | string | ID of the media being processed |
|
||||
| source | int | `0` (AnnotationSource.AI) |
|
||||
| videoTime | string | Video playback position formatted from ms as `"HH:MM:SS"` — mapped to `Annotations.Time` |
|
||||
| detections | list | Detection results for this batch (see below) |
|
||||
| image | string (base64) | Optional — base64-encoded frame image bytes |
|
||||
|
||||
`userId` is not included in the payload. The Annotations service resolves the user identity from the Bearer JWT.
|
||||
|
||||
**Detection object (as sent by Detections):**
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| centerX | float | X center, normalized 0.0–1.0 |
|
||||
| centerY | float | Y center, normalized 0.0–1.0 |
|
||||
| width | float | Width, normalized 0.0–1.0 |
|
||||
| height | float | Height, normalized 0.0–1.0 |
|
||||
| classNum | int | Detection class number |
|
||||
| label | string | Human-readable class name |
|
||||
| confidence | float | Model confidence 0.0–1.0 |
|
||||
|
||||
The Annotations API contract (`CreateAnnotationRequest`) also accepts `description` (string), `affiliation` (AffiliationEnum), and `combatReadiness` (CombatReadinessEnum) on each Detection, but the Detections service does not populate these — the Annotations service uses defaults.
|
||||
|
||||
**Responses from Annotations service:**
|
||||
|
||||
| Status | Condition |
|
||||
|--------|-----------|
|
||||
| 201 | Annotation created |
|
||||
| 400 | Neither image nor mediaId provided |
|
||||
| 404 | MediaId not found in Annotations DB |
|
||||
|
||||
**Failure handling:** POST failures are silently caught — detection processing continues regardless. Annotations that fail to post are not retried.
|
||||
|
||||
**Downstream pipeline (Annotations service side):**
|
||||
|
||||
1. Saves annotation to local PostgreSQL (image → XxHash64 ID, label file in YOLO format)
|
||||
2. Publishes SSE event to UI via `GET /annotations/events`
|
||||
3. Enqueues annotation ID to `annotations_queue_records` buffer table (unless SilentDetection mode is enabled in system settings)
|
||||
4. `FailsafeProducer` (BackgroundService) drains the buffer to RabbitMQ Stream (`azaion-annotations`) using MessagePack + Gzip
|
||||
|
||||
**Token refresh for long-running video:**
|
||||
|
||||
For video detection that may outlast the JWT lifetime, the `TokenManager` auto-refreshes via `POST {ANNOTATIONS_URL}/auth/refresh` when the token is within 60s of expiry. The refresh token is provided by the client in the `X-Refresh-Token` request header.
|
||||
|
||||
## Dependencies
|
||||
|
||||
|
||||
Reference in New Issue
Block a user