Skip to content

Add scoreDecayService tests, webhook docs, action_url migration, fix …#1031

Open
ExcelDsigN-tech wants to merge 3 commits into
LabsCrypt:mainfrom
ExcelDsigN-tech:feat/tests-webhooks-notifications
Open

Add scoreDecayService tests, webhook docs, action_url migration, fix …#1031
ExcelDsigN-tech wants to merge 3 commits into
LabsCrypt:mainfrom
ExcelDsigN-tech:feat/tests-webhooks-notifications

Conversation

@ExcelDsigN-tech
Copy link
Copy Markdown

fix/feat: Score Decay Tests, Notification Deep-Links, Webhook Guide, and README Clone URL Fix | Closes #955, Closes #957, Closes #959, Closes #1023

Overview

This PR addresses two backend gaps and two documentation issues. The scoreDecayService, which
handles financially sensitive credit score mutations for inactive borrowers, gains a dedicated
test suite covering the core decay logic that was previously untested. The notifications system
gains an action_url column and supporting schema changes so that every notification type can
carry a deep-link to its relevant entity, unblocking the inbox feature in #892. On the
documentation side, a webhook integration guide is added to give external subscribers a single
authoritative reference for consuming the RemitLend webhook system. A stale placeholder clone
URL in the README Quick Start is corrected to point at the real repository.

Feature Summary

  • Unit test suite added for scoreDecayService covering inactive user decay, active user
    no-decay, score floor enforcement, idempotency, and batch processing
  • Nullable action_url column added to the notifications table via a new migration
  • action_url populated at notification creation for loan, dispute, and remittance event types
  • action_url included in the GET /notifications response and notification schema
  • New docs/webhooks.md covering subscription management, supported event types, example
    payloads, HMAC-SHA256 signature verification, delivery semantics, and circuit-breaker behavior
  • Webhook guide linked from README.md
  • Placeholder clone URL in README Quick Start replaced with the correct LabsCrypt repository URL

Technical Implementation

Score Decay Service Tests (#955):

  • New file backend/src/services/tests/scoreDecayService.test.ts added following the
    mock pattern established by existing service tests
  • DB and contract layers are mocked at the module boundary; no real persistence or contract
    calls are made in any test case
  • Test cases cover: a user whose last activity timestamp exceeds the configured inactivity
    threshold decays by exactly the configured decay amount; a user whose last activity is within
    the threshold receives no score change; a user whose computed post-decay score falls below
    the configured minimum is floored at that minimum rather than going below it; running the
    decay job twice within the same inactivity window does not apply a second decay to the same
    user (idempotency); and a batch of mixed active and inactive users produces mutations only
    for the inactive subset with correct amounts

Notification Deep-Links (#959):

  • New migration in backend/migrations/ adds a nullable VARCHAR action_url column to the
    notifications table with no backfill; existing rows return null for the field
  • notificationService.ts is updated at each notification creation site (loan approved, loan
    repaid, loan defaulted, dispute opened, remittance completed) to construct and pass the
    appropriate action_url using the entity ID available at that call site
  • notificationSchemas.ts updated to include action_url as an optional nullable string field
    in both the response schema and any shared notification type definitions
  • notificationController.ts GET /notifications handler already serializes via the schema,
    so no controller logic changes are required beyond confirming the field passes through

Webhook Integration Guide (#957):

  • New file docs/webhooks.md structured as follows: subscription CRUD (create, update, delete,
    list) with example request and response shapes; full table of supported event types with
    the object and trigger condition for each; example JSON payload per event type; delivery
    and retry semantics documenting the backoff schedule and maximum attempt count; circuit
    breaker behavior documenting the threshold at which deliveries are suspended and how they
    resume; HMAC-SHA256 signature verification section documenting the X-RemitLend-Signature
    header format and including a verification code snippet in Node.js, with a cross-reference
    to [Backend] Sign outgoing webhook deliveries with HMAC-SHA256 X-RemitLend-Signature header #880 for the signing implementation; and expected HTTP response codes from the subscriber
    endpoint with notes on what triggers a retry
  • README.md updated to include a link to docs/webhooks.md in the relevant integrations or
    documentation section

README Clone URL Fix (#1023):

  • Line 60 of README.md updated, replacing the your-username/remitlend placeholder with
    LabsCrypt/remitlend in the git clone command so the Quick Start works on first copy-paste

Test Coverage

  • scoreDecayService.test.ts covers inactive-user decay with correct delta, active-user no-op,
    score floor at minimum boundary, idempotency across two runs in the same window, and batch
    processing with a mixed user set asserting per-user mutation correctness
  • All mocks are consistent with the patterns used in existing service test files; no real DB
    or contract calls are made
  • notificationService test extended to assert that action_url is correctly set on at least one
    notification type (loan approved used as the representative case)
  • Existing scoreDecayJob test in cron/tests/scoreDecayJob.test.ts is unmodified and
    continues to pass
  • CI runs the full test suite on push; no existing tests are affected by the migration given
    the column is nullable with no default constraint

Checklists

  • scoreDecayService.test.ts created following existing service test mock conventions
  • Inactive user past threshold decays by configured amount
  • Active user within threshold receives no score change
  • Post-decay score floored at configured minimum and not reduced below it
  • Idempotency confirmed: two runs in the same window do not double-decay the same user
  • Batch processing test covers mixed active and inactive users with correct per-user results
  • Migration adds nullable action_url column to notifications table
  • action_url populated at creation for loan, dispute, and remittance notification types
  • action_url included in notificationSchemas.ts response and type definitions
  • GET /notifications response includes action_url field; older rows return null
  • notificationService test asserts action_url is set for at least one notification type
  • docs/webhooks.md created covering subscription CRUD, event types, example payloads,
    delivery and retry semantics, circuit-breaker behavior, and HMAC verification
  • HMAC-SHA256 signature header documented with verification code snippet and link to [Backend] Sign outgoing webhook deliveries with HMAC-SHA256 X-RemitLend-Signature header #880
  • Expected subscriber response codes and retry trigger conditions documented
  • docs/webhooks.md linked from README.md
  • README.md Quick Start clone URL updated from your-username to LabsCrypt
  • All existing tests pass in CI with no regressions

ExcelDsigN-tech added 2 commits May 28, 2026 16:59
…README clone URL

- scoreDecayService tests: inactivity decay, floor, idempotency
- Webhook integration guide with event types, payloads, HMAC, retry
- Migration adding action_url to notifications + service/controller wiring
- Fix placeholder clone URL to LabsCrypt/remitlend
Replace top-level static imports with lazy dynamic imports so jest ESM
environment resolves them at runtime instead of module load time.
if (!process.env.SENDGRID_API_KEY || !fromEmail) {
if (!fromEmail) {
logger.info(
`[Email] FROM_EMAIL not set. Would send to ${email}: ${message}`,
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants