Record the probes that touched live data

seedprices is the only account of what the 15 seeded retail prices were and how
to put the zeros back — products at 1135 and 1185 were all at 0, so nothing was
sellable and the terminal could not be exercised at all. It refuses to overwrite
a price a human already set, so re-running it is safe.

termfixcleanup removes the one bill posted to prove the terminalid fix against
production. Named by its own terminalorderid rather than by date or by "the
newest row": pos_orders holds real takings and is not a table to run an
unbounded DELETE against.

healthproof carries a warning it did not have when it was written. MQTT_USER in
.env is pos_ingest, which the ACL denies publish on the health topic, and
Mosquitto answers an ACL-denied QoS 1 publish with a PUBACK before discarding
it. So the tool connects, reports success, and nothing arrives — indistinguishable
from a dead consumer, which is how it read for an hour.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Suriya
2026-08-05 18:47:54 +05:30
parent ec672a3087
commit 11595ad415
3 changed files with 425 additions and 0 deletions

View File

@@ -0,0 +1,90 @@
// Removes the single bill posted to prove the terminalid fix on v1.3.96.
//
// Named by its own terminalorderid rather than by date or by "the newest row" —
// pos_orders holds real takings, and is not a table to run an unbounded DELETE
// against. Stock is returned before the bill is deleted, so the ledger is never
// left short with nothing remaining to explain why.
//
// go run ./scratch/termfixcleanup
package main
import (
"fmt"
"log"
"os"
"github.com/joho/godotenv"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
const (
tenantID = 1087
locationID = 1135
testOrder = "a1b2c3d4-0000-4000-8000-termfix00001"
)
func main() {
_ = godotenv.Load()
dsn := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
os.Getenv("DB_HOST"), os.Getenv("DB_PORT"), os.Getenv("DB_USER"),
os.Getenv("DB_PASSWORD"), os.Getenv("DB_NAME"))
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
Logger: logger.Default.LogMode(logger.Silent),
})
if err != nil {
log.Fatal(err)
}
var billIDs []int
db.Raw(`SELECT posorderid FROM pos_orders WHERE terminalorderid = ?`,
testOrder).Scan(&billIDs)
if len(billIDs) == 0 {
fmt.Println("no test bill found — nothing to undo")
return
}
fmt.Printf("found test bill(s): %v\n", billIDs)
var consumed []struct {
Productid int
Quantity float64
}
db.Raw(`SELECT productid, SUM(quantity) AS quantity
FROM pos_order_items WHERE posorderid IN ?
GROUP BY productid`, billIDs).Scan(&consumed)
for _, c := range consumed {
qty := int(c.Quantity)
if float64(qty) < c.Quantity {
qty++ // the ingest rounds up, so the reversal must too
}
if err := db.Exec(`
INSERT INTO productstocks (tenantid, stockdate, locationid, productid,
quantity, stocktype, status)
VALUES (?, NOW(), ?, ?, ?, 'in', 'Active')`,
tenantID, locationID, c.Productid, qty).Error; err != nil {
fmt.Println(" return stock:", err)
continue
}
fmt.Printf(" returned %d unit(s) of product %d\n", qty, c.Productid)
}
db.Exec(`DELETE FROM pos_order_items WHERE posorderid IN ?`, billIDs)
db.Exec(`DELETE FROM pos_orders WHERE posorderid IN ?`, billIDs)
fmt.Printf(" deleted %d bill(s) and their items\n", len(billIDs))
var left int64
db.Raw(`SELECT COUNT(*) FROM pos_orders WHERE terminalorderid = ?`, testOrder).Scan(&left)
fmt.Printf("\nremaining test rows: %d\n", left)
var stock float64
db.Raw(`SELECT COALESCE(SUM(CASE WHEN LOWER(stocktype)='in' THEN quantity ELSE 0 END) -
SUM(CASE WHEN LOWER(stocktype)='out' THEN quantity ELSE 0 END), 0)
FROM productstocks WHERE productid = 6988 AND locationid = ? AND tenantid = ?`,
locationID, tenantID).Scan(&stock)
fmt.Printf("Mysore Banana stock now: %.0f (was 750 before any probe)\n", stock)
}