feat(vsaas): add `created_by` and `last_modified_by` tracking fields to customers and payment_methods tables
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_intentspayment_attempts
This PR brings the same auditability to:
customerspayment_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.rsandschema_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:
- Extract
created_byfrom authentication context (API key or JWT) - Populate fields at creation time
- Add
last_modified_byto relevant update variants (CustomerUpdate, PaymentMethodUpdate) - Add integration tests for audit trail verification
Changed Files
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.
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.