Phase 4 Stage 10 backend: Chat-tab feeds (pending payments + cursor history)
Backend half of Stage 10 — the new Chat tab in the customer app that replaces /chat/history with a 3-sub-tab list (Aktif / Pembayaran / Selesai). - New GET /api/client/payment-sessions/pending — returns the customer's pending initial + extension payment sessions. Filter is status='pending' AND expires_at > NOW(). Mitra info comes from session_extensions → chat_sessions for extension rows, payment_sessions.targeted_mitra_id for targeted-curhat-lagi initial rows. TTL reuses the existing payment_session_timeout_minutes app_config row (default 20m) — no new config row needed since payment is still mocked. - getCustomerHistory migrated from offset (page/limit) to cursor pagination. Cursor is base64url(`<endedAtIso>|<id>`) with id-tiebreak in ORDER BY so rows with identical timestamps don't duplicate or skip across pages. SELECT now JOINs payment_sessions to surface `mode` (chat/call) for the Selesai-row voice-call pill. - requirement/flow_customer.mermaid.md: new §7 Chat Tab subgraph + Figma cross-ref entry for SChatList. - requirement/phase4-customer-flow-plan.md: Stage 10 plan section. Also carries forward earlier uncommitted "Post-Stage-8 corrections" notes from the Stage 9 sweep (boot path / SHome1st / onboarding fixes). Tests: +7 for getCustomerPendingPayments (initial null mitra, targeted-mitra fill, extension-via-session JOIN, mixed-newest-first, expired excluded, non-pending excluded, customer scoping). +10 for cursor history (empty, exact-fit, multi-page walk, same-timestamp tiebreak, limit clamp, customer scoping, CLOSING+COMPLETED only). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import {
|
||||
confirmPaymentSession,
|
||||
abandonPaymentSession,
|
||||
getPaymentSession,
|
||||
getCustomerPendingPayments,
|
||||
} from '../../services/payment.service.js'
|
||||
import {
|
||||
isCustomerEligibleForFirstSessionDiscount,
|
||||
@@ -172,6 +173,13 @@ export const clientPaymentRoutes = async (app) => {
|
||||
})
|
||||
})
|
||||
|
||||
// Phase 4 Stage 10 — Chat Tab Pembayaran feed. Static path; registered
|
||||
// before `/:id` so find-my-way matches this and not the wildcard.
|
||||
app.get('/pending', { preHandler: [authenticate, resolveCustomer] }, async (request, reply) => {
|
||||
const data = await getCustomerPendingPayments(request.customer.id)
|
||||
return reply.send({ success: true, data })
|
||||
})
|
||||
|
||||
app.get('/:id', { preHandler: [authenticate, resolveCustomer] }, async (request, reply) => {
|
||||
const session = await getPaymentSession(request.params.id)
|
||||
if (!session) {
|
||||
|
||||
Reference in New Issue
Block a user