package services import ( "errors" "strings" ) // What a person may change about their OWN account. // // Deliberately short, and short for a reason. `app_users` carries the columns // that decide what somebody is allowed to do — `roleid`, `locationid`, // `tenantid`, `status`, `password`, `pin` — beside the ones that merely say who // they are. `PUT /users/update` writes whatever struct it is handed and checks // only `userid`, so before this a self-service profile form would have let a // branch user promote themselves, move to another shop, or reactivate a // disabled account. // // Identity here, authorisation elsewhere. Moving somebody between branches is // AssignStaffToBranch, and it is the store admin's call — which is the whole // point of the hiring order: who runs a shop is decided by the merchant, not by // the person who works there. var editableOwnFields = map[string]bool{ "firstname": true, "lastname": true, "contactno": true, "email": true, } // OwnProfileUpdate reduces a request to the fields a person owns about // themselves. // // Errors when nothing survives rather than reporting a successful write of // nothing: somebody who changed only their role would otherwise be told it // saved. func OwnProfileUpdate(fields map[string]any) (map[string]any, error) { clean := make(map[string]any, len(fields)) for key, value := range fields { lower := strings.ToLower(strings.TrimSpace(key)) if !editableOwnFields[lower] { continue } // Blank means "not supplied". A profile form posts every field it // renders, so honouring blanks would let one save wipe a mobile number // the person never touched. if text, ok := value.(string); ok && strings.TrimSpace(text) == "" { continue } clean[lower] = value } if len(clean) == 0 { return nil, errors.New("nothing to update — no editable field was supplied") } return clean, nil }