Files
krow_backend/go-api/internal/orgctx/orgctx.go
2026-08-24 13:06:29 +05:30

53 lines
1.8 KiB
Go

// Package orgctx carries the organization a request operates on.
//
// Phase 2C has no authentication, so there is nothing to derive a tenant from.
// Rather than defaulting org_id deep inside the SQL — where it would have to be
// unpicked from fourteen repositories once auth arrives — the value is put on
// the request context by one middleware and threaded explicitly through the
// service and repository boundaries.
//
// When authentication lands, DevMiddleware is replaced by one that reads the
// organization off the authenticated session. Nothing below this package
// changes: every caller already takes an org id as a parameter.
package orgctx
import (
"context"
"errors"
)
type key struct{}
// DevOrgSlug identifies the single organization every Phase 2C request runs as.
// The seeder creates it; nothing else does.
//
// THIS IS NOT AUTHENTICATION. It is a fixed development identity with no
// credential, no session and no verification behind it.
const DevOrgSlug = "krow-dev"
// DevOrgName is that organization's display name.
const DevOrgName = "Krow Development"
// ErrNoOrg means the context reached a scoped operation without an organization,
// which is a programming error rather than a client one.
var ErrNoOrg = errors.New("no organization in context")
// With returns a context carrying an organization id.
func With(ctx context.Context, orgID string) context.Context {
return context.WithValue(ctx, key{}, orgID)
}
// From reads the organization id, reporting whether one was present.
func From(ctx context.Context) (string, bool) {
v, ok := ctx.Value(key{}).(string)
return v, ok && v != ""
}
// MustFrom reads the organization id or returns ErrNoOrg.
func MustFrom(ctx context.Context) (string, error) {
if v, ok := From(ctx); ok {
return v, nil
}
return "", ErrNoOrg
}