Tier: Starter · Status: Full · Java original:
firefly-backoffice· .NET project:FireflyFramework.BackOffice
backoffice composes starterapplication
with back-office context middleware that requires every request
to carry the canonical operator headers:
| Header | Purpose |
|---|---|
X-BackOffice-Branch |
Branch / tenant identifier the operator is scoped to |
X-BackOffice-Operator |
The operator's stable user id |
Both must be present; the middleware emits a 400
application/problem+json response when either is missing. Successful
requests have the values stored on the context and exposed via
backoffice.Branch(ctx) / backoffice.Operator(ctx).
const HeaderBranch = "X-BackOffice-Branch"
const HeaderOperator = "X-BackOffice-Operator"
func Branch(ctx) (string, bool)
func Operator(ctx) (string, bool)
func Middleware(next http.Handler) http.Handler
type BackOffice struct {
*starterapplication.Application
}
func New(cfg startercore.Config) *BackOffice
func (*BackOffice) MiddlewareChain() func(http.Handler) http.HandlerMiddlewareChain() returns Core.Middleware() composed with the
back-office middleware as the innermost layer — apply it once and
every handler gets problem rendering, correlation, idempotency, AND
the back-office guard.
import (
"net/http"
"github.com/fireflyframework/fireflyframework-go/backoffice"
"github.com/fireflyframework/fireflyframework-go/startercore"
)
bo := backoffice.New(startercore.Config{AppName: "loan-bo"})
mux := http.NewServeMux()
mux.HandleFunc("GET /admin/loans", func(w http.ResponseWriter, r *http.Request) {
branch, _ := backoffice.Branch(r.Context())
operator, _ := backoffice.Operator(r.Context())
log.Printf("op %s @ branch %s listing loans", operator, branch)
// … domain logic …
})
http.ListenAndServe(":8080", bo.MiddlewareChain()(mux))A request without both headers receives:
400 Bad Request
Content-Type: application/problem+json
{"type":"https://fireflyframework.org/problems/bad-request",
"title":"Bad Request","status":400,"detail":"missing back-office headers"}
cd backoffice
go test ./...Covers missing-headers 400, both-headers happy path with context propagation, and pre-merged middleware chain ordering.