package server import ( "strconv" "strings" "git.lohmar.co.uk/cclohmar/NextMyDay/internal/core/routing" "git.lohmar.co.uk/cclohmar/NextMyDay/internal/core/users" ) // RequestContext is the in-process hand-over from the door to a module function // (SPEC-003 §5, D-003). It carries IDENTIFICATION, never a credential — the // Principal and the session cookie are separate concerns (D-001). // // Field names match the GMS `X-*-*` headers so a future process split is // mechanical (D-003). type RequestContext struct { // Workflow is the PARAM1 classification: a reserved workflow ("home", // "access", …) or the resolved GUID. Workflow string // UserID is the resolved user (0 when anonymous). UserID int64 // Principal is "user:" — IDENTIFICATION only, never a credential. Principal string // Function is the resolved module function / action. Function string // Page is the joined path remainder handed to the function. Page string // Correlation is the request's correlation id. Correlation string // ClientIP is the resolved client IP. ClientIP string // Location is IP-derived and AUDIT ONLY (D-031) — no tracking. Location string } // newRequestContext builds the hand-over from a resolution. func newRequestContext(res routing.Resolution, userID int64, correlation, clientIP string) *RequestContext { principal := "anonymous" if userID != 0 { principal = "user:" + strconv.FormatInt(userID, 10) } return &RequestContext{ Workflow: res.Workflow, UserID: userID, Principal: principal, Function: res.Function, Page: strings.Join(res.Params, "/"), Correlation: correlation, ClientIP: clientIP, } } // RoleGate decides whether an authenticated user's role may call a given // (module, function) (SPEC-003 §4 step 5d). // // SPEC-003 does not fix the policy — that is SPEC-007/SPEC-008. The door // enforces the gate; the default implementation admits any authenticated user // (the tier model ripples down, D-034). type RoleGate interface { Allowed(role users.Role, module, function string) bool } // AllowAuthenticated is the default RoleGate: every authenticated user may call // every registered function. The one-admin and role-above rules are enforced by // the users service; per-module authorisation arrives with SPEC-007/008. type AllowAuthenticated struct{} // Allowed implements RoleGate. func (AllowAuthenticated) Allowed(users.Role, string, string) bool { return true }