Help us shape the future of Go! Take the 2026 Go Developer Survey

sync

package
v0.0.13 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Overview

Package sync orchestrates declarative reconciliation of an application's FlowCatalyst definitions against the platform.

Build a DefinitionSet with the per-category fluent builders, then hand it to Synchronizer.Sync. Each category becomes one HTTP call against the platform's per-resource sync endpoint (POST /api/applications/{appCode}/<resource>/sync). Failures on one category do NOT abort the rest — they're captured on the returned SyncResult so the caller sees a complete picture in one round-trip.

The SDKs converge on one orchestration vocabulary for this package's shape.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CategoryResult

type CategoryResult struct {
	Created     uint32
	Updated     uint32
	Deleted     uint32 // archived, for scheduled jobs
	SyncedCodes []string
	// PasswordHashIgnored (principals): emails whose passwordHash was not
	// applied because the user already existed.
	PasswordHashIgnored []string
	// SkippedRoles (principals): role names that are not roles, so were
	// assigned to no one; the rest of the sync applied. Usually a typo or a
	// role not synced yet.
	SkippedRoles []string
	// Error is non-empty if this category's HTTP call (or local check)
	// failed.
	Error string
}

CategoryResult is the per-category outcome of a Synchronizer.Sync.

Failures are captured here rather than propagated as errors so the caller can see exactly which categories succeeded, which failed, and what was touched on the platform.

func (*CategoryResult) IsError

func (c *CategoryResult) IsError() bool

IsError reports whether this category failed.

func (*CategoryResult) Touched

func (c *CategoryResult) Touched() uint32

Touched is Created + Updated + Deleted — useful for one-line summaries.

type ConnectionDefinition

type ConnectionDefinition struct {
	Code        string
	Name        string
	Description string
	ExternalID  string
}

