From 8cc567c89b2eecf64b2555b9032a14528e21aec0 Mon Sep 17 00:00:00 2001 From: abhishek Date: Fri, 11 Sep 2026 11:10:25 +0530 Subject: [PATCH] daily merchant app login fix --- models/users.go | 7 +++++++ repositories/userRepository.go | 25 ++++++++++++------------- routes/userroutes.go | 7 ++++++- services/userService.go | 23 ++++++++++++++++++++++- 4 files changed, 47 insertions(+), 15 deletions(-) diff --git a/models/users.go b/models/users.go index a920bd0..08e71b6 100644 --- a/models/users.go +++ b/models/users.go @@ -101,4 +101,11 @@ type TenantUserInfo struct { Categoryname string `json:"categoryname"` Subcategoryid int `json:"subcategoryid"` 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"` } diff --git a/repositories/userRepository.go b/repositories/userRepository.go index 4af398a..bbe84ed 100644 --- a/repositories/userRepository.go +++ b/repositories/userRepository.go @@ -14,7 +14,6 @@ type UserRepository interface { GetUserByID(uid int) (models.UserInfo, error) Login(user models.User) (models.UserInfo, error) FindUserID(authname, contactno string, configid int) (int, error) - GetTenantUserByID(userid int) (models.TenantUserInfo, error) UpdateStaff(user models.User) error GetUserByAuthname(authname 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 } -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 { 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 } +// 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 { 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.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, - 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 LEFT JOIN tenants b ON a.tenantid=b.tenantid LEFT JOIN app_location c on c.applocationid=b.applocationid LEFT JOIN app_category d ON b.categoryid=d.categoryid LEFT JOIN tenantlocations e ON a.locationid=e.locationid + LEFT JOIN ridershifts f ON a.shiftid = f.shiftid WHERE a.userid = ? ` diff --git a/routes/userroutes.go b/routes/userroutes.go index 7487158..5c58107 100644 --- a/routes/userroutes.go +++ b/routes/userroutes.go @@ -18,7 +18,12 @@ func RegisterUserRoutes(api fiber.Router, f *facade.Facade) { users.Delete("/delete", f.UserController.DeleteUser) 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.Post("/create", f.UserController.CreateUser) users.Put("/update", f.UserController.UpdateStaff) diff --git a/services/userService.go b/services/userService.go index 3a8589d..dcd3a40 100644 --- a/services/userService.go +++ b/services/userService.go @@ -51,7 +51,28 @@ func (s *userService) TenantLogin(user models.User) (models.TenantUserInfo, erro 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 {