Preuve · code, extrait

backend/ringover-call-events.go

Dépôt jeremy-flexylead/flexylead-crm · commit 730a5e79cbbb4191930f2de2f208f42ba483fb46 · livraison du 8 septembre 2026 à 13 h 51

Extrait tel qu'à ce commit : lignes 581–641, sur 4 441 (numérotation d'origine, 30 lignes de contexte autour de chaque citation) · fichier intégral sur GitHub (dépôt privé, accès requis)

Lignes citées par l'audit : 611

61 lignes reproduites · ← retour à l'audit · catalogue des preuves

581		routing.CentreID = destination
582	}
583	if groupID := stringField(decision, "destination_group_id"); groupID != "" {
584		routing.CommercialGroupID = groupID
585	}
586	routing.MatchSource = appendMatchReason(routing.MatchSource, "smart_routing_decision")
587	return routing, nil
588}
589
590func routingDeliveryConfirmed(payload ringoverPayload, commercialID string) bool {
591	// Ringover can mark the root IVR leg as answered even though no agent ever
592	// picked up. A routed delivery only exists when the provider event can be
593	// tied to the commercial that actually answered.
594	if strings.TrimSpace(commercialID) == "" {
595		return false
596	}
597	event := strings.ToLower(strings.TrimSpace(payload.Event))
598	if event == "answered" {
599		return true
600	}
601	if !isTerminalCallEvent(event) {
602		return false
603	}
604	if firstTime(payload.Data, "answered_at", "answer_time", "answered_date_time_atom") != "" {
605		return true
606	}
607	talk := firstNumber(payload.Data, "talk_duration", "talk_duration_seconds", "conversation_duration")
608	return talk != nil
609}
610
611func isUnattributedIVRAnswer(payload ringoverPayload, commercialID string) bool {
612	if strings.TrimSpace(commercialID) != "" || !truthy(payload.Data["is_ivr"]) {
613		return false
614	}
615	event := strings.ToLower(strings.TrimSpace(payload.Event))
616	if event == "answered" {
617		return true
618	}
619	return isTerminalCallEvent(event) && (firstTime(payload.Data, "answered_at", "answer_time", "answered_date_time_atom") != "" ||
620		firstNumber(payload.Data, "talk_duration", "talk_duration_seconds", "conversation_duration") != nil)
621}
622
623func confirmRoutingDecisionDelivery(ctx *Context, callID, centreID, commercialID, now string) error {
624	callID = strings.TrimSpace(callID)
625	centreID = strings.TrimSpace(centreID)
626	commercialID = strings.TrimSpace(commercialID)
627	if callID == "" || centreID == "" || commercialID == "" {
628		return nil
629	}
630	rows, err := search(ctx, "call_routing_decisions", []any{
631		map[string]any{"col": "provider_call_id", "op": "eq", "value": callID},
632		map[string]any{"col": "status", "op": "eq", "value": "routed"},
633	}, 5)
634	if err != nil {
635		return err
636	}
637	for _, decision := range rows.Rows {
638		if truthyField(decision, "repeated") {
639			continue
640		}
641		id := rowIDInt(decision)