ConnectionDefinition declares a connection. It carries nothing environment-specific (the platform assigns the application's own service account), so one definition serves every environment; it exists so a subscription's connection code resolves. Connections are synced before subscriptions.

func MakeConnection

func MakeConnection(code, name string) ConnectionDefinition

func (ConnectionDefinition) WithDescription

func (c ConnectionDefinition) WithDescription(d string) ConnectionDefinition

func (ConnectionDefinition) WithExternalID

func (c ConnectionDefinition) WithExternalID(id string) ConnectionDefinition

WithExternalID records your own system's identifier for the connection.

type DefinitionSet

type DefinitionSet struct {
	ApplicationCode string
	// ClientID scopes the set's connections and subscriptions to one client:
	// its identifier slug (preferred: ids differ per environment) or its id.
	// Empty is the global scope. Scheduled jobs carry their own ClientID.
	ClientID      string
	Roles         []RoleDefinition
	EventTypes    []EventTypeDefinition
	DispatchPools []DispatchPoolDefinition
	Connections   []ConnectionDefinition
	Subscriptions []SubscriptionDefinition
	Processes     []ProcessDefinition
	ScheduledJobs []ScheduledJobDefinition
	Principals    []PrincipalDefinition
	// OpenAPISpec is the application's OpenAPI 3.x / Swagger 2.x document;
	// nil skips the category. Each sync publishes it as the current version.
	OpenAPISpec json.RawMessage
	// Docs is the application's documentation set (full replace).
	Docs []DocDefinition
}

DefinitionSet is one application's bundled definitions. Build it with ForApplication + per-category Add* methods, then hand it to Synchronizer.Sync.

func ForApplication

func ForApplication(applicationCode string) *DefinitionSet

ForApplication starts a new set scoped to one application code.

func (*DefinitionSet) AddConnection

func (s *DefinitionSet) AddConnection(c ConnectionDefinition) *DefinitionSet

AddConnection appends a connection.

func (*DefinitionSet) AddDispatchPool

func (s *DefinitionSet) AddDispatchPool(d DispatchPoolDefinition) *DefinitionSet

AddDispatchPool appends a dispatch pool.

func (*DefinitionSet) AddDoc

AddDoc appends a documentation page.

func (*DefinitionSet) AddEventType

func (s *DefinitionSet) AddEventType(e EventTypeDefinition) *DefinitionSet

AddEventType appends an event type.

func (*DefinitionSet) AddPrincipal

func (s *DefinitionSet) AddPrincipal(p PrincipalDefinition) *DefinitionSet

AddPrincipal appends a principal.

func (*DefinitionSet) AddProcess

func (s *DefinitionSet) AddProcess(p ProcessDefinition) *DefinitionSet

AddProcess appends a process.

func (*DefinitionSet) AddRole

AddRole appends a role.

func (*DefinitionSet) AddScheduledJob

func (s *DefinitionSet) AddScheduledJob(j ScheduledJobDefinition) *DefinitionSet

AddScheduledJob appends a scheduled job.

func (*DefinitionSet) AddSubscription

func (s *DefinitionSet) AddSubscription(sub SubscriptionDefinition) *DefinitionSet

AddSubscription appends a subscription.

func (*DefinitionSet) ForClient

func (s *DefinitionSet) ForClient(clientID string) *DefinitionSet

ForClient scopes the set's connections and subscriptions to a client (identifier slug preferred).

func (*DefinitionSet) WithOpenAPISpec

func (s *DefinitionSet) WithOpenAPISpec(spec json.RawMessage) *DefinitionSet

WithOpenAPISpec sets the application's OpenAPI document.

type DispatchPoolDefinition

type DispatchPoolDefinition struct {
	Code        string
	Name        string
	Description string
	Concurrency uint32
	// RateLimit is messages per minute; nil for concurrency-only.
	RateLimit *uint32
}

DispatchPoolDefinition declares a dispatch pool.

func MakeDispatchPool

func MakeDispatchPool(code, name string) DispatchPoolDefinition

func (DispatchPoolDefinition) WithConcurrency

func (DispatchPoolDefinition) WithDescription

func (DispatchPoolDefinition) WithRateLimit

func (d DispatchPoolDefinition) WithRateLimit(perMinute uint32) DispatchPoolDefinition

WithRateLimit caps the pool at perMinute messages per minute.

type DocDefinition

type DocDefinition struct {
	Slug    string
	Title   string
	Content string
}

DocDefinition declares one documentation page, shown to administrators under Platform → Documentation. Slug is kebab-case and unique within the application; Content is Markdown; Title defaults to the first "# " heading. The docs sync is a full replace: the set's pages ARE the application's pages.

func MakeDoc

func MakeDoc(slug, content string) DocDefinition

func (DocDefinition) WithTitle

func (d DocDefinition) WithTitle(t string) DocDefinition

type EventTypeDefinition

type EventTypeDefinition struct {
	Code        string
	Name        string
	Description string
}

EventTypeDefinition declares an event type. Code must be the full four-segment identifier {app}:{subdomain}:{aggregate}:{event}.

func MakeEventType

func MakeEventType(code, name string) EventTypeDefinition

func (EventTypeDefinition) WithDescription

func (e EventTypeDefinition) WithDescription(d string) EventTypeDefinition

type Options

type Options struct {
	RemoveUnlisted    bool
	SyncRoles         bool
	SyncEventTypes    bool
	SyncDispatchPools bool
	SyncConnections   bool
	SyncSubscriptions bool
	SyncProcesses     bool
	SyncScheduledJobs bool
	SyncPrincipals    bool
	SyncOpenAPI       bool
	SyncDocs          bool
}

Options controls a Synchronizer.Sync call.

RemoveUnlisted toggles ?removeUnlisted=true on every per-category endpoint that has it (and archiveUnlisted on the scheduled-jobs sync): the platform archives/removes the SDK-sourced rows that aren't in the submitted list. UI-sourced rows are never touched. Default false. The docs sync is always a full replace, and the OpenAPI sync publishes one document; neither reads it.

SyncX flags are per-category skip switches. Empty categories on the DefinitionSet are also implicitly skipped regardless of these flags.

func ConnectionsOnly

func ConnectionsOnly() Options

ConnectionsOnly returns Options enabling only the connections category.

func DefaultOptions

func DefaultOptions() Options

DefaultOptions enables every category, RemoveUnlisted=false.

func DispatchPoolsOnly

func DispatchPoolsOnly() Options

DispatchPoolsOnly returns Options enabling only the dispatch pools category.

func DocsOnly

func DocsOnly() Options

DocsOnly returns Options enabling only the documentation pages.

func EventTypesOnly

func EventTypesOnly() Options

EventTypesOnly returns Options enabling only the event types category.

func NoneOptions

func NoneOptions() Options

NoneOptions disables every category. Use as a starting point for selectively enabling one or two.

func OpenAPIOnly

func OpenAPIOnly() Options

OpenAPIOnly returns Options enabling only the OpenAPI document.

func PrincipalsOnly

func PrincipalsOnly() Options

PrincipalsOnly returns Options enabling only the principals category.

func ProcessesOnly

func ProcessesOnly() Options

ProcessesOnly returns Options enabling only the processes category.

func RolesOnly

func RolesOnly() Options

RolesOnly returns Options enabling only the roles category.

func ScheduledJobsOnly

func ScheduledJobsOnly() Options

ScheduledJobsOnly returns Options enabling only the scheduled jobs category.

func SubscriptionsOnly

func SubscriptionsOnly() Options

SubscriptionsOnly returns Options enabling only the subscriptions category.

func WithRemoveUnlisted

func WithRemoveUnlisted() Options

WithRemoveUnlisted returns DefaultOptions with RemoveUnlisted=true.

type PrincipalDefinition

type PrincipalDefinition struct {
	Email  string
	Name   string
	Roles  []string
	Active bool
	// PasswordHash, when set, carries an already-hashed credential (e.g. an
	// upstream Laravel bcrypt/argon2i hash) so a migrated user keeps their
	// password. Sent verbatim; the platform verifies it and re-encodes it to
	// its native scheme on first login. Use WithPasswordHash to set it.
	PasswordHash *string
}

PrincipalDefinition declares a user principal. Matched by Email on sync. Active defaults to true (set Inactive() to override).

func MakePrincipal

func MakePrincipal(email string) PrincipalDefinition

MakePrincipal starts a PrincipalDefinition for the given email. The principal defaults to Active.

func (PrincipalDefinition) Inactive

Inactive marks the principal as inactive on sync.

func (PrincipalDefinition) WithName

func (PrincipalDefinition) WithPasswordHash

func (p PrincipalDefinition) WithPasswordHash(hash string) PrincipalDefinition

WithPasswordHash attaches an already-hashed credential (e.g. the value of a Laravel user's password column). Pass the HASH, not a plaintext password — it is stored verbatim and verified as-is at login.

func (PrincipalDefinition) WithRoles

func (p PrincipalDefinition) WithRoles(roles ...string) PrincipalDefinition

type ProcessDefinition

type ProcessDefinition struct {
	Code        string
	Name        string
	Description string
	Body        string
	DiagramType string
	Tags        []string
}

ProcessDefinition declares a process documentation entry. Code is {application}:{subdomain}:{process-name}; Body is the diagram source (stored verbatim, typically Mermaid); DiagramType defaults to mermaid.

func MakeProcess

func MakeProcess(code, name string) ProcessDefinition

func (ProcessDefinition) WithBody

func (p ProcessDefinition) WithBody(body string) ProcessDefinition

WithBody sets the diagram source.

func (ProcessDefinition) WithDescription

func (p ProcessDefinition) WithDescription(s string) ProcessDefinition

func (ProcessDefinition) WithDiagramType

func (p ProcessDefinition) WithDiagramType(t string) ProcessDefinition

WithDiagramType sets the diagram language (default mermaid).

func (ProcessDefinition) WithTags

func (p ProcessDefinition) WithTags(tags ...string) ProcessDefinition

WithTags appends tags.

type Result

type Result struct {
	ApplicationCode string
	Roles           *CategoryResult
	EventTypes      *CategoryResult
	DispatchPools   *CategoryResult
	Connections     *CategoryResult
	Subscriptions   *CategoryResult
	Processes       *CategoryResult
	ScheduledJobs   *CategoryResult
	Principals      *CategoryResult
	OpenAPI         *CategoryResult
	Docs            *CategoryResult
}

Result is the aggregate outcome of syncing a DefinitionSet. Each per-category field is non-nil only if the Synchronizer called that endpoint (i.e. the category was enabled in Options AND non-empty).

func (*Result) Errors

func (r *Result) Errors() map[string]string

Errors returns a (category → message) list of failed categories.

func (*Result) HasErrors

func (r *Result) HasErrors() bool

HasErrors reports whether any category failed.

type RoleDefinition

type RoleDefinition struct {
	Name          string
	DisplayName   string
	Description   string
	Permissions   []string
	ClientManaged bool
}

RoleDefinition declares a role for an application. Name is the short name without the `<app>:` prefix — the platform adds it from the sync URL. Set ClientManaged true to let clients re-assign or remove the role per-tenant.

func MakeRole

func MakeRole(name string) RoleDefinition

MakeRole starts a RoleDefinition with the given short name.

func (RoleDefinition) ClientManagedEnabled

func (r RoleDefinition) ClientManagedEnabled() RoleDefinition

func (RoleDefinition) WithDescription

func (r RoleDefinition) WithDescription(d string) RoleDefinition

func (RoleDefinition) WithDisplayName

func (r RoleDefinition) WithDisplayName(name string) RoleDefinition

func (RoleDefinition) WithPermissions

func (r RoleDefinition) WithPermissions(perms ...string) RoleDefinition

type ScheduledJobDefinition

type ScheduledJobDefinition struct {
	Code                string
	Name                string
	Description         string
	Crons               []string
	Timezone            string
	Payload             json.RawMessage
	Concurrent          bool
	TracksCompletion    bool
	TimeoutSeconds      *int32
	DeliveryMaxAttempts *int32 // platform default 3
	TargetURL           string // overrides the application's default callback URL
	ClientID            string
}

ScheduledJobDefinition declares a scheduled job. Crons are evaluated in Timezone (default UTC). Concurrent lets a new firing start while the previous one runs; TracksCompletion makes the platform wait for the application's completion report (see package scheduledjobs) instead of treating delivery as success. ClientID scopes the job to one client (omit for a platform-wide job, anchor only); jobs are sent one request per client.

func MakeScheduledJob

func MakeScheduledJob(code, name string, crons ...string) ScheduledJobDefinition

MakeScheduledJob starts a job with its cron expressions.

func (ScheduledJobDefinition) ConcurrentEnabled

func (j ScheduledJobDefinition) ConcurrentEnabled() ScheduledJobDefinition

func (ScheduledJobDefinition) ForClient

func (ScheduledJobDefinition) TracksCompletionEnabled

func (j ScheduledJobDefinition) TracksCompletionEnabled() ScheduledJobDefinition

func (ScheduledJobDefinition) WithDeliveryMaxAttempts

func (j ScheduledJobDefinition) WithDeliveryMaxAttempts(n int32) ScheduledJobDefinition

func (ScheduledJobDefinition) WithDescription

func (ScheduledJobDefinition) WithPayload

func (ScheduledJobDefinition) WithTargetURL

func (ScheduledJobDefinition) WithTimeout

func (ScheduledJobDefinition) WithTimezone

type SubscriptionBinding

type SubscriptionBinding struct {
	EventTypeCode string
	Filter        string
}

SubscriptionBinding pairs an event type pattern with an optional filter.

type SubscriptionDefinition

type SubscriptionDefinition struct {
	Code        string
	Name        string
	Description string
	Target      string // webhook endpoint URL
	// ConnectionCode names the delivering connection by code (stable across
	// environments; prefer it to ConnectionID). It resolves among this
	// application's connections, or the shared ones when SharedConnection
	// is set. Connections are synced before subscriptions in the same run.
	ConnectionCode   string
	SharedConnection bool
	ConnectionID     string // environment-specific; prefer ConnectionCode
	DispatchPoolCode string
	Mode             string // IMMEDIATE, NEXT_ON_ERROR (platform default) or BLOCK_ON_ERROR
	MaxRetries       *uint32
	TimeoutSeconds   *uint32
	DataOnly         bool
	EventTypes       []SubscriptionBinding
}

SubscriptionDefinition declares a webhook subscription.

func MakeSubscription

func MakeSubscription(code, name, target string) SubscriptionDefinition

func (SubscriptionDefinition) Bind

func (s SubscriptionDefinition) Bind(eventTypeCode, filter string) SubscriptionDefinition

func (SubscriptionDefinition) DataOnlyEnabled

func (s SubscriptionDefinition) DataOnlyEnabled() SubscriptionDefinition

func (SubscriptionDefinition) WithConnection

WithConnection names the delivering connection by id. Ids differ per environment: prefer WithConnectionCode for anything synced to more than one.

func (SubscriptionDefinition) WithConnectionCode

func (s SubscriptionDefinition) WithConnectionCode(code string) SubscriptionDefinition

WithConnectionCode names the delivering connection by code, one of this application's connections.

func (SubscriptionDefinition) WithDescription

func (SubscriptionDefinition) WithDispatchPool

func (s SubscriptionDefinition) WithDispatchPool(code string) SubscriptionDefinition

func (SubscriptionDefinition) WithMaxRetries

func (SubscriptionDefinition) WithMode

func (SubscriptionDefinition) WithSharedConnectionCode

func (s SubscriptionDefinition) WithSharedConnectionCode(code string) SubscriptionDefinition

WithSharedConnectionCode names a shared (application-less) connection by code. There is no fallback between the two namespaces.

func (SubscriptionDefinition) WithTimeout

type Synchronizer

type Synchronizer struct {
	// contains filtered or unexported fields
}

Synchronizer orchestrates per-category sync calls against a FlowCatalystClient. Reuse one Synchronizer across calls — the client is cheap to share.

Categories are sync'd in a fixed order so references already exist by the time later categories arrive (the Rust and Java SDKs' order):

  1. roles
  2. event types
  3. dispatch pools (before subscriptions: the platform drops a subscription's unresolvable dispatchPoolCode)
  4. connections
  5. subscriptions (not sent, with an error, when connections failed: their connection codes would not resolve)
  6. processes
  7. scheduled jobs (one request per job ClientID)
  8. principals (after roles, which they name)
  9. OpenAPI document
  10. documentation pages

A failure in one category does NOT abort the rest — the error lands on the per-category Result.Error field.

func NewSynchronizer

func NewSynchronizer(c *client.FlowCatalystClient) *Synchronizer

NewSynchronizer wires a Synchronizer against an existing client.

func (*Synchronizer) Sync

func (s *Synchronizer) Sync(ctx context.Context, set *DefinitionSet, opts Options) *Result

Sync pushes the DefinitionSet to the platform per Options. Returns the aggregate result; inspect Result.HasErrors / Result.Errors to see what failed.

func (*Synchronizer) SyncAll

func (s *Synchronizer) SyncAll(ctx context.Context, sets []*DefinitionSet, opts Options) []*Result

SyncAll syncs several sets in order; one set's failures do not stop the next.

func (*Synchronizer) SyncUsers

func (s *Synchronizer) SyncUsers(ctx context.Context, defs []PrincipalDefinition) *CategoryResult

SyncUsers performs an application-less user sync (POST /api/principals/sync): a declarative upsert keyed on email that needs no application. Use it to migrate users — including their existing password hashes via PrincipalDefinition.WithPasswordHash — without wrapping the call in an application. Pure upsert: it never strips roles from unlisted users.

Jump to

Keyboard shortcuts

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