changes on agent
This commit is contained in:
93
models/catalogueupload.go
Normal file
93
models/catalogueupload.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
// CatalogueUpload is our own receipt for a spreadsheet sent to the ingest
|
||||
// service — the record that the upload happened, who sent it, and for which
|
||||
// shop.
|
||||
//
|
||||
// It exists because nothing else keeps one. The ingest service holds the drop,
|
||||
// but on its terms and not ours:
|
||||
//
|
||||
// 1. **A drop nobody acts on is deleted after seven days**
|
||||
// (`BATCH_RETENTION_DAYS`). If an admin never presses Start, the only proof
|
||||
// the upload ever happened disappears — including from the sender.
|
||||
// 2. **We cannot list our own drops.** `GET /api/uploads/catalog` is scoped to
|
||||
// the credential that sent them, production has no API keys configured, and
|
||||
// the one admin account is a superuser over their whole application. So the
|
||||
// list is not available to us and should not be.
|
||||
// 3. **The batch id is the credential.** `GET /api/uploads/catalog/{batch_id}`
|
||||
// is anonymous by design — holding the id is the proof of having sent the
|
||||
// drop. Which means whoever holds the id can read the result, and nobody
|
||||
// else can. Losing the id loses the result permanently.
|
||||
//
|
||||
// So the id is the thing worth keeping, and this row is where we keep it. Every
|
||||
// status field beside it is a CACHE of what the ingest service last told us,
|
||||
// written by whichever browser was polling. It is never the authority — the
|
||||
// service is — and it exists so a receipt reads sensibly before anyone re-polls
|
||||
// it.
|
||||
//
|
||||
// The tenant and branch are ours alone. The ingest service writes the GLOBAL
|
||||
// catalogue and has no concept of either, so "which shop was this for" is a
|
||||
// question only this row can answer.
|
||||
type CatalogueUpload struct {
|
||||
Uploadid int `json:"uploadid" gorm:"primaryKey;autoIncrement;column:uploadid"`
|
||||
|
||||
// Who the sheet was for. The ingest service knows neither.
|
||||
Tenantid int `json:"tenantid" gorm:"column:tenantid"`
|
||||
Locationid int `json:"locationid" gorm:"column:locationid"`
|
||||
// The category every row was filed under, chosen at upload time. Worth
|
||||
// keeping: a product filed outside the category the app browses is
|
||||
// invisible to shoppers, and this is the only record of what was chosen.
|
||||
Categoryid int `json:"categoryid" gorm:"column:categoryid"`
|
||||
|
||||
// The drop id, and the only thing here that cannot be reconstructed.
|
||||
Batchid string `json:"batchid" gorm:"column:batchid"`
|
||||
// The run an admin released the drop into, once they have. Cached from
|
||||
// `released_to` so a receipt can be followed without re-walking the drop.
|
||||
Runid string `json:"runid" gorm:"column:runid"`
|
||||
|
||||
Filename string `json:"filename" gorm:"column:filename"`
|
||||
// The label the ingest inbox shows their admin. Stored so we can tell,
|
||||
// afterwards, what they were looking at when they approved it.
|
||||
Sender string `json:"sender" gorm:"column:sender"`
|
||||
|
||||
Uploadedby int `json:"uploadedby" gorm:"column:uploadedby"`
|
||||
Uploadedname string `json:"uploadedname" gorm:"column:uploadedname"`
|
||||
|
||||
// Rows we parsed in the browser, before sending. Independent of anything
|
||||
// the service reports, so a drop that never runs still says how big it was.
|
||||
Rowcount int `json:"rowcount" gorm:"column:rowcount"`
|
||||
|
||||
// ── Cached from the ingest service, by whoever last polled ──────────────
|
||||
|
||||
Laststatus string `json:"laststatus" gorm:"column:laststatus;default:pending"`
|
||||
// Their counts, so a settled receipt reads correctly with no network call.
|
||||
Inserted int `json:"inserted" gorm:"column:inserted"`
|
||||
Backfilled int `json:"backfilled" gorm:"column:backfilled"`
|
||||
Skipped int `json:"skipped" gorm:"column:skipped"`
|
||||
Rejected int `json:"rejected" gorm:"column:rejected"`
|
||||
|
||||
// ── Ours: the half the ingest service cannot do ────────────────────────
|
||||
//
|
||||
// Their pipeline writes the global catalogue, which every merchant shares
|
||||
// and which therefore holds no price and no stock. Shelving is what turns
|
||||
// "the product exists" into "this shop can sell it", and it is a separate
|
||||
// action that can be left undone — so it is recorded separately.
|
||||
|
||||
Shelvedcount int `json:"shelvedcount" gorm:"column:shelvedcount"`
|
||||
Skippedcount int `json:"skippedcount" gorm:"column:skippedcount"`
|
||||
Shelvedat *time.Time `json:"shelvedat" gorm:"column:shelvedat"`
|
||||
|
||||
Created time.Time `json:"created" gorm:"column:created;autoCreateTime"`
|
||||
Updated time.Time `json:"updated" gorm:"column:updated;autoUpdateTime"`
|
||||
|
||||
// Joined for display, never stored. A receipt outlives the page that made
|
||||
// it, so it has to be able to name its own shop.
|
||||
Tenantname string `json:"tenantname" gorm:"->;column:tenantname"`
|
||||
Locationname string `json:"locationname" gorm:"->;column:locationname"`
|
||||
}
|
||||
|
||||
func (CatalogueUpload) TableName() string {
|
||||
return "catalogueuploads"
|
||||
}
|
||||
Reference in New Issue
Block a user