87 lines
2.9 KiB
PHP
87 lines
2.9 KiB
PHP
<?php
|
|
/**
|
|
* WEVIA NPS Submit · Opus 20avr · Doctrine #4 compliance
|
|
* POST endpoint + internal function for WEVIA chat intent
|
|
*
|
|
* Usage:
|
|
* POST /api/wevia-nps-submit.php JSON {"respondent":"yacine","score":9,"comment":"..."}
|
|
* Returns: {"ok":true,"id":N,"nps_live":X}
|
|
*/
|
|
header('Content-Type: application/json');
|
|
header('Access-Control-Allow-Origin: *');
|
|
|
|
function wevia_nps_classify($score) {
|
|
if ($score >= 9) return 'promoter';
|
|
if ($score >= 7) return 'passive';
|
|
return 'detractor';
|
|
}
|
|
|
|
function wevia_nps_compute_live($db) {
|
|
$sql = "SELECT
|
|
COUNT(*) AS total,
|
|
COUNT(*) FILTER (WHERE score >= 9) AS promoters,
|
|
COUNT(*) FILTER (WHERE score BETWEEN 7 AND 8) AS passives,
|
|
COUNT(*) FILTER (WHERE score <= 6) AS detractors
|
|
FROM admin.nps_responses";
|
|
$row = $db->query($sql)->fetch(PDO::FETCH_ASSOC);
|
|
$total = (int)($row['total'] ?? 0);
|
|
if ($total === 0) return ['score' => null, 'total' => 0, 'status' => 'no_responses_yet'];
|
|
$pct_promoters = $row['promoters'] / $total * 100;
|
|
$pct_detractors = $row['detractors'] / $total * 100;
|
|
$nps = round($pct_promoters - $pct_detractors, 1);
|
|
return [
|
|
'score' => $nps,
|
|
'total' => $total,
|
|
'promoters' => (int)$row['promoters'],
|
|
'passives' => (int)$row['passives'],
|
|
'detractors' => (int)$row['detractors'],
|
|
'status' => 'live'
|
|
];
|
|
}
|
|
|
|
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
|
|
$raw = file_get_contents('php://input');
|
|
$in = json_decode($raw, true) ?: $_POST;
|
|
|
|
try {
|
|
$db = new PDO('pgsql:host=10.1.0.3;port=5432;dbname=adx_system;user=admin;password=admin123', null, null, [PDO::ATTR_TIMEOUT => 5, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
|
|
} catch (Throwable $e) {
|
|
echo json_encode(['ok' => false, 'error' => 'db: ' . $e->getMessage()]);
|
|
exit;
|
|
}
|
|
|
|
if ($method === 'GET') {
|
|
// Return live NPS state
|
|
echo json_encode(['ok' => true, 'live' => wevia_nps_compute_live($db)], JSON_PRETTY_PRINT);
|
|
exit;
|
|
}
|
|
|
|
// POST - submit new response
|
|
$respondent = trim((string)($in['respondent'] ?? 'anonymous'));
|
|
$score = isset($in['score']) ? (int)$in['score'] : -1;
|
|
$comment = trim((string)($in['comment'] ?? ''));
|
|
|
|
if ($score < 0 || $score > 10) {
|
|
echo json_encode(['ok' => false, 'error' => 'score must be 0-10']);
|
|
exit;
|
|
}
|
|
|
|
$category = wevia_nps_classify($score);
|
|
|
|
try {
|
|
$stmt = $db->prepare("INSERT INTO admin.nps_responses (respondent, score, comment, category) VALUES (?, ?, ?, ?) RETURNING id");
|
|
$stmt->execute([$respondent, $score, $comment, $category]);
|
|
$id = (int)$stmt->fetchColumn();
|
|
$live = wevia_nps_compute_live($db);
|
|
echo json_encode([
|
|
'ok' => true,
|
|
'id' => $id,
|
|
'respondent' => $respondent,
|
|
'score' => $score,
|
|
'category' => $category,
|
|
'nps_live' => $live
|
|
], JSON_PRETTY_PRINT);
|
|
} catch (Throwable $e) {
|
|
echo json_encode(['ok' => false, 'error' => $e->getMessage()]);
|
|
}
|