Files
kamidso-back/kamidso/native_connectors/providers/didar/semantics.json
T
javadandCursor edbaa2acec Add native Didar connectors so chats can query CRM data reliably.
Connector calls, semantic rules, and DuckDB memory keep long runs stable, and stream retry stops chats from stalling.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-12 19:26:47 +03:30

112 lines
4.0 KiB
JSON

{
"schema_version": "1.0",
"provider": "didar",
"entity_semantics": {
"deal": {
"identity": {
"id": "Id",
"code": "Code",
"title": "Title"
},
"status": {
"field": "Status",
"enum_ref": "enums.authoritative.deal_status",
"authoritative": true,
"never_infer_from": [
"PipelineStageId",
"Probability",
"ChangeToWonTime",
"ChangeToLossTime",
"LabelIds"
]
},
"deletion": {
"field": "IsDeleted",
"separate_from_status": true
},
"dates": {
"created_at": "RegisterTime",
"won_at": "ChangeToWonTime",
"lost_at": "ChangeToLossTime",
"last_update_at": "LastUpdateTime",
"next_activity_at": "NextActivityDate",
"expected_close_at": "ExpectedCloseDate"
},
"money": {
"price": "Price",
"final_adjustment_price": "FinalAdjustmentPrice",
"estimated_price": "EstimatedPrice",
"currency_id": "CurrencyId",
"safe_default_amount_field": "FinalAdjustmentPrice",
"safe_default_is_provisional": true,
"reason": "Exact equivalence to Didar dashboard amount must be reconciled on a real account before declaring a permanent canonical amount."
},
"relations": {
"owner_id": "OwnerId",
"owner_object": "Owner",
"person_id": "PersonId",
"company_id": "CompanyId",
"pipeline_id": "PipelineId",
"pipeline_stage_id": "PipelineStageId",
"source_id": "SourceId",
"lost_reason_id": "LostReasonId"
}
},
"person": {
"identity": {
"id": "Id",
"display_name": "DisplayName"
},
"created_at": "RegisterTime",
"deleted": "IsDeleted",
"owner_id": "OwnerId",
"lead_fields": [
"LeadType",
"LeadStatus",
"LeadGenerationType",
"ContactType"
],
"lead_semantics_status": "not_fully_documented",
"rule": "Do not implement a provider-wide lead_count until reconciled against the Didar UI/account because public endpoint examples expose lead-related fields but do not define one authoritative counting rule."
},
"user": {
"resolver_function": "get_users",
"join_rule": "Deal.OwnerId should be resolved primarily against Response[].UserId. Keep fallback to Response[].Id only if a real-account contract test proves it is required.",
"display_field": "DisplayName"
},
"pipeline": {
"resolver_function": "get_deal_pipelines",
"pipeline_id_path": "Response[].Id",
"stage_id_path": "Response[].Stages[].Id",
"stage_title_path": "Response[].Stages[].Title"
}
},
"business_language": {
"فروش": "sales",
"فروش موفق": "sales",
"معاملات موفق": "won_deals",
"معاملات ناموفق": "lost_deals",
"معاملات جاری": "pending_pipeline_snapshot",
"معاملات ثبت شده": "deals_created",
"معاملات ایجاد شده": "deals_created"
},
"ambiguity_defaults": {
"معاملات <period>": {
"operation": "deals_created",
"date_basis": "created_at",
"response_disclosure": "Always state that the period basis is deal registration time."
},
"فروش <period>": {
"operation": "sales_summary",
"date_basis": "won_at",
"response_disclosure": "Always state that sales period is based on deal won time."
}
},
"accuracy_guards": [
"Never count statuses from only Response.List when Search Deals aggregate fields are available.",
"For current deal status, always trust Status over timestamps or stage/probability.",
"Never label a monetary amount as ریال/تومان/USD/etc. unless the currency mapping for the connection is known.",
"Never add raw amounts belonging to different CurrencyId values.",
"If a semantic report has not passed reconciliation for the current connector account, use safe-mode verification or clearly report that exact parity with Didar dashboard is not yet verified."
]
}