Authoritative machine form of the GRAMMAR.md grammar: zddc.schema.json (draft 2020-12) describes every .zddc key with type, enum, description, and x-zddc-tier — "structure" (the project shape an end user shouldn't change: paths, worm, *_tool, views, available_tools, auto_own*, party_source, history*, records, acl, created_by) vs "option" (the blanks an operator fills: roles members, field_codes, convert, display, admins, title, planned dates). This is the contract a future .zddc form view uses to render option fields editable and structure fields read-only. Embedded (ZddcSchemaBytes) and served at GET /.api/zddc-schema for the client. Test locks the tier classification. Scope note: the schema uses $ref (recursive paths:) + patternProperties, which the in-tree internal/jsonschema validator doesn't support — so it drives the form/client now; wiring it as the SERVER validator (replacing validate.go's hand-rolled checks) needs a $ref-capable validator and is a separate decision. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
59 lines
1.7 KiB
Go
59 lines
1.7 KiB
Go
package zddc
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
)
|
|
|
|
// The embedded .zddc schema must be valid JSON, cover the grammar's keys, and
|
|
// tag every property structure|option — the contract the form view relies on.
|
|
func TestZddcSchemaTiers(t *testing.T) {
|
|
var doc struct {
|
|
Properties map[string]struct {
|
|
Tier string `json:"x-zddc-tier"`
|
|
} `json:"properties"`
|
|
}
|
|
if err := json.Unmarshal(ZddcSchemaBytes(), &doc); err != nil {
|
|
t.Fatalf("schema is not valid JSON: %v", err)
|
|
}
|
|
if len(doc.Properties) == 0 {
|
|
t.Fatal("schema has no properties")
|
|
}
|
|
|
|
// Every property carries a valid tier.
|
|
for name, p := range doc.Properties {
|
|
if p.Tier != "structure" && p.Tier != "option" {
|
|
t.Errorf("property %q has x-zddc-tier=%q, want structure|option", name, p.Tier)
|
|
}
|
|
}
|
|
|
|
// Spot-check the classification the form depends on.
|
|
wantTier := map[string]string{
|
|
"roles": "option", // who's in a group — the headline customisation
|
|
"field_codes": "option",
|
|
"convert": "option",
|
|
"display": "option",
|
|
"admins": "option",
|
|
"title": "option",
|
|
"paths": "structure", // the project shape
|
|
"worm": "structure",
|
|
"party_source": "structure",
|
|
"default_tool": "structure",
|
|
"available_tools": "structure",
|
|
"auto_own": "structure",
|
|
"acl": "structure",
|
|
"records": "structure",
|
|
"views": "structure",
|
|
"created_by": "structure",
|
|
}
|
|
for name, want := range wantTier {
|
|
p, ok := doc.Properties[name]
|
|
if !ok {
|
|
t.Errorf("schema missing expected key %q", name)
|
|
continue
|
|
}
|
|
if p.Tier != want {
|
|
t.Errorf("key %q tier=%q, want %q", name, p.Tier, want)
|
|
}
|
|
}
|
|
}
|