apicontract

package
v0.28.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 12, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package apicontract holds the Go types for every shared JSON type and envelope in the core-investigation-loop Feature's normative transport appendix (spec/features/core-investigation-loop/api-contract.md, hub datatug/datatug), with the exact json:"..." field names that document declares - the schema authority datatug-cli (server) and datatug-apps (client) consume, per Phase 1 corrective Task 12.

Every type's Validate method enforces the appendix's own stated rules - required fields, closed enums, cross-field pairings, canonical string forms - so a value that unmarshals successfully but violates the contract is still caught before it crosses a trust boundary. TypedValue and Scope's carrying types additionally reject unknown fields, duplicate JSON keys and (via DecodeStrict) explicitly named security-relevant fields such as a client-supplied principal or role.

pkg/apicontract/fixtures holds the frozen JSON fixtures generated from these types - one file per envelope/error case the appendix's "Acceptance and migration" section requires coverage for.

Every POST endpoint in the appendix's "Endpoint table" has a request envelope type here: ExecutionRequest (exec/run_query), ApplicableRequest (queries/applicable), RelatedRequest (semantic/related) and RelatedRowsRequest (semantic/related/rows). Each flattens its Scope fields (project/environment/securityContextId) into its own top level, never nesting them under a "scope" key - confirmed against the live server (Task 12 lane S77).

Index

Constants

View Source
const (
	BindingOriginSelection = "selection"
	BindingOriginContext   = "context"
	BindingOriginManual    = "manual"
	BindingOriginDefault   = "default"
)
View Source
const (
	BindingOriginEvidenceServerDefault  = "server-default"
	BindingOriginEvidenceClientReported = "client-reported"
)
View Source
const (
	CandidateStateRunnable          = "runnable"
	CandidateStateNeedsInput        = "needs-input"
	CandidateStateNeedsTarget       = "needs-target"
	CandidateStateSourceUnavailable = "source-unavailable"
)
View Source
const (
	FactOriginSelection = "selection"
	FactOriginContext   = "context"
	FactOriginManual    = "manual"
)
View Source
const (
	FactMappingDeclared = "declared"
	FactMappingInferred = "inferred"
)
View Source
const (
	SemanticProvenanceDeclared = "declared"
	SemanticProvenanceInferred = "inferred"
)
View Source
const (
	ProvenanceModeLive     = "live"
	ProvenanceModeSnapshot = "snapshot"
)
View Source
const (
	ExecutionProfileProtected        = "protected"
	ExecutionProfileOpaquePrivileged = "opaque-privileged"
)

Variables

This section is empty.

Functions

func CanonicalQueryID added in v0.28.1

func CanonicalQueryID(folderPath, id string) string

CanonicalQueryID returns the folder-qualified query ID for a query with bare id under folderPath ("" for the queries root).

func DecodeStrict

func DecodeStrict(data []byte, v any, forbidden ...string) error

