Let an admin create till staff from the console, through the same code
An admin sets a shop up from a browser; a supervisor adds a cashier at the counter. Both had to be possible, and only the second one was. So the console gets createposuser / updateposuser / getposusers / deleteposuser, under both /v1/web/tenants and /v1/mob/tenants — calling the same service methods `/pos/users` calls. Not a parallel implementation: a supervisor created from a browser is the same row, with the same PIN rules, the same duplicate check and the same identity-column allocation, as one created at a till. Two paths writing one table is precisely how the two stop matching, and this codebase already had that happen once. configid is inferred rather than asked for. It is a number nobody looks up, it varies per tenant — 1087's accounts are spread across 1, 6 and 15 — and getting it wrong creates somebody who cannot sign into the portal their colleagues use and is invisible to half the platform's queries. /posroles is served rather than left to the console to hardcode. A console that knew supervisor was 7 would be wrong the day that changed and would have no way to find out. The outlet is the real difference between the two doors. A terminal proves it with a signed token; the console asserts it, and is checked against the tenant before anything is written. That is weaker, and it is worth being plain about: these mint till credentials on an unauthenticated request, exactly like every other route in the /v1/web and /v1/mob groups, because there is no auth middleware on the web API at all. Documented as the weakest point in the design and flagged to move behind a session guard once the console can hold one. The terminal routes are untouched by it. Proven in a rolled-back transaction against live data: the console creates a supervisor at 1135, that supervisor signs in by PIN with can_manage_staff true, the till's /pos/staff sees them alongside the two created at the counter, and 0451, 1234 and a duplicate PIN are each refused with the same message the terminal gives. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -48,6 +48,10 @@ type PosService interface {
|
||||
// LoginWithPin signs a person in at a terminal that is already open. Never
|
||||
// reachable anonymously — four digits is not a barrier on its own.
|
||||
LoginWithPin(tenantID, locationID int, pin string) (*models.PosSession, error)
|
||||
|
||||
// ConfigidFor infers which portal a tenant's people belong to, so the console
|
||||
// is never asked for a number nobody can look up.
|
||||
ConfigidFor(tenantID int) int
|
||||
}
|
||||
|
||||
type posService struct {
|
||||
@@ -168,3 +172,7 @@ func (s *posService) LoginWithPin(tenantID, locationID int, pin string) (*models
|
||||
}
|
||||
return s.mint(session, "")
|
||||
}
|
||||
|
||||
func (s *posService) ConfigidFor(tenantID int) int {
|
||||
return s.repo.PosConfigidFor(tenantID)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user