Files
mesh-delivery/modules/mesh-delivery-indexer/internal/index/domain.go
T

76 lines
3.5 KiB
Go

package index
// Where a seat of the mesh's own contracts may be defined (novox/hq ADR 0636 §5, ADR 0634 §7): a definition names its
// glossary domain; the indexer accepts a seat of the mesh's own contracts only from that domain's contracts module
// (mesh-<domain>-contracts), or from mesh-contracts for a domain with none. A second definer is refused with a finding
// naming both. A definition moving from mesh-contracts to its domain's contracts module is a handover: the new
// definer takes the seat over whichever trunk merges first, and a removal from the module that is not the seat's
// domain's keeps the last trunk definition until the domain's module defines it.
import (
"encoding/json"
"fmt"
"slices"
"strings"
"git.novox.be/novox/mesh-sdk/go/seatdef"
)
// fallbackContracts is the mesh's contracts module for a domain with no contracts module of its own.
const fallbackContracts = "mesh-contracts"
// domainsWithContracts are the domains whose seats have a contracts module of their own (ADR 0634 §7): the six
// the milestone creates. Every other domain's seats are defined in fallbackContracts.
var domainsWithContracts = []string{"Delivery", "Provisioning", "Identity and access", "Health and repair",
"Connectivity", "Operator and conversation"}
// domainContracts is the module that defines a domain's seats: mesh-<domain>-contracts, the heading lowercased with
// its spaces as dashes, or fallbackContracts for a domain with none.
func domainContracts(domain string) string {
if !slices.Contains(domainsWithContracts, domain) {
return fallbackContracts
}
return "mesh-" + strings.ReplaceAll(strings.ToLower(domain), " ", "-") + "-contracts"
}
// ownContracts says a contracts module is one of the mesh's own: fallbackContracts or a domain's.
func ownContracts(module string) bool {
return module == fallbackContracts || slices.ContainsFunc(seatdef.Domains, func(d string) bool {
return module == domainContracts(d) && module != fallbackContracts
})
}
// domainRefusal is, for a definition a contracts module of the mesh's own holds, why it may not: the words naming the
// module and the domain's. Empty when the module may define the seat (a module outside the mesh's own contracts defines
// what it likes, ADR 0625 §7).
func domainRefusal(module string, d seatdef.Definition) string {
if !ownContracts(module) {
return ""
}
if want := domainContracts(d.Domain); want != module {
return fmt.Sprintf("it is a seat of the domain %q, whose seats %s defines, and %s defines it", d.Domain, want, module)
}
return ""
}
// domainOf is the domain a kept definition names ("" when it is none or does not decode).
func domainOf(raw json.RawMessage) string {
var d struct {
Domain string `json:"domain"`
}
_ = json.Unmarshal(raw, &d)
return d.Domain
}
// handsOver says a kept trunk entry is handed over to a definer: the entry is held by a module of the mesh's own
// that is not the seat's domain's, and the definer is the seat's domain's contracts module.
func handsOver(cur SeatDefinitionEntry, module string, d seatdef.Definition) bool {
return cur.Module != module && ownContracts(cur.Module) && domainContracts(d.Domain) == module
}
// handoverPending says a trunk entry its holder no longer defines waits for its domain's module: the holder is a
// module of the mesh's own and not the seat's domain's, so the last trunk definition stays until that module defines it.
func handoverPending(cur SeatDefinitionEntry) bool {
return ownContracts(cur.Module) && domainContracts(domainOf(cur.Definition)) != cur.Module
}