hyperswitch icon indicating copy to clipboard operation
hyperswitch copied to clipboard

feat(vsaas): add `created_by` and `last_modified_by` tracking fields to customers and payment_methods tables

Open tsdk02 opened this issue 1 month ago • 2 comments

Type of Change

  • [ ] Bugfix
  • [x] New feature
  • [x] Enhancement
  • [ ] Refactoring
  • [ ] Dependency updates
  • [ ] Documentation
  • [ ] CI/CD

Description

This PR introduces audit-trail tracking fields (created_by and last_modified_by) to the customers and payment_methods tables. These fields enable us to identify who actually initiated the creation or modification of a customer or payment method — whether it was a platform API key, a connected merchant API key, or a dashboard user.

Complete Domain Context: Customers & Payment Methods in the Platform Model

In our platform model, multiple connected merchants operate under a single platform merchant:

  • The platform merchant is always the owner of the entire payment setup.
  • Connected merchants are the processors (execute payments under the platform umbrella).
  • Payments may be triggered by:
    • The platform’s API key (acting on behalf of connected merchants), or
    • A connected merchant’s API key, or
    • A dashboard user authenticated via JWT.

Why Customers and Payment Methods Need Audit Tracking

Customers in our system are created automatically during a payment if they don’t already exist.
Under the platform model:

  • All customers belong to the platform merchant, not the connected merchants.
  • Customers are shared across all connected merchants operating under the platform.
  • By extension, payment methods — since they always belong to a customer — also store the platform merchant id as their owner.

This setup allows:

  • Shared customer and payment method data across connected merchants
  • Unified customer identity under the platform
  • Centralized user and payment method profiles

However, it introduces an important challenge:

We must track who actually triggered:

  • The creation of the customer
  • The creation of any payment method
  • Future updates/modifications to these entities

A connected merchant might initiate a payment that results in the creation of a customer or payment method, but the owner of those records will still be the platform merchant.
Thus, without explicit audit fields, we lose visibility into who triggered the actual operation.

The created_by field already exist for:

  • payment_intents
  • payment_attempts

This PR brings the same auditability to:

  • customers
  • payment_methods

What This PR Adds

New Audit Fields in Storage

For both customers and payment_methods tables:

  • created_by (VARCHAR(255))
  • last_modified_by (VARCHAR(255))

Strongly-Typed Domain Representation

The new fields integrate into a domain-level enum:

pub enum CreatedBy {
    Api { merchant_id: String },
    Jwt { user_id: String },
}

Current Behavior (Important Note)

Although the schema and model support is now in place:

  • There is currently no logic populating these audit fields.
  • Until the authentication context extraction PR lands, all records will temporarily store:
created_by = None
last_modified_by = None

A follow-up PR will:

  • Extract initiator context from API key or JWT
  • Construct a concrete CreatedBy value
  • Populate created_by during creation
  • Populate last_modified_by during modifications

This PR is strictly schema + infrastructure groundwork.

Additional Changes

  • [x] This PR modifies the API contract
  • [x] This PR modifies the database schema
  • [ ] This PR modifies application configuration/environment variables

Database Schema Changes:

  • migrations/2025-11-11-111301_add_tracking_fields_to_customers/
  • migrations/2025-11-12-135015_add_tracking_fields_to_payment_methods/
  • Updated schema.rs and schema_v2.rs

Motivation and Context

Closes #10248

Currently, we lack visibility into who creates or modifies customer and payment method records.

This PR establishes the foundation for comprehensive audit trails by adding the database schema and model layer support

Follow-up work will populate these fields from authentication context at runtime.

How did you test it?

Note: Fields are currently set to None with TODO comments at creation points. Full integration testing will be performed when auth context extraction is implemented.

Checklist

  • [x] I formatted the code cargo +nightly fmt --all
  • [x] I addressed lints thrown by cargo clippy
  • [x] I reviewed the submitted code
  • [ ] I added unit tests for my changes where possible

Next Steps:

  1. Extract created_by from authentication context (API key or JWT)
  2. Populate fields at creation time
  3. Add last_modified_by to relevant update variants (CustomerUpdate, PaymentMethodUpdate)
  4. Add integration tests for audit trail verification

