Files
Agent-System/internal/archtest/boundaries.go
T
weichenandCursor f8b21ecd7c feat(app): add UnitOfWork and owner-bound repositories
Give each document command one postgres transaction and only let table owners unwrap the scope, so cross-owner writes can roll back together.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 13:54:27 +00:00

158 lines
3.6 KiB
Go

package archtest
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
"time"
"gopkg.in/yaml.v3"
)
const (
KindImport = "import"
KindSQLWrite = "sql_write"
KindPath = "path"
KindEvent = "event"
)
type Boundaries struct {
Imports map[string][]string `yaml:"imports"`
TableOwners map[string][]string `yaml:"table_owners"`
PathOwners map[string][]string `yaml:"path_owners"`
EventProducers map[string][]string `yaml:"event_producers"`
EventConsumers map[string][]string `yaml:"event_consumers"`
UnwrapOwners []string `yaml:"unwrap_owners"`
Exceptions []Exception `yaml:"exceptions"`
BaselineCounts map[string]int `yaml:"baseline_counts"`
}
type Exception struct {
Kind string `yaml:"kind"`
Package string `yaml:"package"`
File string `yaml:"file"`
Symbol string `yaml:"symbol"`
Owner string `yaml:"owner"`
Reason string `yaml:"reason"`
Milestone string `yaml:"milestone"`
Expires string `yaml:"expires"`
}
type Finding struct {
Kind string
Package string
File string
Symbol string
Detail string
}
func (f Finding) Key() string {
return f.Kind + "|" + f.Package + "|" + filepath.ToSlash(f.File) + "|" + f.Symbol
}
func ModuleRoot() (string, error) {
_, file, _, ok := runtime.Caller(0)
if !ok {
return "", fmt.Errorf("archtest: cannot locate caller")
}
dir := filepath.Dir(file)
for {
if _, err := os.Stat(filepath.Join(dir, "go.mod")); err == nil {
return dir, nil
}
parent := filepath.Dir(dir)
if parent == dir {
return "", fmt.Errorf("archtest: go.mod not found")
}
dir = parent
}
}
func LoadBoundaries(path string) (*Boundaries, error) {
b, err := os.ReadFile(path)
if err != nil {
return nil, err
}
var out Boundaries
if err := yaml.Unmarshal(b, &out); err != nil {
return nil, err
}
if out.Imports == nil {
out.Imports = map[string][]string{}
}
if out.TableOwners == nil {
out.TableOwners = map[string][]string{}
}
if out.PathOwners == nil {
out.PathOwners = map[string][]string{}
}
if out.EventProducers == nil {
out.EventProducers = map[string][]string{}
}
if out.EventConsumers == nil {
out.EventConsumers = map[string][]string{}
}
if out.UnwrapOwners == nil {
out.UnwrapOwners = []string{}
}
if out.BaselineCounts == nil {
out.BaselineCounts = map[string]int{}
}
return &out, nil
}
func DefaultBoundariesPath(root string) string {
return filepath.Join(root, ".doc", "system-design", "module-boundaries.yaml")
}
func allowedHas(list []string, needle string) bool {
for _, p := range list {
if strings.TrimSpace(p) == needle {
return true
}
}
return false
}
func (e Exception) validate(now time.Time) error {
if strings.TrimSpace(e.Owner) == "" {
return fmt.Errorf("missing owner")
}
if strings.TrimSpace(e.Reason) == "" {
return fmt.Errorf("missing reason")
}
if strings.TrimSpace(e.Milestone) == "" {
return fmt.Errorf("missing milestone")
}
if strings.TrimSpace(e.Expires) == "" {
return fmt.Errorf("missing expires")
}
day, err := time.ParseInLocation("2006-01-02", e.Expires, time.UTC)
if err != nil {
return fmt.Errorf("invalid expires %q", e.Expires)
}
// expires is inclusive through that calendar day (UTC).
if !now.UTC().Before(day.Add(24 * time.Hour)) {
return fmt.Errorf("expired on %s", e.Expires)
}
return nil
}
func (e Exception) matches(f Finding) bool {
if e.Kind != f.Kind {
return false
}
if e.Package != "" && e.Package != f.Package {
return false
}
if e.File != "" && filepath.ToSlash(e.File) != filepath.ToSlash(f.File) {
return false
}
if e.Symbol != "" && e.Symbol != f.Symbol {
return false
}
return true
}