Audit Logs

Description

The LOC Service maintains two types of audit logs to track changes to payments and installments. These logs are created by DynamoDB Stream handlers when records are modified, providing a complete history of all changes.

Payment Logs

Payment logs track the lifecycle of each payment including status changes, amounts, and which installments the payment was applied to.

Fields

Field Type Description

user_id

String

User ID who owns the payment

loan_id

String

Loan this payment belongs to

payment_id

String

Payment being logged

amount

Integer

Payment amount in cents at time of log

confirmation_id

String

Confirmation ID from payments service

status

String

Payment status at time of log

process

String

Process type: MANUAL, AUTO, RETRY

payment_attempts

Integer

Number of payment attempts at time of log

applied_installments

Array

Installments this payment was applied to

message

String

Description of the change (from UpdateReason)

created_at

String

Log creation timestamp (RFC3339)

Keys

Key Pattern

PK

PAYMENTLOG#<user_id>

SK

LOAN#<loan_id>#PAYMENTLOG#<payment_id>#<created_at>

Query Patterns

Query Index Key Condition

List all payment logs for a loan

Primary

PK = PAYMENTLOG#<user_id>, SK begins_with LOAN#<loan_id>#PAYMENTLOG

List logs for specific payment

Primary

PK = PAYMENTLOG#<user_id>, SK begins_with LOAN#<loan_id>#PAYMENTLOG#<payment_id>

Installment Logs

Installment logs track changes to installments including payment applications and status changes.

Fields

Field Type Description

user_id

String

User ID who owns the installment

loan_id

String

Loan this installment belongs to

installment_id

String

Installment being logged

process

String

Process type: CREATION, AUTOPAY, MANUAL, UNAPPLY

applied_payments

Array

Payments applied to this installment at time of log

message

String

Description of the change (from UpdateReason)

created_at

String

Log creation timestamp (RFC3339)

Keys

Key Pattern

PK

INSTALLMENTLOG#<user_id>

SK

LOAN#<loan_id>#INSTALLMENT#<installment_id>#<created_at>

Query Patterns

Query Index Key Condition

List all installment logs for a loan

Primary

PK = INSTALLMENTLOG#<user_id>, SK begins_with LOAN#<loan_id>#INSTALLMENT

List logs for specific installment

Primary

PK = INSTALLMENTLOG#<user_id>, SK begins_with LOAN#<loan_id>#INSTALLMENT#<installment_id>

How Logs Are Created

Logs are created through DynamoDB Streams:

Payment/Installment Update
         │
         ▼
┌─────────────────────────┐
│    DynamoDB Stream      │
│  (captures old/new)     │
└───────────┬─────────────┘
            │
            ▼
┌─────────────────────────┐
│     Log Handler         │
│  (Lambda function)      │
└───────────┬─────────────┘
            │
            ▼
┌─────────────────────────┐
│   PaymentLog or         │
│   InstallmentLog        │
│   (saved to DynamoDB)   │
└─────────────────────────┘

UpdateReason Field

Both Payment and Installment entities have a transient UpdateReason field that is consumed by the log handler:

  • This field should describe what change was made and why

  • For payments, include amount change information when relevant

  • The field is marked omitempty and not persisted long-term on the main record

Example usage in code:

payment.UpdateReason = "Payment completed successfully, applied $50.00 to installment"

Example Log Entry

{
  "PK": "PAYMENTLOG#user-123",
  "SK": "LOAN#loan-456#PAYMENTLOG#pay-789#2024-01-15T12:00:00Z",
  "user_id": "user-123",
  "loan_id": "loan-456",
  "payment_id": "pay-789",
  "amount": 5000,
  "confirmation_id": "conf-abc",
  "status": "COMPLETED",
  "process": "AUTO",
  "payment_attempts": 1,
  "applied_installments": [
    {
      "payment_id": "pay-789",
      "installment_id": "inst-001",
      "amount": 5000,
      "payment_date": "2024-01-15T12:00:00Z"
    }
  ],
  "message": "Autopay payment completed successfully",
  "created_at": "2024-01-15T12:00:00Z"
}