tsdk02 avatar Nov 13 '25 10:11 tsdk02

Review changes with  SemanticDiff

Changed Files
File Status
  crates/hyperswitch_domain_models/src/payments.rs  69% smaller
  crates/hyperswitch_domain_models/src/payments/payment_attempt.rs  52% smaller
  crates/storage_impl/src/payment_method.rs  23% smaller
  crates/hyperswitch_domain_models/src/customer.rs  13% smaller
  crates/common_utils/src/macros.rs  12% smaller
  crates/diesel_models/src/payment_method.rs  11% smaller
  crates/hyperswitch_domain_models/src/payments/payment_intent.rs  9% smaller
  crates/diesel_models/src/schema_v2.rs  8% smaller
  crates/common_utils/src/types.rs  0% smaller
  crates/diesel_models/src/customers.rs  0% smaller
  crates/diesel_models/src/kv.rs  0% smaller
  crates/diesel_models/src/schema.rs  0% smaller
  crates/hyperswitch_domain_models/src/payment_methods.rs  0% smaller
  crates/payment_methods/src/core/migration/payment_methods.rs  0% smaller
  crates/router/src/core/customers.rs  0% smaller
  crates/router/src/core/payment_methods.rs  0% smaller
  crates/router/src/core/payment_methods/cards.rs  0% smaller
  crates/router/src/core/payment_methods/migration.rs  0% smaller
  crates/router/src/core/payment_methods/tokenize/card_executor.rs  0% smaller
  crates/router/src/core/payment_methods/tokenize/payment_method_executor.rs  0% smaller
  crates/router/src/core/payments/helpers.rs  0% smaller
  crates/router/src/core/payments/operations/payment_response.rs  0% smaller
  crates/router/src/core/payouts.rs  0% smaller
  crates/router/src/core/payouts/helpers.rs  0% smaller
  crates/router/src/core/pm_auth.rs  0% smaller
  crates/router/src/core/webhooks/incoming.rs  0% smaller
  crates/router/src/core/webhooks/network_tokenization_incoming.rs  0% smaller
  crates/router/src/workflows/payment_method_status_update.rs  0% smaller
  migrations/2025-11-11-111301_add_tracking_fields_to_customers/down.sql Unsupported file format
  migrations/2025-11-11-111301_add_tracking_fields_to_customers/up.sql Unsupported file format
  migrations/2025-11-12-135015_add_tracking_fields_to_payment_methods/down.sql Unsupported file format
  migrations/2025-11-12-135015_add_tracking_fields_to_payment_methods/up.sql Unsupported file format

semanticdiff-com[bot] avatar Nov 13 '25 10:11 semanticdiff-com[bot]

Codecov Report

:x: Patch coverage is 5.81395% with 81 lines in your changes missing coverage. Please review. :warning: Please upload report for BASE (main@76928bc). Learn more about missing BASE report.

Files with missing lines Patch % Lines
crates/hyperswitch_domain_models/src/customer.rs 4.16% 23 Missing :warning:
crates/diesel_models/src/payment_method.rs 0.00% 20 Missing :warning:
...s/hyperswitch_domain_models/src/payment_methods.rs 0.00% 14 Missing :warning:
crates/common_utils/src/macros.rs 0.00% 10 Missing :warning:
crates/diesel_models/src/customers.rs 0.00% 4 Missing :warning:
crates/router/src/core/customers.rs 0.00% 4 Missing :warning:
crates/router/src/core/payment_methods/cards.rs 0.00% 2 Missing :warning:
crates/storage_impl/src/payment_method.rs 0.00% 2 Missing :warning:
crates/router/src/core/payment_methods.rs 0.00% 1 Missing :warning:
crates/router/src/core/payouts.rs 0.00% 1 Missing :warning:
Additional details and impacted files
@@           Coverage Diff           @@
##             main   #10250   +/-   ##
=======================================
  Coverage        ?    6.49%           
=======================================
  Files           ?     1238           
  Lines           ?   309420           
  Branches        ?        0           
=======================================
  Hits            ?    20112           
  Misses          ?   289308           
  Partials        ?        0           

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

:rocket: New features to boost your workflow:
  • :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • :package: JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

codecov[bot] avatar Nov 13 '25 10:11 codecov[bot]