updates on the ai agents and time series prediction and updates on the api to

This commit is contained in:
2026-10-09 13:50:30 +05:30
parent 29690c56f2
commit 153be40e5c
42 changed files with 4889 additions and 186 deletions

View File

@@ -14,11 +14,59 @@ type Tenant struct {
// parcel; not for a food order, where it just slows every drop down.
// Defaults off: turning it on platform-wide would block deliveries for
// clients whose customer app has no way to show the code yet.
Requiredeliveryotp bool `json:"requiredeliveryotp" gorm:"column:requiredeliveryotp;default:false"`
Requiredeliveryotp bool `json:"requiredeliveryotp" gorm:"column:requiredeliveryotp;default:false"`
// Deliverycategory is WHAT this client ships, from the same vocabulary
// pricing uses (constants.DeliveryCategories) — a tenant whose category is
// not a pricing category cannot be priced, so the two are one list.
//
// It decides whether reverse logistics applies: a returned meal is waste,
// not inventory, so Food clients get no RTO path. See
// constants.ReverseLogisticsAllowed for the reasoning.
//
// Empty on every tenant onboarded before this field existed, and empty
// must keep behaving as it always did — which is why
// ReverseLogisticsAllowed treats an unknown category as returnable rather
// than defaulting the new flag to off.
Deliverycategory string `json:"deliverycategory" gorm:"column:deliverycategory;size:32"`
// Reverselogisticsenabled is the OPERATIONAL consequence, stored rather
// than derived on every read.
//
// Two reasons it is its own column. First, an operator may need to turn
// returns off for a non-Food client (a clearance line that is final sale)
// or on for a Food client (a caterer who takes back equipment), and a
// derived value cannot be overridden. Second, deriving it would mean that
// editing a client's category silently changes whether live parcels can be
// returned — a stored flag makes that an explicit second decision.
// A POINTER, deliberately, and this is load-bearing.
//
// GORM omits a zero-value field from an INSERT when the tag declares a
// default — so a plain `bool` set to false was silently dropped and the
// column default (true) applied, creating Food clients with reverse
// logistics ENABLED: the exact case this feature exists to prevent,
// failing silently. A test caught it.
//
// Dropping the default instead is worse: ADD COLUMN ... NOT NULL with no
// default fails outright on a populated tenants table.
//
// A pointer gives both. nil means "not stated" and the column default
// (true) applies — which is what every row predating this field wants. A
// non-nil false is written as false, because GORM never omits a non-nil
// pointer. Read it through ReturnsEnabled(), never directly.
Reverselogisticsenabled *bool `json:"reverselogisticsenabled" gorm:"column:reverselogisticsenabled;default:true"`
Createdat time.Time `json:"createdat" gorm:"column:createdat;default:CURRENT_TIMESTAMP"`
Updatedat time.Time `json:"updatedat" gorm:"column:updatedat;default:CURRENT_TIMESTAMP"`
}
// ReturnsEnabled is the one way to read Reverselogisticsenabled.
//
// nil means the client predates the field, and those clients were all using
// returns — so nil is TRUE. Reading the pointer directly invites a nil deref
// or, worse, treating "not stated" as "disabled" and silently withdrawing a
// capability a client is already using.
func (t Tenant) ReturnsEnabled() bool {
return t.Reverselogisticsenabled == nil || *t.Reverselogisticsenabled
}
func (Tenant) TableName() string {
return "tenants"
}