backend requirements onthe xustomer app
This commit is contained in:
85
controllers/cxDeviceController.go
Normal file
85
controllers/cxDeviceController.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"doormile/db"
|
||||
"doormile/models"
|
||||
"doormile/utils"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
// Device registration — §10 of the contract.
|
||||
//
|
||||
// One row per device token rather than one column on the customer. A customer
|
||||
// with a phone and a tablet has to get the delivery notification on both, and
|
||||
// appcustomers.device_token could only ever hold whichever registered last —
|
||||
// so the older device silently stopped receiving anything.
|
||||
|
||||
// RegisterCxDevice records a push token for the signed-in customer.
|
||||
func RegisterCxDevice(c *fiber.Ctx) error {
|
||||
customerID := c.Locals("userid").(int)
|
||||
|
||||
var req struct {
|
||||
Token string `json:"token"`
|
||||
Platform string `json:"platform"`
|
||||
AppVersion string `json:"appVersion"`
|
||||
}
|
||||
if err := c.BodyParser(&req); err != nil {
|
||||
return utils.CxBadRequest(c, "We could not read that request")
|
||||
}
|
||||
token := strings.TrimSpace(req.Token)
|
||||
if token == "" {
|
||||
return utils.CxBadRequest(c, "A device token is required")
|
||||
}
|
||||
|
||||
platform := strings.ToLower(strings.TrimSpace(req.Platform))
|
||||
if platform != "android" && platform != "ios" {
|
||||
platform = ""
|
||||
}
|
||||
|
||||
device := models.CustomerDevice{
|
||||
Appcustomerid: customerID,
|
||||
Token: token,
|
||||
Platform: platform,
|
||||
Appversion: strings.TrimSpace(req.AppVersion),
|
||||
Lastseenat: utils.DBNow(),
|
||||
}
|
||||
|
||||
// A token can migrate between accounts — a shared handset, or a customer
|
||||
// signing out and a second one signing in. Upserting on the token (rather
|
||||
// than inserting) reassigns it, which is the only outcome that does not
|
||||
// send one person's parcel updates to another person's phone.
|
||||
if err := db.DB.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "token"}},
|
||||
DoUpdates: clause.AssignmentColumns([]string{
|
||||
"appcustomerid", "platform", "appversion", "lastseenat",
|
||||
}),
|
||||
}).Create(&device).Error; err != nil {
|
||||
utils.Error("RegisterCxDevice: upsert failed", "customer_id", customerID, "error", err)
|
||||
return utils.CxInternal(c)
|
||||
}
|
||||
|
||||
return utils.CxOK(c, fiber.Map{"registered": true})
|
||||
}
|
||||
|
||||
// UnregisterCxDevice drops a push token. Called on sign-out, so a signed-out
|
||||
// phone stops receiving updates about a pickup it can no longer open.
|
||||
func UnregisterCxDevice(c *fiber.Ctx) error {
|
||||
customerID := c.Locals("userid").(int)
|
||||
token := strings.TrimSpace(c.Params("token"))
|
||||
if token == "" {
|
||||
return utils.CxBadRequest(c, "A device token is required")
|
||||
}
|
||||
|
||||
if err := db.DB.Where("appcustomerid = ? AND token = ?", customerID, token).
|
||||
Delete(&models.CustomerDevice{}).Error; err != nil && err != gorm.ErrRecordNotFound {
|
||||
utils.Error("UnregisterCxDevice: delete failed", "customer_id", customerID, "error", err)
|
||||
return utils.CxInternal(c)
|
||||
}
|
||||
|
||||
return utils.CxOK(c, fiber.Map{"registered": false})
|
||||
}
|
||||
Reference in New Issue
Block a user