feat: Implement loyalty and wholesale services with models, routes, and validation
CI / test (push) Successful in 10m23s

- Added models for loyalty points allocation, redemption, rewards, tiers, tier history, and referrals.
- Created business credit ledger entries, settlements, and settlement items models.
- Developed services for loyalty operations including account management, point allocation, redemption, and referral handling.
- Implemented wholesale credit management services for transactions and settlements.
- Established routes for loyalty and wholesale admin and customer operations with appropriate middleware for authentication and permission checks.
- Introduced validation schemas for loyalty and wholesale operations.
- Set up cron jobs for loyalty reconciliation tasks such as birthday rewards and point expirations.
- Created migration scripts to set up the database schema for loyalty and wholesale features.
- Added unit tests for validation and policy enforcement in loyalty and wholesale services.
This commit is contained in:
Sathira Sri Sathara
2026-09-09 13:56:37 +05:30
parent 222483d194
commit abb760cc19
45 changed files with 482 additions and 58 deletions
+273 -53
View File
@@ -9,24 +9,19 @@
// app/models/index.js
const { Sequelize, DataTypes } = require("sequelize");
const dbConfig = require("../config/db.config");
const loggingOption = process.env.NODE_ENV === "development" ? console.log : false;
const loggingOption =
process.env.NODE_ENV === "development" ? console.log : false;
const sequelize = new Sequelize(
dbConfig.DB,
dbConfig.USER,
dbConfig.PASSWORD,
{
host: dbConfig.HOST,
port: dbConfig.PORT,
dialect: dbConfig.DIALECT,
pool: dbConfig.pool,
logging: loggingOption
}
);
const sequelize = new Sequelize(dbConfig.DB, dbConfig.USER, dbConfig.PASSWORD, {
host: dbConfig.HOST,
port: dbConfig.PORT,
dialect: dbConfig.DIALECT,
pool: dbConfig.pool,
logging: loggingOption,
});
const db = {};
@@ -34,20 +29,38 @@ db.Sequelize = Sequelize;
db.sequelize = sequelize;
/* Register db models */
// User and Authentication
// User and Authentication
db.User = require("./user/user.model")(sequelize, DataTypes);
db.Customer = require("./user/customer.model")(sequelize, DataTypes);
db.BusinessCustomer = require("./user/businessCustomer.model")(sequelize, DataTypes);
db.BusinessCustomer = require("./user/businessCustomer.model")(
sequelize,
DataTypes,
);
db.AuthSession = require("./user/authSession.model")(sequelize, DataTypes);
db.UserIdentity = require("./user/userIdentity.model")(sequelize, DataTypes);
db.UserActivity = require("./activities/userActivities.model")(sequelize, DataTypes);
db.UserActivity = require("./activities/userActivities.model")(
sequelize,
DataTypes,
);
db.Profile = require("./user/profile.model")(sequelize, DataTypes);
db.Address = require("./user/address.model")(sequelize, DataTypes);
db.BusinessApplication = require("./user/businessApplication.model")(sequelize, DataTypes);
db.BusinessContact = require("./user/businessContact.model")(sequelize, DataTypes);
db.BusinessCreditAccount = require("./user/businessCreditAccount.model")(sequelize, DataTypes);
db.SettlementTerm = require("./user/settlementTerm.model")(sequelize, DataTypes);
db.BusinessApplication = require("./user/businessApplication.model")(
sequelize,
DataTypes,
);
db.BusinessContact = require("./user/businessContact.model")(
sequelize,
DataTypes,
);
db.BusinessCreditAccount = require("./user/businessCreditAccount.model")(
sequelize,
DataTypes,
);
db.SettlementTerm = require("./user/settlementTerm.model")(
sequelize,
DataTypes,
);
// Uploads
db.Upload = require("./upload/upload.model")(sequelize, DataTypes);
@@ -55,57 +68,264 @@ db.Upload = require("./upload/upload.model")(sequelize, DataTypes);
// Roles and Permissions
db.roles = require("./permission/role.model")(sequelize, DataTypes);
db.permission = require("./permission/permission.model")(sequelize, DataTypes);
db.rolePermission = require("./permission/rolePermission.model")(sequelize, DataTypes);
db.userPermission = require("./permission/userPermission.model")(sequelize, DataTypes);
db.rolePermission = require("./permission/rolePermission.model")(
sequelize,
DataTypes,
);
db.userPermission = require("./permission/userPermission.model")(
sequelize,
DataTypes,
);
db.UserRole = require("./permission/userRole.model")(sequelize, DataTypes);
// Document Management
db.Document = require("./document/document.model")(sequelize, DataTypes);
db.DocumentType = require("./document/documentType.model")(sequelize, DataTypes);
db.DocumentType = require("./document/documentType.model")(
sequelize,
DataTypes,
);
// Reference Numbers
db.referenceNumber = require("./referenceNumbers/referenceNumber.model")(sequelize, DataTypes);
db.referenceNumber = require("./referenceNumbers/referenceNumber.model")(
sequelize,
DataTypes,
);
// Notifications
db.notification = require("./notification/notification.model")(sequelize, DataTypes);
db.userNotification = require("./notification/userNotification.model")(sequelize, DataTypes);
db.NotificationDelivery = require("./notification/notificationDelivery.model")(sequelize, DataTypes);
db.notification = require("./notification/notification.model")(
sequelize,
DataTypes,
);
db.userNotification = require("./notification/userNotification.model")(
sequelize,
DataTypes,
);
db.NotificationDelivery = require("./notification/notificationDelivery.model")(
sequelize,
DataTypes,
);
// Catalogue and localized content
db.Brand = require("./catalogue/brand.model")(sequelize, DataTypes);
db.Category = require("./catalogue/category.model")(sequelize, DataTypes);
db.CategoryTranslation = require("./catalogue/categoryTranslation.model")(sequelize, DataTypes);
db.CategoryTranslation = require("./catalogue/categoryTranslation.model")(
sequelize,
DataTypes,
);
db.Product = require("./catalogue/product.model")(sequelize, DataTypes);
db.ProductTranslation = require("./catalogue/productTranslation.model")(sequelize, DataTypes);
db.ProductCategory = require("./catalogue/productCategory.model")(sequelize, DataTypes);
db.ProductVariant = require("./catalogue/productVariant.model")(sequelize, DataTypes);
db.ProductOption = require("./catalogue/productOption.model")(sequelize, DataTypes);
db.ProductOptionValue = require("./catalogue/productOptionValue.model")(sequelize, DataTypes);
db.VariantOptionValue = require("./catalogue/variantOptionValue.model")(sequelize, DataTypes);
db.ProductAttribute = require("./catalogue/productAttribute.model")(sequelize, DataTypes);
db.ProductMedia = require("./catalogue/productMedia.model")(sequelize, DataTypes);
db.ProductTranslation = require("./catalogue/productTranslation.model")(
sequelize,
DataTypes,
);
db.ProductCategory = require("./catalogue/productCategory.model")(
sequelize,
DataTypes,
);
db.ProductVariant = require("./catalogue/productVariant.model")(
sequelize,
DataTypes,
);
db.ProductOption = require("./catalogue/productOption.model")(
sequelize,
DataTypes,
);
db.ProductOptionValue = require("./catalogue/productOptionValue.model")(
sequelize,
DataTypes,
);
db.VariantOptionValue = require("./catalogue/variantOptionValue.model")(
sequelize,
DataTypes,
);
db.ProductAttribute = require("./catalogue/productAttribute.model")(
sequelize,
DataTypes,
);
db.ProductMedia = require("./catalogue/productMedia.model")(
sequelize,
DataTypes,
);
db.Collection = require("./catalogue/collection.model")(sequelize, DataTypes);
db.CollectionTranslation = require("./catalogue/collectionTranslation.model")(sequelize, DataTypes);
db.CollectionProduct = require("./catalogue/collectionProduct.model")(sequelize, DataTypes);
db.CollectionTranslation = require("./catalogue/collectionTranslation.model")(
sequelize,
DataTypes,
);
db.CollectionProduct = require("./catalogue/collectionProduct.model")(
sequelize,
DataTypes,
);
db.SizeGuide = require("./catalogue/sizeGuide.model")(sequelize, DataTypes);
db.ProductRelation = require("./catalogue/productRelation.model")(sequelize, DataTypes);
db.ProductReview = require("./catalogue/productReview.model")(sequelize, DataTypes);
db.Warehouse=require("./inventory/warehouse.model")(sequelize,DataTypes);db.InventoryBalance=require("./inventory/inventoryBalance.model")(sequelize,DataTypes);db.InventoryTransaction=require("./inventory/inventoryTransaction.model")(sequelize,DataTypes);db.InventoryReservation=require("./inventory/inventoryReservation.model")(sequelize,DataTypes);db.InventoryTransfer=require("./inventory/inventoryTransfer.model")(sequelize,DataTypes);
db.BusinessTier=require("./pricing/businessTier.model")(sequelize,DataTypes);db.VariantBusinessPrice=require("./pricing/variantBusinessPrice.model")(sequelize,DataTypes);db.BusinessPriceTier=require("./pricing/businessPriceTier.model")(sequelize,DataTypes);
db.Promotion=require("./merchandising/promotion.model")(sequelize,DataTypes);db.PromotionTarget=require("./merchandising/promotionTarget.model")(sequelize,DataTypes);db.Coupon=require("./merchandising/coupon.model")(sequelize,DataTypes);db.Banner=require("./merchandising/banner.model")(sequelize,DataTypes);db.BannerTranslation=require("./merchandising/bannerTranslation.model")(sequelize,DataTypes);
db.Cart=require("./shopping/cart.model")(sequelize,DataTypes);db.CartItem=require("./shopping/cartItem.model")(sequelize,DataTypes);db.WishlistItem=require("./shopping/wishlistItem.model")(sequelize,DataTypes);db.CheckoutSession=require("./shopping/checkoutSession.model")(sequelize,DataTypes);db.CheckoutItem=require("./shopping/checkoutItem.model")(sequelize,DataTypes);
db.ShippingZone=require("./shipping/shippingZone.model")(sequelize,DataTypes);db.ShippingZoneRegion=require("./shipping/shippingZoneRegion.model")(sequelize,DataTypes);db.ShippingMethod=require("./shipping/shippingMethod.model")(sequelize,DataTypes);db.ShippingRate=require("./shipping/shippingRate.model")(sequelize,DataTypes);
db.Order=require("./commerce/order.model")(sequelize,DataTypes);db.OrderItem=require("./commerce/orderItem.model")(sequelize,DataTypes);db.Payment=require("./commerce/payment.model")(sequelize,DataTypes);db.PaymentAttempt=require("./commerce/paymentAttempt.model")(sequelize,DataTypes);db.PaymentWebhookEvent=require("./commerce/paymentWebhookEvent.model")(sequelize,DataTypes);db.Invoice=require("./commerce/invoice.model")(sequelize,DataTypes);db.Refund=require("./commerce/refund.model")(sequelize,DataTypes);db.RefundItem=require("./commerce/refundItem.model")(sequelize,DataTypes);db.ReturnRequest=require("./commerce/returnRequest.model")(sequelize,DataTypes);db.ReturnItem=require("./commerce/returnItem.model")(sequelize,DataTypes);db.CouponRedemption=require("./commerce/couponRedemption.model")(sequelize,DataTypes);
db.RiderProfile=require("./logistics/riderProfile.model")(sequelize,DataTypes);db.Shipment=require("./logistics/shipment.model")(sequelize,DataTypes);db.ShipmentItem=require("./logistics/shipmentItem.model")(sequelize,DataTypes);db.ShipmentAssignment=require("./logistics/shipmentAssignment.model")(sequelize,DataTypes);db.ShipmentEvent=require("./logistics/shipmentEvent.model")(sequelize,DataTypes);db.ShipmentProof=require("./logistics/shipmentProof.model")(sequelize,DataTypes);
db.ProductRelation = require("./catalogue/productRelation.model")(
sequelize,
DataTypes,
);
db.ProductReview = require("./catalogue/productReview.model")(
sequelize,
DataTypes,
);
db.Warehouse = require("./inventory/warehouse.model")(sequelize, DataTypes);
db.InventoryBalance = require("./inventory/inventoryBalance.model")(
sequelize,
DataTypes,
);
db.InventoryTransaction = require("./inventory/inventoryTransaction.model")(
sequelize,
DataTypes,
);
db.InventoryReservation = require("./inventory/inventoryReservation.model")(
sequelize,
DataTypes,
);
db.InventoryTransfer = require("./inventory/inventoryTransfer.model")(
sequelize,
DataTypes,
);
db.BusinessTier = require("./pricing/businessTier.model")(sequelize, DataTypes);
db.VariantBusinessPrice = require("./pricing/variantBusinessPrice.model")(
sequelize,
DataTypes,
);
db.BusinessPriceTier = require("./pricing/businessPriceTier.model")(
sequelize,
DataTypes,
);
db.Promotion = require("./merchandising/promotion.model")(sequelize, DataTypes);
db.PromotionTarget = require("./merchandising/promotionTarget.model")(
sequelize,
DataTypes,
);
db.Coupon = require("./merchandising/coupon.model")(sequelize, DataTypes);
db.Banner = require("./merchandising/banner.model")(sequelize, DataTypes);
db.BannerTranslation = require("./merchandising/bannerTranslation.model")(
sequelize,
DataTypes,
);
db.Cart = require("./shopping/cart.model")(sequelize, DataTypes);
db.CartItem = require("./shopping/cartItem.model")(sequelize, DataTypes);
db.WishlistItem = require("./shopping/wishlistItem.model")(
sequelize,
DataTypes,
);
db.CheckoutSession = require("./shopping/checkoutSession.model")(
sequelize,
DataTypes,
);
db.CheckoutItem = require("./shopping/checkoutItem.model")(
sequelize,
DataTypes,
);
db.ShippingZone = require("./shipping/shippingZone.model")(
sequelize,
DataTypes,
);
db.ShippingZoneRegion = require("./shipping/shippingZoneRegion.model")(
sequelize,
DataTypes,
);
db.ShippingMethod = require("./shipping/shippingMethod.model")(
sequelize,
DataTypes,
);
db.ShippingRate = require("./shipping/shippingRate.model")(
sequelize,
DataTypes,
);
db.Order = require("./commerce/order.model")(sequelize, DataTypes);
db.OrderItem = require("./commerce/orderItem.model")(sequelize, DataTypes);
db.Payment = require("./commerce/payment.model")(sequelize, DataTypes);
db.PaymentAttempt = require("./commerce/paymentAttempt.model")(
sequelize,
DataTypes,
);
db.PaymentWebhookEvent = require("./commerce/paymentWebhookEvent.model")(
sequelize,
DataTypes,
);
db.Invoice = require("./commerce/invoice.model")(sequelize, DataTypes);
db.Refund = require("./commerce/refund.model")(sequelize, DataTypes);
db.RefundItem = require("./commerce/refundItem.model")(sequelize, DataTypes);
db.ReturnRequest = require("./commerce/returnRequest.model")(
sequelize,
DataTypes,
);
db.ReturnItem = require("./commerce/returnItem.model")(sequelize, DataTypes);
db.CouponRedemption = require("./commerce/couponRedemption.model")(
sequelize,
DataTypes,
);
db.RiderProfile = require("./logistics/riderProfile.model")(
sequelize,
DataTypes,
);
db.Shipment = require("./logistics/shipment.model")(sequelize, DataTypes);
db.ShipmentItem = require("./logistics/shipmentItem.model")(
sequelize,
DataTypes,
);
db.ShipmentAssignment = require("./logistics/shipmentAssignment.model")(
sequelize,
DataTypes,
);
db.ShipmentEvent = require("./logistics/shipmentEvent.model")(
sequelize,
DataTypes,
);
db.ShipmentProof = require("./logistics/shipmentProof.model")(
sequelize,
DataTypes,
);
db.LoyaltyAccount = require("./loyalty/loyaltyAccount.model")(
sequelize,
DataTypes,
);
db.LoyaltyTier = require("./loyalty/loyaltyTier.model")(sequelize, DataTypes);
db.LoyaltyTierHistory = require("./loyalty/loyaltyTierHistory.model")(
sequelize,
DataTypes,
);
db.LoyaltyEarnRule = require("./loyalty/loyaltyEarnRule.model")(
sequelize,
DataTypes,
);
db.LoyaltyLedgerEntry = require("./loyalty/loyaltyLedgerEntry.model")(
sequelize,
DataTypes,
);
db.LoyaltyPointAllocation = require("./loyalty/loyaltyPointAllocation.model")(
sequelize,
DataTypes,
);
db.LoyaltyReward = require("./loyalty/loyaltyReward.model")(
sequelize,
DataTypes,
);
db.LoyaltyRedemption = require("./loyalty/loyaltyRedemption.model")(
sequelize,
DataTypes,
);
db.Referral = require("./loyalty/referral.model")(sequelize, DataTypes);
db.CustomerCouponEntitlement =
require("./loyalty/customerCouponEntitlement.model")(sequelize, DataTypes);
db.BusinessCreditLedgerEntry =
require("./wholesale/businessCreditLedgerEntry.model")(sequelize, DataTypes);
db.BusinessSettlement = require("./wholesale/businessSettlement.model")(
sequelize,
DataTypes,
);
db.BusinessSettlementItem = require("./wholesale/businessSettlementItem.model")(
sequelize,
DataTypes,
);
db.PaymentAllocation = require("./wholesale/paymentAllocation.model")(
sequelize,
DataTypes,
);
/* Associations */
Object.keys(db).forEach(model => {
Object.keys(db).forEach((model) => {
if (db[model].associate) {
db[model].associate(db);
}
});
module.exports = db;
@@ -0,0 +1 @@
module.exports=(s,D)=>s.define("CustomerCouponEntitlement",{id:{type:D.STRING,primaryKey:true},user_id:{type:D.STRING,allowNull:false},coupon_id:{type:D.STRING,allowNull:false},source_type:{type:D.STRING(40),allowNull:false},source_id:{type:D.STRING,allowNull:false},status:{type:D.ENUM("ACTIVE","USED","EXPIRED","REVOKED"),allowNull:false},issued_at:{type:D.DATE,allowNull:false},used_at:D.DATE,expires_at:D.DATE},{tableName:"customer_coupon_entitlements",timestamps:true,indexes:[{unique:true,fields:["user_id","coupon_id","source_type","source_id"]}]});
@@ -0,0 +1 @@
module.exports=(s,D)=>s.define("LoyaltyAccount",{id:{type:D.STRING,primaryKey:true},user_id:{type:D.STRING,allowNull:false,unique:true},status:{type:D.ENUM("ACTIVE","SUSPENDED","CLOSED"),allowNull:false,defaultValue:"ACTIVE"},current_tier_id:D.STRING,lifetime_points_earned:{type:D.INTEGER,allowNull:false,defaultValue:0},lifetime_points_redeemed:{type:D.INTEGER,allowNull:false,defaultValue:0},available_points:{type:D.INTEGER,allowNull:false,defaultValue:0},pending_points:{type:D.INTEGER,allowNull:false,defaultValue:0},points_debt:{type:D.INTEGER,allowNull:false,defaultValue:0},last_activity_at:D.DATE},{tableName:"loyalty_accounts",timestamps:true});
@@ -0,0 +1 @@
module.exports=(s,D)=>s.define("LoyaltyEarnRule",{id:{type:D.STRING,primaryKey:true},source_type:{type:D.ENUM("PURCHASE","VERIFIED_REVIEW","REFERRAL","BIRTHDAY"),allowNull:false},status:{type:D.ENUM("ACTIVE","INACTIVE"),allowNull:false},points_per_amount:{type:D.INTEGER},amount_unit:D.DECIMAL(15,2),fixed_points:D.INTEGER,minimum_amount:D.DECIMAL(15,2),maximum_points:D.INTEGER,expiry_days:D.INTEGER,effective_from:{type:D.DATE,allowNull:false},effective_to:D.DATE},{tableName:"loyalty_earn_rules",timestamps:true});
@@ -0,0 +1 @@
module.exports=(s,D)=>s.define("LoyaltyLedgerEntry",{id:{type:D.STRING,primaryKey:true},event_id:{type:D.STRING(180),allowNull:false,unique:true},loyalty_account_id:{type:D.STRING,allowNull:false},type:{type:D.ENUM("EARN","REDEEM","EXPIRE","ADJUSTMENT","REVERSAL"),allowNull:false},source_type:{type:D.STRING(50),allowNull:false},source_id:D.STRING,points_delta:{type:D.INTEGER,allowNull:false},balance_after:{type:D.INTEGER,allowNull:false},status:{type:D.ENUM("POSTED"),allowNull:false,defaultValue:"POSTED"},expires_at:D.DATE,description_code:D.STRING(80),metadata:D.JSON,occurred_at:{type:D.DATE,allowNull:false}},{tableName:"loyalty_ledger_entries",timestamps:true,updatedAt:false});
@@ -0,0 +1 @@
module.exports=(s,D)=>s.define("LoyaltyPointAllocation",{id:{type:D.STRING,primaryKey:true},earn_ledger_id:{type:D.STRING,allowNull:false},loyalty_account_id:{type:D.STRING,allowNull:false},original_points:{type:D.INTEGER,allowNull:false},remaining_points:{type:D.INTEGER,allowNull:false},expires_at:D.DATE},{tableName:"loyalty_point_allocations",timestamps:true});
@@ -0,0 +1 @@
module.exports=(s,D)=>s.define("LoyaltyRedemption",{id:{type:D.STRING,primaryKey:true},redemption_number:{type:D.STRING(80),allowNull:false,unique:true},idempotency_key:{type:D.STRING(160),allowNull:false},loyalty_account_id:{type:D.STRING,allowNull:false},reward_id:{type:D.STRING,allowNull:false},points_cost:{type:D.INTEGER,allowNull:false},status:{type:D.ENUM("COMPLETED","CANCELLED"),allowNull:false},fulfilled_reference:D.STRING,redeemed_at:{type:D.DATE,allowNull:false}},{tableName:"loyalty_redemptions",timestamps:true,indexes:[{unique:true,fields:["loyalty_account_id","idempotency_key"]}]});
@@ -0,0 +1 @@
module.exports=(s,D)=>s.define("LoyaltyReward",{id:{type:D.STRING,primaryKey:true},code:{type:D.STRING(60),allowNull:false,unique:true},name:{type:D.STRING(160),allowNull:false},description:D.TEXT,type:{type:D.ENUM("COUPON","MANUAL"),allowNull:false},points_cost:{type:D.INTEGER,allowNull:false},status:{type:D.ENUM("ACTIVE","INACTIVE","ARCHIVED"),allowNull:false},starts_at:D.DATE,ends_at:D.DATE,stock_limit:D.INTEGER,per_user_limit:D.INTEGER,configuration:D.JSON},{tableName:"loyalty_rewards",timestamps:true});
+1
View File
@@ -0,0 +1 @@
module.exports=(s,D)=>s.define("LoyaltyTier",{id:{type:D.STRING,primaryKey:true},code:{type:D.STRING(60),allowNull:false,unique:true},name:{type:D.STRING(120),allowNull:false},status:{type:D.ENUM("ACTIVE","INACTIVE"),allowNull:false,defaultValue:"ACTIVE"},rank:{type:D.INTEGER,allowNull:false},qualification_threshold:{type:D.INTEGER,allowNull:false},qualification_metric:{type:D.ENUM("LIFETIME_POINTS"),allowNull:false,defaultValue:"LIFETIME_POINTS"},benefits_json:D.JSON,sort_order:{type:D.INTEGER,allowNull:false,defaultValue:0}},{tableName:"loyalty_tiers",timestamps:true});
@@ -0,0 +1 @@
module.exports=(s,D)=>s.define("LoyaltyTierHistory",{id:{type:D.STRING,primaryKey:true},loyalty_account_id:{type:D.STRING,allowNull:false},from_tier_id:D.STRING,to_tier_id:{type:D.STRING,allowNull:false},reason:{type:D.STRING(120),allowNull:false},effective_at:{type:D.DATE,allowNull:false}},{tableName:"loyalty_tier_history",timestamps:true});
+1
View File
@@ -0,0 +1 @@
module.exports=(s,D)=>s.define("Referral",{id:{type:D.STRING,primaryKey:true},referrer_user_id:{type:D.STRING,allowNull:false},referred_user_id:{type:D.STRING,unique:true},referral_code:{type:D.STRING(32),allowNull:false,unique:true},status:{type:D.ENUM("PENDING","REGISTERED","QUALIFIED","REWARDED","REJECTED","EXPIRED"),allowNull:false},qualified_order_id:D.STRING,qualified_at:D.DATE,rewarded_at:D.DATE},{tableName:"referrals",timestamps:true});
@@ -0,0 +1 @@
module.exports=(s,D)=>s.define("BusinessCreditLedgerEntry",{id:{type:D.STRING,primaryKey:true},event_id:{type:D.STRING(180),allowNull:false,unique:true},business_credit_account_id:{type:D.STRING,allowNull:false},business_customer_id:{type:D.STRING,allowNull:false},order_id:D.STRING,payment_id:D.STRING,type:{type:D.ENUM("AUTHORIZATION","CAPTURE","RELEASE","PAYMENT","REFUND","ADJUSTMENT"),allowNull:false},amount:{type:D.DECIMAL(15,2),allowNull:false},currency:{type:D.STRING(3),allowNull:false},balance_delta:{type:D.DECIMAL(15,2),allowNull:false},balance_after:{type:D.DECIMAL(15,2),allowNull:false},reference:D.STRING(160),occurred_at:{type:D.DATE,allowNull:false},metadata:D.JSON},{tableName:"business_credit_ledger_entries",timestamps:true,updatedAt:false});
@@ -0,0 +1 @@
module.exports=(s,D)=>s.define("BusinessSettlement",{id:{type:D.STRING,primaryKey:true},settlement_number:{type:D.STRING(80),allowNull:false,unique:true},business_customer_id:{type:D.STRING,allowNull:false},period_start:{type:D.DATEONLY,allowNull:false},period_end:{type:D.DATEONLY,allowNull:false},due_date:{type:D.DATEONLY,allowNull:false},status:{type:D.ENUM("DRAFT","ISSUED","PARTIALLY_PAID","PAID","OVERDUE","CANCELLED"),allowNull:false},currency:{type:D.STRING(3),allowNull:false},charge_total:{type:D.DECIMAL(15,2),allowNull:false},payment_total:{type:D.DECIMAL(15,2),allowNull:false},balance_due:{type:D.DECIMAL(15,2),allowNull:false},issued_at:D.DATE,paid_at:D.DATE},{tableName:"business_settlements",timestamps:true,indexes:[{unique:true,fields:["business_customer_id","period_start","period_end"]}]});
@@ -0,0 +1 @@
module.exports=(s,D)=>s.define("BusinessSettlementItem",{id:{type:D.STRING,primaryKey:true},business_settlement_id:{type:D.STRING,allowNull:false},order_id:D.STRING,invoice_id:D.STRING,credit_ledger_entry_id:D.STRING,description:{type:D.STRING(255),allowNull:false},amount:{type:D.DECIMAL(15,2),allowNull:false},currency:{type:D.STRING(3),allowNull:false}},{tableName:"business_settlement_items",timestamps:true});
@@ -0,0 +1 @@
module.exports=(s,D)=>s.define("PaymentAllocation",{id:{type:D.STRING,primaryKey:true},event_id:{type:D.STRING(180),allowNull:false,unique:true},payment_id:{type:D.STRING,allowNull:false},business_settlement_id:{type:D.STRING,allowNull:false},amount:{type:D.DECIMAL(15,2),allowNull:false},currency:{type:D.STRING(3),allowNull:false},allocated_at:{type:D.DATE,allowNull:false},allocated_by:{type:D.STRING,allowNull:false}},{tableName:"payment_allocations",timestamps:true});