Skip to content

backend implementation on NPS Satisfaction Survey Automation and Door…#1311

Merged
yusuftomilola merged 1 commit into
DistinctCodes:mainfrom
feyishola:feat/survey-automation
Jun 29, 2026
Merged

backend implementation on NPS Satisfaction Survey Automation and Door…#1311
yusuftomilola merged 1 commit into
DistinctCodes:mainfrom
feyishola:feat/survey-automation

Conversation

@feyishola

Copy link
Copy Markdown
Contributor

… Access Hardware Integration (Kisi / Brivo)

closes #1232
closes #1230

What's Been Implemented

  1. NPS Satisfaction Survey Automation
    Goal: Automatically measure member satisfaction after completed bookings.

What was built:

NpsSurveyResponse entity — tracks both survey sends and member responses in one table (score/comment/submittedAt are null until the member responds; createdAt serves as the "sent at" timestamp for rate limiting)

Bull queue processor (nps-survey) — picks up delayed jobs and fires the survey email 2 hours after booking completion

NpsService:

scheduleIfEligible — checks the 30-day rate limit, deduplicates by booking, inserts the NpsSurveyResponse record, then enqueues the delayed job
respond — validates ownership, rejects duplicate submissions, writes score/comment/submittedAt
getSummary — computes promoters (9–10), passives (7–8), detractors (0–6), NPS score (P% − D%) × 100, average, and recent comments
getResponses — paginated admin view of submitted responses
3 REST endpoints:

POST /nps/respond — member submits score + comment
GET /nps/summary — admin aggregate stats
GET /nps/responses — admin paginated raw responses
Email template (nps-survey.hbs) + EmailService.sendNpsSurveyEmail()

CompleteBookingProvider modified — after status → COMPLETED, fires scheduleIfEligible non-blocking (skips guest bookings)

  1. Door Access Hardware Integration (Kisi / Brivo)
    Goal: Auto-grant door access on booking confirmation and revoke it on cancellation or completion.

What was built:

AccessIntegration entity — singleton config row storing the active provider (KISI or BRIVO), AES-256-CBC encrypted API key, enabled flag, and provider-specific doorGroupId in a JSONB meta column

AccessCredential entity — per-booking log of every grant/revoke event (externalCredentialId, provider, isActive, grantedAt, revokedAt)

KisiProvider — calls Kisi API v3: resolves user by email (or creates via invite), creates a group grant, stores the grant ID; deletes grant on revoke

BrivoProvider — calls Brivo API: finds user by email, assigns a credential template, stores credential ID; deletes credential on revoke

DoorAccessService:

configure — upsert integration config, encrypts API key before storing
getStatus — returns { configured, provider, isEnabled }
grantAccess — decrypts key, calls the right provider, saves AccessCredential
revokeAccess — finds the active credential by bookingId, calls provider revoke, marks isActive = false
getLogs — paginated credential event log
3 REST endpoints (admin-only):

POST /integrations/access/configure
GET /integrations/access/status
GET /integrations/access/logs
3 booking providers modified (all non-blocking):

ConfirmBookingProvider → grantAccess on CONFIRMED
CancelBookingProvider → revokeAccess on CANCELLED
CompleteBookingProvider → revokeAccess on COMPLETED (alongside NPS scheduling)
Shared patterns across both features
All side-effects (email sends, provider API calls) are fire-and-forget with .catch(() => void 0) — failures never break the core booking response
Both modules export their primary service and are imported into BookingsModule and AppModule
TypeORM synchronize: true means both entities auto-create their tables on next boot — no migration needed

@vercel

vercel Bot commented Jun 29, 2026

Copy link
Copy Markdown

@feyishola is attempting to deploy a commit to the naijabuz's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Jun 29, 2026

Copy link
Copy Markdown

@feyishola Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@yusuftomilola yusuftomilola merged commit fb37f45 into DistinctCodes:main Jun 29, 2026
4 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BE-44] Door access hardware integration (Kisi / Brivo API) [BE-43] NPS satisfaction survey automation: backend

2 participants