daily merchant app login fix
This commit is contained in:
@@ -101,4 +101,11 @@ type TenantUserInfo struct {
|
|||||||
Categoryname string `json:"categoryname"`
|
Categoryname string `json:"categoryname"`
|
||||||
Subcategoryid int `json:"subcategoryid"`
|
Subcategoryid int `json:"subcategoryid"`
|
||||||
Issuperadmin bool `json:"issuperadmin"`
|
Issuperadmin bool `json:"issuperadmin"`
|
||||||
|
// Carried so this response is a SUPERSET of what `UserInfo` returned.
|
||||||
|
// `/mob/users/tenant/login` used to answer with UserInfo, and a shipped app
|
||||||
|
// may read any of these three; dropping them while repointing the route
|
||||||
|
// would have been a breaking change disguised as a fix.
|
||||||
|
Shiftid int `json:"shiftid"`
|
||||||
|
Shiftname string `json:"shiftname"`
|
||||||
|
Status string `json:"status"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ type UserRepository interface {
|
|||||||
GetUserByID(uid int) (models.UserInfo, error)
|
GetUserByID(uid int) (models.UserInfo, error)
|
||||||
Login(user models.User) (models.UserInfo, error)
|
Login(user models.User) (models.UserInfo, error)
|
||||||
FindUserID(authname, contactno string, configid int) (int, error)
|
FindUserID(authname, contactno string, configid int) (int, error)
|
||||||
GetTenantUserByID(userid int) (models.TenantUserInfo, error)
|
|
||||||
UpdateStaff(user models.User) error
|
UpdateStaff(user models.User) error
|
||||||
GetUserByAuthname(authname string, configid int) (int, string, string)
|
GetUserByAuthname(authname string, configid int) (int, string, string)
|
||||||
GetUserByContactNo(contactno string, configid int) (int, string, string)
|
GetUserByContactNo(contactno string, configid int) (int, string, string)
|
||||||
@@ -188,18 +187,7 @@ func (r *userRepository) FindUserID(authname, contactno string, configid int) (i
|
|||||||
return uid, nil
|
return uid, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *userRepository) GetTenantUserByID(userid int) (models.TenantUserInfo, error) {
|
|
||||||
var info models.TenantUserInfo
|
|
||||||
query := `SELECT a.userid, a.authname, a.contactno, a.tenantid, t.tenantname
|
|
||||||
FROM app_users a
|
|
||||||
LEFT JOIN tenants t ON a.tenantid = t.tenantid
|
|
||||||
WHERE a.userid = ?`
|
|
||||||
|
|
||||||
if err := r.db.Raw(query, userid).Scan(&info).Error; err != nil {
|
|
||||||
return info, err
|
|
||||||
}
|
|
||||||
return info, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *userRepository) UpdateStaff(user models.User) error {
|
func (r *userRepository) UpdateStaff(user models.User) error {
|
||||||
return r.db.Table("app_users").Where("userid = ?", user.Userid).Updates(&user).Error
|
return r.db.Table("app_users").Where("userid = ?", user.Userid).Updates(&user).Error
|
||||||
@@ -237,6 +225,15 @@ func (r *userRepository) UpdateFCMToken(userid int, token string) error {
|
|||||||
return r.db.Exec(query, token, userid).Error
|
return r.db.Exec(query, token, userid).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The one tenant-user read. There used to be two.
|
||||||
|
//
|
||||||
|
// A `GetTenantUserByID` sat beside this — one capital letter apart, twenty-eight
|
||||||
|
// columns short, selecting only userid, authname, contactno, tenantid and
|
||||||
|
// tenantname. `TenantLogin` called that one, so the mobile login it served
|
||||||
|
// answered with a record whose name, branch, region and coordinates were blank,
|
||||||
|
// and the route was quietly pointed at a different handler to work around it.
|
||||||
|
// Deleted rather than documented: two functions this similar, where picking the
|
||||||
|
// wrong one fails silently, is a trap and not an API.
|
||||||
func (r *userRepository) GetTenantUserById(userid int) models.TenantUserInfo {
|
func (r *userRepository) GetTenantUserById(userid int) models.TenantUserInfo {
|
||||||
var info models.TenantUserInfo
|
var info models.TenantUserInfo
|
||||||
|
|
||||||
@@ -252,12 +249,14 @@ func (r *userRepository) GetTenantUserById(userid int) models.TenantUserInfo {
|
|||||||
b.partnerid,b.moduleid,b.categoryid as categoryid,b.subcategoryid as subcategoryid,
|
b.partnerid,b.moduleid,b.categoryid as categoryid,b.subcategoryid as subcategoryid,
|
||||||
b.applocationid,b.tenantname,b.address as tenantaddress,b.state as tenantstate,b.city as tenantcity,
|
b.applocationid,b.tenantname,b.address as tenantaddress,b.state as tenantstate,b.city as tenantcity,
|
||||||
b.postcode as tenantpostcode,b.latitude as tenantlat,b.longitude as tenantlong,c.locationname AS applocation,
|
b.postcode as tenantpostcode,b.latitude as tenantlat,b.longitude as tenantlong,c.locationname AS applocation,
|
||||||
c.latitude as applatitude,c.longitude as applongitude,c.radius as appradius, d.categoryname, e.locationname
|
c.latitude as applatitude,c.longitude as applongitude,c.radius as appradius, d.categoryname, e.locationname,
|
||||||
|
a.shiftid, concat(f.starttime, ' - ', f.endtime) as shiftname, a.status
|
||||||
from app_users a
|
from app_users a
|
||||||
LEFT JOIN tenants b ON a.tenantid=b.tenantid
|
LEFT JOIN tenants b ON a.tenantid=b.tenantid
|
||||||
LEFT JOIN app_location c on c.applocationid=b.applocationid
|
LEFT JOIN app_location c on c.applocationid=b.applocationid
|
||||||
LEFT JOIN app_category d ON b.categoryid=d.categoryid
|
LEFT JOIN app_category d ON b.categoryid=d.categoryid
|
||||||
LEFT JOIN tenantlocations e ON a.locationid=e.locationid
|
LEFT JOIN tenantlocations e ON a.locationid=e.locationid
|
||||||
|
LEFT JOIN ridershifts f ON a.shiftid = f.shiftid
|
||||||
WHERE a.userid = ?
|
WHERE a.userid = ?
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,12 @@ func RegisterUserRoutes(api fiber.Router, f *facade.Facade) {
|
|||||||
users.Delete("/delete", f.UserController.DeleteUser)
|
users.Delete("/delete", f.UserController.DeleteUser)
|
||||||
|
|
||||||
users = api.Group("/v1/mob/users")
|
users = api.Group("/v1/mob/users")
|
||||||
users.Post("/tenant/login", f.UserController.Login)
|
// `TenantLogin`, not `Login`. The route is named for the tenant and the app
|
||||||
|
// needs the shop with it — its name, address, category, branch and the
|
||||||
|
// superadmin flag — none of which `UserInfo` carries. `TenantUserInfo` now
|
||||||
|
// also carries the shiftid, shiftname and status that `Login` returned, so
|
||||||
|
// this response is a superset of the old one and no client loses a field.
|
||||||
|
users.Post("/tenant/login", f.UserController.TenantLogin)
|
||||||
users.Get("/getusers", f.UserController.GetUserInfo)
|
users.Get("/getusers", f.UserController.GetUserInfo)
|
||||||
users.Post("/create", f.UserController.CreateUser)
|
users.Post("/create", f.UserController.CreateUser)
|
||||||
users.Put("/update", f.UserController.UpdateStaff)
|
users.Put("/update", f.UserController.UpdateStaff)
|
||||||
|
|||||||
@@ -51,7 +51,28 @@ func (s *userService) TenantLogin(user models.User) (models.TenantUserInfo, erro
|
|||||||
return models.TenantUserInfo{}, errors.New("user not found")
|
return models.TenantUserInfo{}, errors.New("user not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.repo.GetTenantUserByID(uid)
|
// `GetTenantUserById`, NOT `GetTenantUserByID`.
|
||||||
|
//
|
||||||
|
// The two differ by one letter and by twenty-eight columns. The capital-ID
|
||||||
|
// one selects five — userid, authname, contactno, tenantid, tenantname —
|
||||||
|
// so this function used to answer with a record whose name, branch, region
|
||||||
|
// and coordinates were all blank. That is why routing
|
||||||
|
// `/mob/users/tenant/login` at it was never as simple as swapping the
|
||||||
|
// handler: the app would have received a mostly-empty object.
|
||||||
|
//
|
||||||
|
// The lowercase-d one is the query `AppLogin` and `TenantWebLogin` already
|
||||||
|
// use, and it fills the whole record. It is now the only one anything calls.
|
||||||
|
//
|
||||||
|
// The FCM token is stored here rather than left to the repository, because
|
||||||
|
// the full read does not write. Only a real token is stored: a login that
|
||||||
|
// omits it must not wipe the device already registered, which is exactly
|
||||||
|
// what "userfcmtoken": "your_fcm_token_here" did to a live account during
|
||||||
|
// this investigation.
|
||||||
|
if strings.TrimSpace(user.Userfcmtoken) != "" {
|
||||||
|
_ = s.repo.UpdateUserFcmToken(uid, user.Userfcmtoken)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.repo.GetTenantUserById(uid), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *userService) UpdateStaff(user models.User) error {
|
func (s *userService) UpdateStaff(user models.User) error {
|
||||||
|
|||||||
Reference in New Issue
Block a user