Add webhook prod check script and update handoff

This commit is contained in:
2026-05-23 09:37:32 +07:00
parent 77cc676f40
commit 6d3c2efe5a
4 changed files with 82 additions and 8 deletions

View File

@ -1,4 +1,4 @@
import { Body, Controller, Get, Param, Patch, Post, Req, UseGuards } from '@nestjs/common'; import { Body, Controller, Get, Inject, Param, Patch, Post, Req, UseGuards } from '@nestjs/common';
import type { Request } from 'express'; import type { Request } from 'express';
import { AuthService } from './auth.service'; import { AuthService } from './auth.service';
import { LoginDto } from './dto/login.dto'; import { LoginDto } from './dto/login.dto';
@ -15,11 +15,7 @@ import { ChangePasswordDto } from './dto/change-password.dto';
@Controller('auth') @Controller('auth')
export class AuthController { export class AuthController {
private readonly authService: AuthService; constructor(@Inject(AuthService) private readonly authService: AuthService) {}
constructor(authService: AuthService) {
this.authService = authService;
}
@Post('login') @Post('login')
signIn(@Req() request: Request, @Body() body: LoginDto) { signIn(@Req() request: Request, @Body() body: LoginDto) {

View File

@ -2,6 +2,22 @@
Snapshot tanggal: `2026-05-22` Snapshot tanggal: `2026-05-22`
Perubahan terbaru (sesi ini, 23 Mei 2026):
- Menambahkan script pemeriksaan webhook production: `scripts/check-webhook-prod.sh`
- Otomatis cek `webhook_events`, `jobs` queue `webhooks`, summary status, korelasi inbound vs `conversation_messages`, dan sample `contacts`.
- Script otomatis handle koneksi via `psql` lokal atau fallback ke container Docker PostgreSQL.
- Menyetel key React pada activity list di `frontend/src/components/conversations-inbox.tsx` agar tidak duplicate:
- dari `key={item.title}-{item.meta}`
- menjadi `key={item.title}-{item.meta}-{index}`.
- Perbaikan kecil controller DI pada `backend/src/auth/auth.controller.ts`:
- constructor injection diringkas via parameter property + `@Inject(AuthService)` agar konsisten style.
Catatan diagnosa dari output terakhir:
- Webhook `POST /api/webhooks/whatsapp` sudah masuk ke DB dan diproses (`processing_status=processed`, `jobs` `webhooks` berstatus `processed`, tidak ada `queued/failed`).
- Event `message.inbound` juga sudah terhubung ke `conversation_messages` dan memiliki contact, sehingga data percakapan sudah tersimpan.
- Jika UI belum nampak, kemungkinan di sisi fetch/render dashboard perlu refresh/target contact yang sesuai, bukan di jalur webhook.
Dokumen ini adalah ringkasan kondisi terakhir BizOne Portal supaya sesi Codex berikutnya bisa lanjut tanpa bongkar ulang dari nol. Dokumen ini adalah ringkasan kondisi terakhir BizOne Portal supaya sesi Codex berikutnya bisa lanjut tanpa bongkar ulang dari nol.
## Ringkasan Cepat ## Ringkasan Cepat

View File

@ -533,8 +533,8 @@ export function ConversationsInbox({
<section className="conversations-profile-section"> <section className="conversations-profile-section">
<h4>{labels.recentActivity}</h4> <h4>{labels.recentActivity}</h4>
<div className="conversations-activity-list"> <div className="conversations-activity-list">
{activeConversation?.activity.map((item) => ( {activeConversation?.activity.map((item, index) => (
<article key={`${item.title}-${item.meta}`} className="conversations-activity-item"> <article key={`${item.title}-${item.meta}-${index}`} className="conversations-activity-item">
<i className={item.tone === 'primary' ? 'is-primary' : 'is-muted'} /> <i className={item.tone === 'primary' ? 'is-primary' : 'is-muted'} />
<div> <div>
<strong>{item.title}</strong> <strong>{item.title}</strong>

62
scripts/check-webhook-prod.sh Executable file
View File

@ -0,0 +1,62 @@
#!/usr/bin/env bash
set -euo pipefail
DB_URL=${DB_URL:-"postgresql://bizone:%2BQ%26xN%2486LbSA%3Cav%3C@127.0.0.1:5432/wa_dashboard"}
run_psql() {
psql "$DB_URL" -c "$1"
}
run_with_docker() {
local container="$1"
docker exec -i "$container" psql "$DB_URL" -c "$2"
}
if command -v psql >/dev/null 2>&1; then
echo "=== WEBHOOK EVENTS (DB) ==="
run_psql "SELECT event_id,event_type,processing_status,verified,created_at,sender_phone,recipient_phone FROM webhook_events ORDER BY created_at DESC LIMIT 20;"
echo "=== WEBHOOK JOBS ==="
run_psql "SELECT id,queue_name,job_type,status,attempts,max_attempts,error_message,created_at FROM jobs WHERE queue_name='webhooks' ORDER BY created_at DESC LIMIT 20;"
echo "=== WEBHOOK SUMMARY ==="
run_psql "SELECT COUNT(*) FILTER (WHERE event_type='message.inbound') AS inbound_count, COUNT(*) FILTER (WHERE processing_status='received') AS received_count, COUNT(*) FILTER (WHERE processing_status='queued') AS queued_count, COUNT(*) FILTER (WHERE processing_status='processed') AS processed_count, COUNT(*) FILTER (WHERE processing_status='failed') AS failed_count FROM webhook_events;"
echo "=== INBOUND EVENTS VS CONVERSATION MESSAGES ==="
run_psql "SELECT w.event_id, w.sender_phone, w.recipient_phone, w.created_at AS event_at, w.processing_status, w.verified, c.id AS contact_id, c.phone_number, cm.id AS conversation_message_id, cm.direction, cm.body, cm.occurred_at AS message_at FROM webhook_events w LEFT JOIN conversation_messages cm ON cm.webhook_event_id = w.event_id LEFT JOIN contacts c ON c.id = cm.contact_id WHERE w.event_type = 'message.inbound' ORDER BY w.created_at DESC LIMIT 20;"
echo "=== CONTACTS TO CHECK (for manual validation) ==="
run_psql "SELECT id, phone_number, name, created_at, updated_at FROM contacts ORDER BY updated_at DESC LIMIT 20;"
elif command -v docker >/dev/null 2>&1; then
CONTAINER=$(docker ps --filter "ancestor=postgres" --format '{{.Names}}' | head -n 1)
if [ -z "${CONTAINER}" ]; then
CONTAINER=$(docker ps --filter "name=postgres" --format '{{.Names}}' | head -n 1)
fi
if [ -z "${CONTAINER}" ]; then
echo "Container postgres tidak ketemu via docker ps."
echo "Isi container yang ada:"
docker ps --format '{{.Names}}\t{{.Image}}'
exit 1
fi
echo "Menggunakan container: ${CONTAINER}"
echo "=== WEBHOOK EVENTS (DB via container) ==="
run_with_docker "$CONTAINER" "SELECT event_id,event_type,processing_status,verified,created_at,sender_phone,recipient_phone FROM webhook_events ORDER BY created_at DESC LIMIT 20;"
echo "=== WEBHOOK JOBS (DB via container) ==="
run_with_docker "$CONTAINER" "SELECT id,queue_name,job_type,status,attempts,max_attempts,error_message,created_at FROM jobs WHERE queue_name='webhooks' ORDER BY created_at DESC LIMIT 20;"
echo "=== WEBHOOK SUMMARY (DB via container) ==="
run_with_docker "$CONTAINER" "SELECT COUNT(*) FILTER (WHERE event_type='message.inbound') AS inbound_count, COUNT(*) FILTER (WHERE processing_status='received') AS received_count, COUNT(*) FILTER (WHERE processing_status='queued') AS queued_count, COUNT(*) FILTER (WHERE processing_status='processed') AS processed_count, COUNT(*) FILTER (WHERE processing_status='failed') AS failed_count FROM webhook_events;"
echo "=== INBOUND EVENTS VS CONVERSATION MESSAGES (via container) ==="
run_with_docker "$CONTAINER" "SELECT w.event_id, w.sender_phone, w.recipient_phone, w.created_at AS event_at, w.processing_status, w.verified, c.id AS contact_id, c.phone_number, cm.id AS conversation_message_id, cm.direction, cm.body, cm.occurred_at AS message_at FROM webhook_events w LEFT JOIN conversation_messages cm ON cm.webhook_event_id = w.event_id LEFT JOIN contacts c ON c.id = cm.contact_id WHERE w.event_type = 'message.inbound' ORDER BY w.created_at DESC LIMIT 20;"
echo "=== CONTACTS TO CHECK (via container) ==="
run_with_docker "$CONTAINER" "SELECT id, phone_number, name, created_at, updated_at FROM contacts ORDER BY updated_at DESC LIMIT 20;"
else
echo "Tidak ada psql dan docker CLI di server ini."
exit 1
fi