Adds LoyaltySettingsProcessor (docs/prd-point-coin.md F1, F2, F12, PC-109). Reading returns typed settings for an outlet (earning per currency, paying with EnakPoint) and for an organization (point value, exchange rate, transfers, and the expiry settings awaiting note N4). A key that was never set takes the PRD default. A stored value that is unusable, such as an earn_per_amount of 0 that would divide by zero, also falls back to the default and is logged, so a bad row never reaches a calculation. Writing takes the whole settings struct, validates every rule in the PRD before touching the database, and stores and records in loyalty_setting_changes only the keys whose effective value changes: old value (NULL while it was on its default), new value, and who changed it. Clearing a limit deletes the stored value. Each save runs in one transaction under an advisory lock per outlet or organization, so two saves at once cannot both compute their change from the same old value. The outlet must belong to the caller's organization. Every key is described once (key, default, valid range, bound field), and reading, validating and diffing all use that description. GET /customer/wallet now reads the point value through this processor; the minimal organization settings repository from PC-106 is removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
35 lines
1.1 KiB
Go
35 lines
1.1 KiB
Go
package entities
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// LoyaltySettingChange records one change to a loyalty setting: which key, from what,
|
|
// to what, by whom (docs/prd-point-coin.md F2). Append-only.
|
|
type LoyaltySettingChange struct {
|
|
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
|
|
OrganizationID uuid.UUID `gorm:"type:uuid;not null" json:"organization_id"`
|
|
// Nil for an organization setting.
|
|
OutletID *uuid.UUID `gorm:"type:uuid" json:"outlet_id"`
|
|
Key string `gorm:"not null;size:100" json:"key"`
|
|
// Nil when the key had no stored value, or has none any more.
|
|
OldValue *string `gorm:"type:text" json:"old_value"`
|
|
NewValue *string `gorm:"type:text" json:"new_value"`
|
|
ChangedBy uuid.UUID `gorm:"type:uuid;not null" json:"changed_by"`
|
|
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"`
|
|
}
|
|
|
|
func (c *LoyaltySettingChange) BeforeCreate(tx *gorm.DB) error {
|
|
if c.ID == uuid.Nil {
|
|
c.ID = uuid.New()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (LoyaltySettingChange) TableName() string {
|
|
return "loyalty_setting_changes"
|
|
}
|