docs: add requirements tracker and Ozonetel CDR API reference

- requirements.md: full 16-user-story tracker with verified implementation
  status, code references, Ozonetel API findings, platform capability notes,
  and implementation guides for search (includeInSearch), barge/whisper, and
  appointment notifications
- ozonetel-cdr-api-reference.md: all 42 CDR fields, 3 endpoints (detailed,
  UCID, paginated), sidecar mapping status, known gotchas (nullable fields,
  field name inconsistency, rate limits)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-12 12:53:33 +05:30
parent f3e488348a
commit 85364c6d69
2 changed files with 1321 additions and 0 deletions

View File

@@ -0,0 +1,102 @@
# Ozonetel CDR API Reference
> Source: [Ozonetel docs](https://docs.ozonetel.com/reference/get_ca-reports-fetchcdrdetails)
## Endpoints
| Endpoint | Path | Use Case |
|----------|------|----------|
| Fetch CDR Detailed | `GET /ca_reports/fetchCDRDetails` | All CDR for a single day |
| Fetch CDR by UCID | `GET /ca_reports/fetchCdrByUCID` | Single call lookup by UCID |
| Fetch CDR Paginated | `GET /ca_reports/fetchCdrByPagination` | Paginated CDR with `totalCount` |
## Common Constraints
- **Auth**: Bearer token (via `POST /ca_apis/caToken/generateToken`)
- **Rate limit**: 2 requests per minute (all CDR endpoints)
- **Date range**: Single day only (`fromDate` and `toDate` must be same date)
- **Lookback**: 15 days maximum from time of request
- **Mandatory params**: `fromDate`, `toDate`, `userName` (+ `ucid` for UCID endpoint)
- **Date format**: `YYYY-MM-DD HH:MM:SS`
## Domain
- Domestic: `in1-ccaas-api.ozonetel.com`
- International: `api.ccaas.ozonetel.com`
## CDR Record Fields (42 fields)
| Field | Type | Description | Sidecar Status |
|-------|------|-------------|----------------|
| `AgentDialStatus` | string | Agent's dial attempt status (e.g., "answered") | Not mapped |
| `AgentID` | string | Agent identifier | **Mapped** — filter CDR by agent |
| `AgentName` | string | Agent name | **Mapped** — fallback filter |
| `CallAudio` | string | URL to call recording (S3) | Not mapped (recording via platform) |
| `CallDate` | string | Date of call (YYYY-MM-DD) | Not mapped |
| `CallID` | number | Unique call identifier | Not mapped |
| `CallerConfAudioFile` | string | Conference audio file | Not mapped |
| `CallerID` | string | Caller's phone number | Not mapped |
| `CampaignName` | string | Associated campaign name | Not mapped — **available for US-15** |
| `Comments` | string | Additional comments | Not mapped |
| `ConferenceDuration` | string | Conference duration (HH:MM:SS) | Not mapped |
| `CustomerDialStatus` | string | Customer dial status | Not mapped |
| `CustomerRingTime` | string | Customer phone ring time | Not mapped — **missed call analysis** |
| `DID` | string | Direct inward dial number | Not mapped — **available for US-2 branch display** |
| `DialOutName` | string | Dialed party name | Not mapped |
| `DialStatus` | string | Overall dial status | Not mapped |
| `DialedNumber` | string | Phone number dialed | Not mapped |
| `Disposition` | string | Call disposition/outcome | **Mapped** — disposition breakdown |
| `Duration` | string | Total call duration | Not mapped |
| `DynamicDID` | string | Dynamic DID reference | Not mapped |
| `E164` | string | E.164 formatted phone number | Not mapped |
| `EndTime` | string | Call end time | Not mapped |
| `Event` | string | Event type (e.g., "AgentDial") | Not mapped |
| `HandlingTime` | string/null | Total handling time — **CAN BE NULL** | Not mapped — **available for US-13 avg handling** |
| `HangupBy` | string | Who terminated call | Not mapped |
| `HoldDuration` | string | Time on hold | Not mapped — **available for US-12** |
| `Location` | string | Caller location | Not mapped |
| `PickupTime` | string | When call was answered | Not mapped |
| `Rating` | number | Call quality rating | Not mapped |
| `RatingComments` | string | Rating comments | Not mapped |
| `Skill` | string | Agent skill/queue name | Not mapped |
| `StartTime` | string | Call start time | Not mapped |
| `Status` | string | Call status (Answered/NotAnswered) | **Mapped** — inbound/missed split |
| `TalkTime` | string | Active talk duration | **Mapped** — avg talk time calc |
| `TimeToAnswer` | string | Duration until answer | Not mapped — **available for lead response KPI** |
| `TransferType` | string | Type of transfer | Not mapped — **available for US-3 audit** |
| `TransferredTo` / `TransferTo` | string | Transfer target — **field name varies by endpoint** | Not mapped |
| `Type` | string | Call type (InBound/Manual/Progressive) | **Mapped** — inbound/outbound split |
| `UCID` | number | Unique call identifier | Not mapped |
| `UUI` | string | User-to-user information | Not mapped |
| `WrapUpEndTime` | string/null | Wrapup completion time — **CAN BE NULL** | Not mapped |
| `WrapUpStartTime` | string/null | Wrapup start time — **CAN BE NULL** | Not mapped |
| `WrapupDuration` | string/null | Wrapup duration — **CAN BE NULL** | Not mapped — **available for US-12** |
## Pagination Endpoint Extra Fields
| Field | Description |
|-------|-------------|
| `totalCount` | Total number of records matching the query |
## Known Issues / Gotchas
1. **`HandlingTime`, `WrapupDuration`, `WrapUpStartTime`, `WrapUpEndTime` can be `null`** — when agent didn't complete wrapup (seen in UCID endpoint example). Code must null-guard these.
2. **Field name inconsistency**: `TransferredTo` in fetchCDRDetails vs `TransferTo` in pagination endpoint. Handle both.
3. **`WrapUpEndTime` vs `WrapupEndTime`**: casing differs between endpoints (camelCase vs mixed). Handle both.
4. **Single-day constraint**: `fromDate` and `toDate` must be the same date. For multi-day range, call once per day.
5. **Rate limit 2 req/min**: For a 7-day weekly report that needs CDR + summary per day = 14 API calls = 7 minutes minimum. Consider caching daily results.
## Current Sidecar Usage
**Endpoint used**: `fetchCDRDetails` only (in `ozonetel-agent.service.ts`)
**Fields actively mapped** (6 of 42):
- `AgentID` / `AgentName` — agent filtering
- `Type` — inbound/outbound split
- `Status` — answered/missed split
- `TalkTime` — avg talk time calculation
- `Disposition` — disposition breakdown chart
**Not yet used**:
- `fetchCdrByUCID` — useful for Patient 360 single-call drill-down
- `fetchCdrByPagination` — useful for high-volume days (current approach loads all records into memory)

1219
docs/requirements.md Normal file

File diff suppressed because it is too large Load Diff