DecodeStrict decodes data into v with no leniency: unknown JSON fields are rejected (encoding/json's DisallowUnknownFields), duplicate keys at any nesting level are rejected (encoding/json silently keeps only the last occurrence otherwise - the appendix requires duplicate JSON keys to be "rejected, never reconciled by precedence") - including two spellings of one struct field that differ only in case ("project" and "Project"), which encoding/json matches to the same field - trailing data after the JSON value is rejected, and any field name listed in forbidden is rejected even when the target type has no field for it - the same "client-supplied principal or role are rejected" rule the appendix states, made explicit at every call site that carries security-relevant identity.

Types

type AgentCapabilities

type AgentCapabilities struct {
	ProtectedQueries bool `json:"protectedQueries"`
	OpaqueReadOnly   bool `json:"opaqueReadOnly"`
}

AgentCapabilities reports what the session may do - never what it did; Result.Provenance.ExecutionProfile reports the actual executor used for a given run, "even a privileged principal running protected DTQL still receives protected provenance".

type AgentInfo

type AgentInfo struct {
	Version           string            `json:"version"`
	Principal         AgentPrincipal    `json:"principal"`
	SecurityContextID string            `json:"securityContextId"`
	Projects          []AgentProjectRef `json:"projects"`
	Capabilities      AgentCapabilities `json:"capabilities"`
}

AgentInfo is the exact success envelope of GET agent-info. api-contract.md "Endpoint table".

func (AgentInfo) Validate

func (a AgentInfo) Validate() error

Validate enforces Version and SecurityContextID are required, Principal is itself valid, and every Projects entry is itself valid.

type AgentPrincipal

type AgentPrincipal struct {
	ID     string   `json:"id"`
	Roles  []string `json:"roles"`
	Groups []string `json:"groups"`
}

AgentPrincipal is the effective identity agent-info reports - never the role inferred from a name; the server states it explicitly.

func (AgentPrincipal) Validate

func (p AgentPrincipal) Validate() error

type AgentProjectRef

type AgentProjectRef struct {
	ID string `json:"id"`
}

AgentProjectRef is one project agent-info reports as registered.

func (AgentProjectRef) Validate

func (r AgentProjectRef) Validate() error

type Ambiguous

type Ambiguous struct {
	ParameterID string   `json:"parameterId"`
	FactIDs     []string `json:"factIds"`
}

Ambiguous names a parameter with more than one distinct candidate value within the highest eligible automatic binding tier.

func (Ambiguous) Validate

func (a Ambiguous) Validate() error

type ApplicableRequest added in v0.27.0

type ApplicableRequest struct {
	Project           string `json:"project"`
	Environment       string `json:"environment"`
	SecurityContextID string `json:"securityContextId"`
	Values            []Fact `json:"values"`
}

ApplicableRequest is POST queries/applicable's request body: "Scope + {values:Fact[]}" - api-contract.md "Endpoint table". Scope's three fields are flattened into the top level of the JSON body, exactly like ExecutionRequest, never nested under a "scope" key - confirmed against the live server (Task 12 lane S77).

func (ApplicableRequest) Validate added in v0.27.0

func (r ApplicableRequest) Validate() error

Validate enforces Project/Environment/SecurityContextID are required (the same Scope invariants every scoped call carries - api-contract.md "Scope and identity") and every Values entry is itself valid. An empty Values list is legitimate: a caller with no known facts still gets back every query's notYet candidate.

type ApplicableResponse

type ApplicableResponse struct {
	Applicable []Candidate `json:"applicable"`
	NotYet     []Candidate `json:"notYet"`
}

ApplicableResponse is the exact success envelope of POST queries/applicable. "applicable contains only runnable candidates. notYet contains authorized query metadata for needs-input/needs-target/ source-unavailable candidates... Candidates sort by queryId for deterministic tests." api-contract.md "Endpoint table".

func (ApplicableResponse) Validate

func (r ApplicableResponse) Validate() error

Validate enforces every candidate is itself valid, every Applicable entry has State "runnable", every NotYet entry does not, and both slices are sorted by QueryID.

type Binding

type Binding struct {
	ParameterID    string     `json:"parameterId"`
	Value          TypedValue `json:"value"`
	Origin         string     `json:"origin"`         // selection | context | manual | default
	OriginEvidence string     `json:"originEvidence"` // server-default | client-reported
	FactID         string     `json:"factId,omitempty"`
}

Binding is one parameter's resolved value and its provenance. Returned bindings are execution-confirmed; a selection/context/manual origin's OriginEvidence remains explicitly "client-reported", never presented as server-attested; "server-default" is used only when a declared default was validated against the query definition. api-contract.md "Shared JSON types" / "Endpoint table".

func (Binding) Validate

func (b Binding) Validate() error

Validate enforces ParameterID is required, Value is itself valid, Origin and OriginEvidence are each one of their closed sets, and the two pair correctly: Origin "default" only with OriginEvidence "server-default", every other Origin only with "client-reported" - "The UI must not present client origins as server-attested provenance."

type BindingOriginEntry

type BindingOriginEntry struct {
	ParameterID string `json:"parameterId"`
	Origin      string `json:"origin"` // selection | context | manual | default
	FactID      string `json:"factId,omitempty"`
}

BindingOriginEntry supplies display provenance for one submitted parameter - "never influences authorization". api-contract.md "Endpoint table".

func (BindingOriginEntry) Validate

func (e BindingOriginEntry) Validate() error

type Candidate

type Candidate struct {
	QueryID string            `json:"queryId"`
	Targets []CandidateTarget `json:"targets"`
	// SelectedSource is present only when exactly one eligible target
	// remains - "present only when one eligible target remains".
	SelectedSource string      `json:"selectedSource,omitempty"`
	Bindings       []Binding   `json:"bindings"`
	Chain          []ChainStep `json:"chain"`
	Missing        []string    `json:"missing"`
	Ambiguous      []Ambiguous `json:"ambiguous"`
	State          string      `json:"state"`
}

Candidate is one query's runnability against the caller's current facts: its authorized eligible targets, the bindings/chain it would apply, what is still missing or ambiguous, and its overall State. api-contract.md "Endpoint table".

func (Candidate) Validate

func (c Candidate) Validate() error

Validate enforces QueryID is required, every Target/Binding/ChainStep/ Ambiguous entry is itself valid, SelectedSource is set only when there is exactly one Target, and State is one of the closed set.

type CandidateTarget

type CandidateTarget struct {
	Source string `json:"source"`
	Label  string `json:"label"`
}

CandidateTarget is one authorized eligible source a saved query could run against.

func (CandidateTarget) Validate

func (t CandidateTarget) Validate() error

type CaptureBindingOrigin added in v0.28.1

type CaptureBindingOrigin struct {
	ParameterID string `json:"parameterId"`
	Origin      string `json:"origin"` // selection | context | manual
}

CaptureBindingOrigin records how one parameter was bound while the user explored. It is client-reported provenance, never server-attested, and carries no value and no fact ID.

func (CaptureBindingOrigin) Validate added in v0.28.1

func (b CaptureBindingOrigin) Validate() error

Validate enforces a required ParameterID and an origin of selection, context or manual - a default value is never captured, so "default" is not a capture origin.

type CaptureProvenance added in v0.28.1

type CaptureProvenance struct {
	// Author is the serving principal; omitted when the server runs with no
	// identified principal.
	Author string `json:"author,omitempty"`
	// Environment is the environment the source was resolved in.
	Environment string `json:"environment"`
	// Collection is the collection the query reads, derived from the DTQL.
	Collection string `json:"collection"`
}

CaptureProvenance is what the server itself recorded about a capture.

type CaptureQueryRequest added in v0.28.1

type CaptureQueryRequest struct {
	Project           string        `json:"project"`
	Environment       string        `json:"environment"`
	SecurityContextID string        `json:"securityContextId"`
	IfNoneMatch       bool          `json:"ifNoneMatch,omitempty"`
	IfMatch           string        `json:"ifMatch,omitempty"`
	Query             CapturedQuery `json:"query"`
}

CaptureQueryRequest is POST queries/capture's request body. Like every other POST envelope here it flattens Scope into its own top level.

func (CaptureQueryRequest) Validate added in v0.28.1

func (r CaptureQueryRequest) Validate() error

Validate enforces Scope's required fields, exactly one of IfNoneMatch or IfMatch, and the query's own rules (CapturedQuery.Validate), reporting a query field as "query.<field>".

type CaptureQueryResponse added in v0.28.1

type CaptureQueryResponse struct {
	// QueryID is the stored query's canonical, folder-qualified ID
	// (CanonicalQueryID) - the queryId exec/run_query and
	// queries/applicable use.
	QueryID string `json:"queryId"`
	// Revision identifies the stored bytes; send it back as IfMatch to
	// replace this exact revision. Opaque: compare for equality only.
	Revision   string            `json:"revision"`
	Query      CapturedQuery     `json:"query"`
	Provenance CaptureProvenance `json:"provenance"`
}

CaptureQueryResponse is POST queries/capture's success envelope, sent only after the store has persisted the pair.

func (CaptureQueryResponse) Validate added in v0.28.1

func (r CaptureQueryResponse) Validate() error

Validate enforces QueryID and Revision are present, QueryID is the query's own canonical ID, the query is itself valid and the provenance names its environment and collection.

type CapturedParameter added in v0.28.1

type CapturedParameter struct {
	ID         string          `json:"id"`
	Type       string          `json:"type"` // string | number | integer | decimal | boolean | date | datetime
	Title      string          `json:"title,omitempty"`
	IsRequired bool            `json:"isRequired"`
	Meta       *EntityFieldRef `json:"meta,omitempty"`
}

CapturedParameter is one typed parameter of a captured query. It has no default value: a captured default would persist a possibly protected value into git-tracked project files.

func (CapturedParameter) Validate added in v0.28.1

func (p CapturedParameter) Validate() error

Validate enforces a required ID, a type from the closed set and, when Meta is present, both its entity and field.

type CapturedQuery added in v0.28.1

type CapturedQuery struct {
	// FolderPath is the "/"-separated folder under the project's queries/
	// root; "" is the root itself.
	FolderPath string `json:"folderPath"`
	// ID is the query's bare ID: one file-name segment.
	ID      string `json:"id"`
	Title   string `json:"title"`
	Purpose string `json:"purpose"`
	// Source is the stable project-local source ID (SourceRef.source) the
	// captured lookup read; the server resolves it through the project
	// registry and binds the saved query to it.
	Source string `json:"source"`
	// DTQL is the query text persisted as "<id>.query.dtql".
	DTQL           string                 `json:"dtql"`
	Parameters     []CapturedParameter    `json:"parameters"`
	BindingOrigins []CaptureBindingOrigin `json:"bindingOrigins"`
}

CapturedQuery is the persisted definition of a captured query, as the client submits it and as the server returns it once stored.

func (CapturedQuery) Validate added in v0.28.1

func (q CapturedQuery) Validate() error

Validate enforces the shape rules both server and client apply: ID is one path segment and FolderPath is "" or "/"-separated segments, none empty, "." or ".." and none holding a backslash or NUL (the server applies its stricter file-name rules on top); Title, Purpose, Source and DTQL are required; every parameter has a unique ID, a type from the closed set and, when present, a complete Meta; every binding origin names a declared parameter at most once with origin selection, context or manual.

type ChainStep

type ChainStep struct {
	ParameterID string `json:"parameterId"`
	FactID      string `json:"factId,omitempty"`
	Explanation string `json:"explanation"`
}

ChainStep explains, per parameter, how its value was (or would be) derived - declared, inferred or manual - distinctly. "a missing parameter still has an explanation."

func (ChainStep) Validate

func (c ChainStep) Validate() error

type Column

type Column struct {
	Name string `json:"name"`
	Type string `json:"type"`
}

Column names one recordset column and its declared type.

func (Column) Validate

func (c Column) Validate() error

type EntityFieldRef added in v0.28.1

type EntityFieldRef struct {
	Entity string `json:"entity"`
	Field  string `json:"field"`
}

EntityFieldRef is a semantic parameter's declaration that it requires a value of one entity field ("requires Customer.ID") - datatug-core's ParameterDef.Meta on the wire.

type ErrorBody

type ErrorBody struct {
	Code      string         `json:"code"`
	Message   string         `json:"message"`
	Field     string         `json:"field,omitempty"`
	RequestID string         `json:"requestId"`
	Targets   []TargetOption `json:"targets,omitempty"`
}

ErrorBody is the exact shape of every error's "error" field. "Messages and IDs must not reveal protected values or credentials. Tests assert both status and code, not English wording." api-contract.md "Security and errors".

func (ErrorBody) Validate

func (e ErrorBody) Validate() error

Validate enforces Code is one of the closed ErrorCode set, Message and RequestID are required, and Targets is populated only when Code is TARGET_REQUIRED - "Only TARGET_REQUIRED may include authorized target options."

type ErrorCode

type ErrorCode string

ErrorCode is the closed set of error codes api-contract.md "Security and errors" declares, each mapped to its exact HTTP status.

const (
	ErrCodeInvalidRequest                ErrorCode = "INVALID_REQUEST"
	ErrCodeTypeMismatch                  ErrorCode = "TYPE_MISMATCH"
	ErrCodeMissingParameter              ErrorCode = "MISSING_PARAMETER"
	ErrCodeAmbiguousBinding              ErrorCode = "AMBIGUOUS_BINDING"
	ErrCodeTargetRequired                ErrorCode = "TARGET_REQUIRED"
	ErrCodeUnauthenticated               ErrorCode = "UNAUTHENTICATED"
	ErrCodeAccessDenied                  ErrorCode = "ACCESS_DENIED"
	ErrCodeUnsupportedProtectedExecution ErrorCode = "UNSUPPORTED_PROTECTED_EXECUTION"
	ErrCodeNotFound                      ErrorCode = "NOT_FOUND"
	ErrCodeStaleContext                  ErrorCode = "STALE_CONTEXT"
	ErrCodeResponseTooLarge              ErrorCode = "RESPONSE_TOO_LARGE"
	ErrCodeSourceUnavailable             ErrorCode = "SOURCE_UNAVAILABLE"
	ErrCodeTimeout                       ErrorCode = "TIMEOUT"
	// ErrCodeRevisionConflict (409) refuses a project write whose
	// optimistic-concurrency condition failed: a create (ifNoneMatch) found
	// something already stored at the location, or an update (ifMatch) named
	// a revision that is no longer current. Nothing was written. It is
	// distinct from STALE_CONTEXT, which means the caller's securityContextId
	// is stale and is recovered by calling agent-info again - retrying a
	// stale revision that way would never succeed. Lead assumption
	// 2026-09-11 (Phase 2 task 2, queries/capture), pending an amendment of
	// api-contract.md's closed code set.
	ErrCodeRevisionConflict ErrorCode = "REVISION_CONFLICT"
)

func (ErrorCode) HTTPStatus

func (c ErrorCode) HTTPStatus() int

HTTPStatus returns c's exact HTTP status, or 0 for an unknown code.

func (ErrorCode) Valid

func (c ErrorCode) Valid() bool

Valid reports whether c is one of the closed set of error codes.

type ErrorEnvelope

type ErrorEnvelope struct {
	Error ErrorBody `json:"error"`
}

ErrorEnvelope is the exact shape of every error response. "{error:{code:string,message:string,field?:string,requestId:string, targets?:{source:string,label:string}[]}}" api-contract.md "Security and errors".

func (ErrorEnvelope) Validate

func (e ErrorEnvelope) Validate() error

type ExecutionRequest

type ExecutionRequest struct {
	Project           string                `json:"project"`
	Environment       string                `json:"environment"`
	SecurityContextID string                `json:"securityContextId"`
	Source            string                `json:"source,omitempty"`
	QueryID           string                `json:"queryId,omitempty"`
	DTQL              string                `json:"dtql,omitempty"`
	Parameters        map[string]TypedValue `json:"parameters"`
	BindingOrigins    []BindingOriginEntry  `json:"bindingOrigins"`
	Mode              string                `json:"mode"` // live | snapshot
	SnapshotID        string                `json:"snapshotId,omitempty"`
	Limit             *int                  `json:"limit,omitempty"`
}

ExecutionRequest is POST exec/run_query's request body. "For ad-hoc DTQL, source is required. For saved queries, source obeys target resolution... Unknown parameters and type mismatches are rejected. The server never silently binds from stored browser context." api-contract.md "Endpoint table".

func (ExecutionRequest) Validate

func (r ExecutionRequest) Validate() error

Validate enforces: Project/Environment/SecurityContextID required; exactly one of QueryID/DTQL ("exactly one required"); DTQL set requires Source ("For ad-hoc DTQL, source is required"); every Parameters value is itself valid; BindingOrigins is checked for exactly the submitted Parameters keys - no more, no fewer - and each entry is itself valid; Mode is one of the closed set, snapshot Mode requires a SnapshotID; Limit, when present, is within (0, 500] - "Default result limit is 100 and maximum is 500."

type Fact

type Fact struct {
	ID       string       `json:"id"`
	Entity   string       `json:"entity"`
	Field    string       `json:"field"`
	Value    TypedValue   `json:"value"`
	Origin   string       `json:"origin"` // selection | context | manual
	Physical *PhysicalRef `json:"physical,omitempty"`
	Mapping  string       `json:"mapping,omitempty"` // declared | inferred
	Enabled  bool         `json:"enabled"`
}

Fact is a semantic suggestion, not an access credential - the server revalidates physical references and mapping declarations against authorized project metadata. Manual facts cannot impersonate a selected protected record. api-contract.md "Shared JSON types".

func (Fact) Validate

func (f Fact) Validate() error

Validate enforces id/entity/field are required, Value is itself valid, Origin is one of the closed set, Physical (when present) is itself valid, and Mapping (when present) is one of the closed set.

type Limitation

type Limitation struct {
	Policy        string   `json:"policy"`
	RowsFiltered  bool     `json:"rowsFiltered"`
	HiddenColumns []string `json:"hiddenColumns"`
}

Limitation reports an applied restriction, not the number of rejected rows or their values. Only names visible in authorized metadata may appear in HiddenColumns or Policy; use a generic policy label and an empty HiddenColumns where names are protected. api-contract.md "Shared JSON types" / "Limitations report applied restrictions...".

func (Limitation) Validate

func (l Limitation) Validate() error

Validate enforces Policy is required - a limitation with no named policy cannot be attributed to a rule, and the appendix requires attribution ("never silent, always attributable to a named rule").

type PhysicalRef

type PhysicalRef struct {
	Source     string `json:"source"`
	Collection string `json:"collection"`
	Column     string `json:"column"`
}

PhysicalRef names a physical column a semantic mapping points at. "PhysicalRef = {source: string; collection: string; column: string}" - api-contract.md "Shared JSON types".

func (PhysicalRef) Validate

func (r PhysicalRef) Validate() error

Validate enforces all three fields are required per the appendix's type.

type Provenance

type Provenance struct {
	Source           string `json:"source"`
	Collection       string `json:"collection,omitempty"`
	QueryID          string `json:"queryId,omitempty"`
	Mode             string `json:"mode"` // live | snapshot
	SnapshotID       string `json:"snapshotId,omitempty"`
	ObservedAt       string `json:"observedAt"`
	ExecutionProfile string `json:"executionProfile"` // protected | opaque-privileged
}

Provenance describes where a Result actually came from: "Result.provenance .executionProfile reports the actual executor used for that run" - never the session's allowed capabilities, and a privileged principal running protected DTQL still receives protected provenance. api-contract.md "Shared JSON types" / "Security and errors".

func (Provenance) Validate

func (p Provenance) Validate() error

Validate enforces Source and ObservedAt are required (ObservedAt must be an RFC3339-UTC-normalized instant, the same rule TypedValue's "datetime" type enforces), Mode is one of the closed set, snapshot Mode requires a SnapshotID ("a snapshot requires explicit separate selection... and a configured snapshotId"), and ExecutionProfile is one of the closed set.

type Recordset

type Recordset struct {
	Columns []Column       `json:"columns"`
	Rows    [][]TypedValue `json:"rows"`
}

Recordset is Result's tabular payload. "Arrays are ordered; rows have exactly one value per returned column." api-contract.md "Shared JSON types".

func (Recordset) Validate

func (r Recordset) Validate() error

Validate enforces every column is itself valid, every row has exactly as many values as there are columns, and every cell value is itself valid.

type RelatedItem

type RelatedItem struct {
	LookupID   string `json:"lookupId"`
	Label      string `json:"label"`
	Source     string `json:"source"`
	Collection string `json:"collection"`
	Count      *int64 `json:"count"` // number | null
}

RelatedItem is one related-lookup target. Count is optional: nil means "return null if an exact authorized count cannot be obtained within a 2-second budget" - never the unrestricted count.

func (RelatedItem) Validate

func (i RelatedItem) Validate() error

type RelatedRequest added in v0.27.0

type RelatedRequest struct {
	Project           string `json:"project"`
	Environment       string `json:"environment"`
	SecurityContextID string `json:"securityContextId"`
	Fact              Fact   `json:"fact"`
	Limit             *int   `json:"limit,omitempty"`
}

RelatedRequest is POST semantic/related's request body: "Scope + {fact:Fact,limit?:number}" - api-contract.md "Endpoint table". Scope's three fields are flattened into the top level of the JSON body, exactly like ExecutionRequest, never nested under a "scope" key - confirmed against the live server (Task 12 lane S77). Related operations use POST so a semantic value is never copied into a URL, browser history or access log.

func (RelatedRequest) Validate added in v0.27.0

func (r RelatedRequest) Validate() error

Validate enforces Project/Environment/SecurityContextID are required, Fact is itself valid, and Limit, when present, is within (0, relatedMaxItems] - "Related discovery returns at most 50 targets" (api-contract.md "Bounded lookups and HTTP") bounds what a caller may ask for, not just what a response may contain, so this reuses the same relatedMaxItems the RelatedResponse envelope is capped at (responses.go).

type RelatedResponse

type RelatedResponse struct {
	Related   []RelatedItem `json:"related"`
	Truncated bool          `json:"truncated"`
}

RelatedResponse is the exact success envelope of POST semantic/related. api-contract.md "Endpoint table".

func (RelatedResponse) Validate

func (r RelatedResponse) Validate() error

Validate enforces every Related entry is itself valid and there are no more than relatedMaxItems of them.

type RelatedRowsRequest added in v0.27.0

type RelatedRowsRequest struct {
	Project           string     `json:"project"`
	Environment       string     `json:"environment"`
	SecurityContextID string     `json:"securityContextId"`
	LookupID          string     `json:"lookupId"`
	Value             TypedValue `json:"value"`
	Limit             *int       `json:"limit,omitempty"`
}

RelatedRowsRequest is POST semantic/related/rows's request body: "Scope + {lookupId:string,value:TypedValue,limit?:number}" - api-contract.md "Endpoint table". Scope's three fields are flattened into the top level of the JSON body, exactly like ExecutionRequest, never nested under a "scope" key - confirmed against the live server (Task 12 lane S77). LookupID is "an opaque handle to a server-validated relationship... not authority. Each rows request revalidates the relationship, value type, current source policy and limit" (api-contract.md "Bounded lookups and HTTP") - this type only enforces it is present and nonempty; the server revalidates everything it names.

func (RelatedRowsRequest) Validate added in v0.27.0

func (r RelatedRowsRequest) Validate() error

Validate enforces Project/Environment/SecurityContextID and LookupID are required, Value is itself valid, and Limit, when present, is within (0, executionMaxLimit] - this endpoint returns a Result, the same shape exec/run_query returns, so it is bound by the same "Default result limit is 100 and maximum is 500" rule (api-contract.md "Bounded lookups and HTTP") ExecutionRequest.Limit already enforces.

type Result

type Result struct {
	Recordset       Recordset    `json:"recordset"`
	Limitations     []Limitation `json:"limitations"`
	BindingsApplied []Binding    `json:"bindingsApplied"`
	Provenance      Provenance   `json:"provenance"`
	Truncated       bool         `json:"truncated"`
}

Result is the exact success envelope of POST exec/run_query and POST semantic/related/rows. "Denied requests return no recordset, sample, true count, SQL text or hidden value." api-contract.md "Shared JSON types".

func (Result) Validate

func (r Result) Validate() error

Validate enforces Recordset, every Limitation, every applied Binding and Provenance are each themselves valid.

type Scope

type Scope struct {
	Project           string `json:"project"`
	Environment       string `json:"environment"`
	SecurityContextID string `json:"securityContextId"`
}

Scope identifies the project, environment and staleness-check security context every scoped call carries. "Scope = {project: string, environment: string, securityContextId: string}" - api-contract.md "Scope and identity". Project and environment IDs are required, nonempty, and resolved within this server's registered projects; securityContextId is a staleness check, never authentication.

func (Scope) Validate

func (s Scope) Validate() error

Validate enforces "Project and environment IDs are required, nonempty" and the same for securityContextId (a call carrying a blank/absent staleness check cannot be validated against anything).

type SemanticColumnMapping

type SemanticColumnMapping struct {
	Column     string `json:"column"`
	Entity     string `json:"entity"`
	Field      string `json:"field"`
	Provenance string `json:"provenance"` // declared | inferred
}

SemanticColumnMapping is one physical column's resolved entity/field mapping. Unmapped columns are omitted from the response entirely, never listed with an empty entity/field.

func (SemanticColumnMapping) Validate

func (m SemanticColumnMapping) Validate() error

type SemanticColumnsResponse

type SemanticColumnsResponse struct {
	Columns []SemanticColumnMapping `json:"columns"`
}

SemanticColumnsResponse is the exact success envelope of GET semantic/columns. api-contract.md "Endpoint table".

func (SemanticColumnsResponse) Validate

func (r SemanticColumnsResponse) Validate() error

type SourceRef

type SourceRef struct {
	Source     string `json:"source"`
	Collection string `json:"collection"`
}

SourceRef names a stable project-local source, resolved through the project registry for the requested environment - never a filesystem path, arbitrary HTTP URL or credential. "SourceRef = {source: string, collection: string}" - api-contract.md "Scope and identity".

func (SourceRef) Validate

func (r SourceRef) Validate() error

Validate enforces both fields are required per the appendix's type.

type TargetOption

type TargetOption struct {
	Source string `json:"source"`
	Label  string `json:"label"`
}

TargetOption is one authorized eligible source offered on a TARGET_REQUIRED error - "the same authorized target options in error.targets, never hidden source IDs."

func (TargetOption) Validate

func (t TargetOption) Validate() error

type TypedValue

type TypedValue struct {
	Type ValueType
	Str  string
	Num  float64
	Bool bool
}

TypedValue is the wire tagged union every value crossing the transport boundary uses - api-contract.md "Shared JSON types". Missing and null differ (omit an unbound parameter; null satisfies only a nullable parameter); false, zero and empty string are present values, never coerced. Exactly one of Str/Num/Bool holds the payload, selected by Type: Str for string/integer/decimal/date/datetime (the wire encodes all of these as a JSON string, per the union), Num for number (a JSON number), Bool for boolean (a JSON boolean); null carries no payload.

func NewBooleanValue

func NewBooleanValue(v bool) TypedValue

func NewDateValue

func NewDateValue(v string) TypedValue

func NewDatetimeValue

func NewDatetimeValue(v string) TypedValue

func NewDecimalValue

func NewDecimalValue(v string) TypedValue

func NewIntegerValue

func NewIntegerValue(v string) TypedValue

func NewNullValue

func NewNullValue() TypedValue

func NewNumberValue

func NewNumberValue(v float64) TypedValue

func NewStringValue

func NewStringValue(v string) TypedValue

func (TypedValue) MarshalJSON

func (v TypedValue) MarshalJSON() ([]byte, error)

MarshalJSON writes the exact `{type:'...', value:...}` wire shape, with value's own JSON kind (string/number/boolean/null) selected by Type.

func (*TypedValue) UnmarshalJSON

func (v *TypedValue) UnmarshalJSON(data []byte) error

UnmarshalJSON parses the wire shape strictly: only "type" and "value" are accepted fields, at most once each (duplicate keys are checked directly - not just left to a caller's DecodeStrict - since TypedValue.UnmarshalJSON is invoked by encoding/json's own machinery whenever this type is embedded in a larger structure, bypassing any outer DecodeStrict call), value's JSON kind must match what Type requires (no string/number coercion), and the parsed result must pass Validate() before it is accepted.

func (TypedValue) Validate

func (v TypedValue) Validate() error

Validate enforces the appendix's per-type content rules: "finite, exactly representable JSON number" for number; "canonical decimal integer, no leading +/zeros" for integer; "canonical decimal; preserve precision" for decimal; "YYYY-MM-DD, valid calendar date" for date; "RFC3339 normalized to UTC" for datetime. string/boolean/null carry no further content constraint - false, zero and empty string are valid present values.

type ValidationError

type ValidationError struct {
	Field   string
	Message string
}

ValidationError reports a single appendix rule a value violated.

func (*ValidationError) Error

func (e *ValidationError) Error() string

type ValueType

type ValueType string

ValueType is TypedValue's tagged-union discriminant - the closed set of "type" values api-contract.md's TypedValue union declares.

const (
	ValueTypeString   ValueType = "string"
	ValueTypeNumber   ValueType = "number"
	ValueTypeInteger  ValueType = "integer"
	ValueTypeDecimal  ValueType = "decimal"
	ValueTypeBoolean  ValueType = "boolean"
	ValueTypeDate     ValueType = "date"
	ValueTypeDatetime ValueType = "datetime"
	ValueTypeNull     ValueType = "null"
)

Directories

Path Synopsis
Package fixtures holds the frozen JSON fixtures for pkg/apicontract's normative transport types (spec/features/core-investigation-loop/ api-contract.md, hub datatug/datatug) - one file per envelope/error case listed in the appendix's "Acceptance and migration" section.
Package fixtures holds the frozen JSON fixtures for pkg/apicontract's normative transport types (spec/features/core-investigation-loop/ api-contract.md, hub datatug/datatug) - one file per envelope/error case listed in the appendix's "Acceptance and migration" section.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL