delivery slot api creation

This commit is contained in:
2026-10-06 17:35:51 +05:30
parent f67cbad79a
commit 03ae7d310b
12 changed files with 1137 additions and 104 deletions

55
main.go
View File

@@ -196,6 +196,61 @@ func main() {
log.Println("⚠️ could not add products.showhealthscore, every product will keep showing its health score:", err)
}
// When a shop delivers, and which window an order chose.
//
// Three named windows a day per BRANCH — see models/deliveryslot.go for why
// the scope is the branch and not the company.
//
// ── A branch with no rows here still trades ─────────────────────────────
//
// Every tenant on the platform the day this ships has no slots, and all of
// them must keep taking orders exactly as before. No backfill, no defaults
// written here: absence means "order without a slot", and the app is
// required to treat an empty list as ordinary rather than as a closed shop.
// Seeding every existing branch with invented timings would have each one
// promising hours nobody agreed to.
if err := db.DB.Exec(`CREATE TABLE IF NOT EXISTS deliveryslots (
slotid SERIAL PRIMARY KEY,
tenantid INTEGER NOT NULL,
locationid INTEGER NOT NULL DEFAULT 0,
slotkey TEXT NOT NULL,
name TEXT NOT NULL DEFAULT '',
starttime TEXT NOT NULL,
endtime TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'active',
created TIMESTAMPTZ NOT NULL DEFAULT now(),
updated TIMESTAMPTZ NOT NULL DEFAULT now()
)`).Error; err != nil {
log.Println("⚠️ could not create deliveryslots, delivery windows will be unavailable:", err)
}
// One row per key per branch. A shop has ONE morning, and a duplicate would
// show the shopper the same window twice with different hours — so the
// upsert that writes these leans on this constraint rather than on a
// read-then-write that two requests could interleave.
if err := db.DB.Exec(
`CREATE UNIQUE INDEX IF NOT EXISTS deliveryslots_branch_key
ON deliveryslots (tenantid, locationid, slotkey)`).Error; err != nil {
log.Println("⚠️ could not add the deliveryslots uniqueness index, a branch may end up with duplicate windows:", err)
}
// The window an order chose, and the day it falls on.
//
// Both nullable, and both stay empty for every order placed without a slot —
// which is every order today and every order from a branch that never sets
// timings. Nothing downstream may require them.
//
// The DATE is not redundant. "evening" cannot say tonight or tomorrow night,
// and an order placed after the last window closes is for the next day.
if err := db.DB.Exec(
`ALTER TABLE orders ADD COLUMN IF NOT EXISTS deliveryslotid INTEGER`).Error; err != nil {
log.Println("⚠️ could not add orders.deliveryslotid, orders will not record a delivery window:", err)
}
if err := db.DB.Exec(
`ALTER TABLE orders ADD COLUMN IF NOT EXISTS deliveryslotdate DATE`).Error; err != nil {
log.Println("⚠️ could not add orders.deliveryslotdate, orders will not record which day their window falls on:", err)
}
// When a product became visible to a store, and the only thing that decides
// whether it is.
//