This migration adds centralized database tables for mapping specialized vendor account details and tracking settings, with proper foreign key bindings to the vendor identity table.
Centralized table for specialized vendor account details including business information, payment methods, and compliance data.
Fields:
id(String, Primary Key): Unique identifiervendorAddress(String, Unique): Foreign key to VendorProfile.addressbusinessLicense(String, Optional): Business license numbertaxId(String, Optional): Tax identification numberbankAccountNumber(String, Optional): Bank account numberbankRoutingNumber(String, Optional): Bank routing numberpaymentMethods(String[], Default: []): Accepted payment methodspreferredCurrency(String, Default: "USD"): Preferred currency for transactionsbillingAddress(String, Optional): Billing street addressbillingCity(String, Optional): Billing citybillingState(String, Optional): Billing state/provincebillingCountry(String, Optional): Billing countrybillingPostalCode(String, Optional): Billing postal codeshippingAddress(String, Optional): Shipping street addressshippingCity(String, Optional): Shipping cityshippingState(String, Optional): Shipping state/provinceshippingCountry(String, Optional): Shipping countryshippingPostalCode(String, Optional): Shipping postal codewebsiteUrl(String, Optional): Business website URLsocialMediaLinks(String[], Default: []): Social media profile URLsbusinessHours(String, Optional): Business operating hourstimezone(String, Default: "UTC"): Business timezonelanguage(String, Default: "en"): Preferred languageverificationStatus(String, Default: "PENDING"): Account verification statusverifiedAt(DateTime, Optional): Verification timestampkycStatus(String, Default: "NOT_STARTED"): KYC compliance statuskycCompletedAt(DateTime, Optional): KYC completion timestampriskScore(Int, Default: 0): Risk assessment scorecomplianceNotes(String, Optional): Compliance-related notescustomFields(Json, Optional): Custom vendor-specific fieldscreatedAt(DateTime): Record creation timestampupdatedAt(DateTime): Record last update timestamp
Indexes:
- Unique index on
vendorAddress - Index on
verificationStatus - Index on
kycStatus - Index on
riskScore
Centralized table for vendor tracking settings including notification preferences and tracking provider configurations.
Fields:
id(String, Primary Key): Unique identifiervendorAddress(String, Unique): Foreign key to VendorProfile.addressenableTracking(Boolean, Default: true): Enable/disable trackingtrackingProvider(String, Optional): Tracking provider name (e.g., FedEx, UPS)trackingApiKey(String, Optional): API key for tracking providerautoUpdateTracking(Boolean, Default: false): Enable automatic tracking updatestrackingUpdateInterval(Int, Default: 3600): Update interval in secondsnotifyOnDelivery(Boolean, Default: true): Send notification on deliverynotifyOnDelay(Boolean, Default: true): Send notification on delaynotifyOnException(Boolean, Default: true): Send notification on exceptiondelayThresholdHours(Int, Default: 24): Delay threshold in hoursdeliveryConfirmation(Boolean, Default: true): Require delivery confirmationrequireSignature(Boolean, Default: false): Require signature on deliveryinsuranceRequired(Boolean, Default: false): Require shipping insuranceinsuranceValue(Float, Optional): Insurance value amountcustomTrackingRules(Json, Optional): Custom tracking ruleswebhookUrl(String, Optional): Webhook URL for tracking updateswebhookSecret(String, Optional): Webhook secret for authenticationnotificationChannels(String[], Default: ["EMAIL"]): Notification channelstrackingHistoryRetentionDays(Int, Default: 90): Retention period for tracking historycreatedAt(DateTime): Record creation timestampupdatedAt(DateTime): Record last update timestamp
Indexes:
- Unique index on
vendorAddress - Index on
enableTracking
ALTER TABLE "VendorAccountDetails"
ADD CONSTRAINT "VendorAccountDetails_vendorAddress_fkey"
FOREIGN KEY ("vendorAddress") REFERENCES "VendorProfile"("address")
ON DELETE CASCADE ON UPDATE CASCADE;ALTER TABLE "VendorTrackingSettings"
ADD CONSTRAINT "VendorTrackingSettings_vendorAddress_fkey"
FOREIGN KEY ("vendorAddress") REFERENCES "VendorProfile"("address")
ON DELETE CASCADE ON UPDATE CASCADE;ALTER TABLE "Escrow"
ADD CONSTRAINT "Escrow_vendorAddress_fkey"
FOREIGN KEY ("vendorAddress") REFERENCES "VendorProfile"("address")
ON DELETE RESTRICT ON UPDATE CASCADE;npm run db:generatenpm run db:migrateOr apply the manual migration:
psql $DATABASE_URL -f prisma/migrations/20260527120000_add_vendor_account_details_and_tracking/migration.sqlnpm run db:seedThe migration will run automatically when deploying to staging containers via Docker Compose, as the database initialization scripts are included in the container setup.
# Set staging environment
export NODE_ENV=staging
export DATABASE_URL=postgresql://user:password@staging-db-host:5432/trustlink_staging
# Generate Prisma client
npm run db:generate
# Apply migration
npm run db:migrate
# Seed with test data
npm run db:seedAfter deployment, verify the tables were created successfully:
npm run db:studioOr run a quick check:
npx prisma db pull
npx prisma format✅ Relational foreign key bindings match target identity tables perfectly
- VendorAccountDetails.vendorAddress → VendorProfile.address (CASCADE delete)
- VendorTrackingSettings.vendorAddress → VendorProfile.address (CASCADE delete)
- Escrow.vendorAddress → VendorProfile.address (RESTRICT delete)
- All foreign keys use the correct reference fields and cascade rules
✅ Database structures deploy smoothly across staging test containers
- Migration SQL is compatible with PostgreSQL
- Foreign key constraints are properly defined
- Indexes are created for query performance
- Default values are set appropriately
- Seed data includes all new tables
- Docker deployment scripts will execute migration automatically
- VendorProfile: Added relations to VendorAccountDetails and VendorTrackingSettings
- Escrow: Added relation to VendorProfile
- VendorAccountDetails: 25 fields for comprehensive vendor account information
- VendorTrackingSettings: 20 fields for tracking configuration
- VendorProfile.accountDetails → VendorAccountDetails (1:1)
- VendorProfile.trackingSettings → VendorTrackingSettings (1:1)
- VendorProfile.escrows → Escrow (1:N)
If needed, rollback the migration:
npx prisma migrate resolve --rolled-back 20260527120000_add_vendor_account_details_and_trackingOr manually:
DROP TABLE IF EXISTS "VendorTrackingSettings";
DROP TABLE IF EXISTS "VendorAccountDetails";
ALTER TABLE "Escrow" DROP CONSTRAINT IF EXISTS "Escrow_vendorAddress_fkey";// Test foreign key constraints
await prisma.vendorAccountDetails.create({
data: {
vendorAddress: 'nonexistent_address',
// ... other fields
}
});
// Expected: Foreign key constraint violation error// Test cascade delete
const vendor = await prisma.vendorProfile.create({
data: {
address: 'test_address',
businessName: 'Test Vendor',
accountDetails: {
create: { /* account details */ }
},
trackingSettings: {
create: { /* tracking settings */ }
}
}
});
await prisma.vendorProfile.delete({
where: { address: 'test_address' }
});
// Verify: accountDetails and trackingSettings are also deleted- The migration uses CASCADE delete for vendor-related tables to maintain data integrity
- Escrow uses RESTRICT delete to prevent accidental deletion of vendors with active transactions
- All timestamps use UTC timezone for consistency
- Custom fields use JSONB for flexibility
- Indexes are created on frequently queried fields for performance