githubapp

package
v0.102.5 Latest Latest
Warning

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

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

README

Workbench GitHub App control-plane contract

github.com/sneat-dev/wb/api/githubapp owns the typed HTTP contract for the Workbench dashboard at https://sneat.work/bench. The service is mounted by the existing Sneat Go Cloud Run executable at https://wb-github-app.sneat.dev. It is not a separate service.

The host supplies three narrow ports:

  1. ReadModel, which records a repository's explicit public opt-in (including its README-linked free-eligibility declaration) before it returns anonymous data. Private subjects require an authenticated member and are rendered as 404 for every other caller.
  2. DeliveryStore, backed by durable storage, which atomically claims GitHub delivery IDs and persists coalesced wakeups.
  3. AuthoritativeReader, which refreshes GitHub App state before a webhook can enqueue work. Cached data is never enough to authorize an action.

The API provides the dashboard summary, repository/organization/user stats, time series usable as tables or graphs, leaderboards, and latest merges with pull request, issue, merge commit, release, and Workbench receipt URLs. The stats route uses a remainder wildcard so canonical IDs such as github.com/acme/app round-trip without dropping path segments.

GET /v0/workbench/events is the default server-to-browser transport. It is resumable SSE: after (or Last-Event-ID) replays durable events with strictly monotonic IDs before the browser receives the live subscription. The source and service filter private events before serialization. Event types are queue, job.phase, job.progress, ci, cleanup, sync, and daemon.generation. WebSocket is reserved for later bidirectional controls such as cancellation and reprioritization.

The sequenced EventSource is also the terminal-monitoring source: filter by repo, task, operation, session, severity, after, and RFC 3339 since. wb monitor --format=jsonl consumes this same sequence; wb log tail can be an alias, but immutable Work Logs are never used as a mutable event queue.

Provider storage boundary

The host-neutral provider in provider.go implements ReadModel over a ProjectionStore; the host supplies the durable adapter. Projection documents use the workbench_projections collection, with scope and the canonical GitHub subject ID (github.com/<org> or github.com/<org>/<repo>) retained in the document. Webhook envelopes are normalized to the same github.com/<org>/<repo> form before wakeups or projection refreshes. ProjectionKey derives a stable SHA-256 document ID so slashes cannot alter storage hierarchy. Series, leaderboard, and latest-merge records use the corresponding named collections and typed store methods. The public latest-merges method is intentionally typed to return public-only entries. Leaderboard documents likewise require public_only; private boards are refused until a subject-scoped board contract exists.

Repository projections are anonymous only when public_opt_in is true. For a private projection the host's MembershipResolver must prove that the Firebase-authenticated Viewer.UserID maps to an installed GitHub identity with access to that exact organization or repository. Browser headers and GitHub repository visibility are never accepted as membership evidence. A missing resolver or failed membership check fails closed as private data.

The provider does not choose Firestore paths, Firebase projects, GitHub credentials, or aggregation credentials. Sneat Go can bind those through its wire-only adapter once the corresponding durable store and membership service are configured.

Firestore adapter schema

The host may bind FirestoreProjectionStore, FirestoreProjectionWriter, and FirestoreProjectionDeliveryStore through the small FirestoreBackend seam. Projection documents live in workbench_projections/{ProjectionKey(scope,id)}; series and leaderboards use workbench_series and workbench_leaderboards; the public merge snapshot is workbench_latest_merges/public. Delivery state uses workbench_deliveries/{deliveryID}, and coalesced wakeups use workbench_wakeups/{sha256(wakeupKey)} while retaining the canonical key in the wakeup body. Delivery claims carry a bounded lease and expire into retryable work. Hosts supply the actual Firestore client and transaction implementation; this package contains no Firebase or Firestore SDK dependency.

Projection delivery boundary

The projector uses a ProjectionDeliveryStore claim before refresh. The claim is atomic across concurrent workers, and ReleaseDelivery makes failed refreshes or writes retryable while preserving the append-only delivery audit. The writer receives the delivery ID with each repository, organization, and latest-merge batch and must make those operations idempotent. The final CommitDeliveryAndWakeup call records the terminal delivery and coalesced wakeup only after all projection writes succeed.

Documentation

Overview

Package githubapp defines the Workbench GitHub App control-plane API.

Index

Constants

View Source
const (
	// ControlPlaneOrigin is the dedicated machine API origin.
	ControlPlaneOrigin = "https://wb-github-app.sneat.dev"
	// ControlPlaneHost is the host-only form used by the Cloud Run adapter.
	ControlPlaneHost = "wb-github-app.sneat.dev"
	// UIOrigin is the browser origin permitted to call the control-plane API.
	UIOrigin = "https://sneat.work"
	// APIPrefix is mounted by the host application.
	APIPrefix = "/v0/workbench"
)
View Source
const (
	ProjectionCollection  = "workbench_projections"
	SeriesCollection      = "workbench_series"
	LeaderboardCollection = "workbench_leaderboards"
	MergeCollection       = "workbench_latest_merges"
)

Variables

View Source
var (
	ErrNoProjector       = errors.New("workbench projection engine is not configured")
	ErrInvalidProjection = errors.New("invalid workbench projection snapshot")
)
View Source
var (
	ErrPrivateData = errors.New("private Workbench data requires membership")
	ErrNoReadModel = errors.New("workbench read model is not configured")
	ErrNoWebhook   = errors.New("workbench webhook processor is not configured")
)
View Source
var ErrProjectionNotFound = errors.New("workbench projection not found")

Functions

func NewHandler

func NewHandler(options HandlerOptions) http.Handler

NewHandler returns the Workbench GitHub App API under APIPrefix. It permits the Sneat Workbench browser origin only; GitHub webhooks have no CORS need.

func ProjectionKey added in v0.100.0

func ProjectionKey(scope Scope, id string) string

ProjectionKey is the stable document key: scope plus a SHA-256 digest of the canonical subject ID. The digest prevents slashes in github.com/org/repo IDs from changing collection hierarchy while preserving the original ID in the document body for audit and display.

func ValidateProjectionDocument added in v0.100.0

func ValidateProjectionDocument(document ProjectionDocument) error

func ValidatePublicEligibility added in v0.102.0

func ValidatePublicEligibility(evidence PublicEligibility) error

ValidatePublicEligibility rejects incomplete or non-canonical durable evidence. It intentionally verifies the identity and URL shape only; the authoritative reader verifies the README contents before it records this evidence with a projection.

Types

type Access

type Access[T any] struct {
	Visibility Visibility
	Value      T
}

Access wraps a read-model result with its disclosure class.

type AuthoritativeReader

type AuthoritativeReader interface {
	Refresh(context.Context, WebhookDelivery) error
}

AuthoritativeReader refreshes the GitHub App's authoritative view before an action is queued. A cache hit alone must never satisfy this call.

type Dashboard

type Dashboard struct {
	GeneratedAt time.Time `json:"generated_at"`
	Summary     Summary   `json:"summary"`
	Links       []Link    `json:"links,omitempty"`
}

Dashboard is the top-level dashboard response.

type DeliveryStore

type DeliveryStore interface {
	HasDelivery(context.Context, string) (bool, error)
	CommitDeliveryAndWakeup(context.Context, string, Wakeup) (bool, error)
}

DeliveryStore must be backed by durable storage. HasDelivery is a cheap preflight that avoids repeating an authoritative GitHub read for a redelivery. CommitDeliveryAndWakeup atomically records the delivery ID and persists a wakeup coalesced by its scope key. It returns false when a concurrent request committed the same delivery first.

type Event

type Event struct {
	ID         uint64          `json:"id"`
	Type       EventType       `json:"type"`
	Visibility Visibility      `json:"visibility"`
	At         time.Time       `json:"at"`
	Repository string          `json:"repository,omitempty"`
	Task       string          `json:"task,omitempty"`
	Operation  string          `json:"operation,omitempty"`
	Session    string          `json:"session,omitempty"`
	Severity   string          `json:"severity,omitempty"`
	Payload    json.RawMessage `json:"payload"`
}

Event is an SSE record. ID is a durable monotonic cursor, not a timestamp. Payload is only serialized after the viewer passes its visibility check.

type EventFilter

type EventFilter struct {
	After      uint64
	Since      time.Time
	Repository string
	Task       string
	Operation  string
	Session    string
	Severity   string
}

EventFilter selects one resumable daemon/direct-WB event sequence. Work Logs remain immutable per-task evidence; this filter is transient monitoring only.

type EventSource

type EventSource interface {
	Replay(context.Context, EventFilter) ([]Event, error)
	Subscribe(context.Context, EventFilter) (<-chan Event, error)
}

EventSource durably replays events strictly after a cursor, then exposes a live subscription. Implementations must retain enough history for reconnects and issue globally monotonic IDs across daemon generations.

type EventType

type EventType string

EventType classifies a live Workbench daemon update. WebSocket is reserved for later bidirectional controls such as cancel and reprioritize.

const (
	EventQueue            EventType = "queue"
	EventJobPhase         EventType = "job.phase"
	EventJobProgress      EventType = "job.progress"
	EventCI               EventType = "ci"
	EventCleanup          EventType = "cleanup"
	EventSync             EventType = "sync"
	EventDaemonGeneration EventType = "daemon.generation"
)

type FirestoreBackend added in v0.102.0

type FirestoreBackend interface {
	Get(context.Context, string, string, any) (bool, error)
	Query(context.Context, string, map[string]any, int, any) error
	Set(context.Context, string, string, any) error
	UpdateAtomic(context.Context, func(FirestoreTransaction) error) error
}

FirestoreBackend is the deliberately small seam implemented by the host's Firestore client. Values are decoded into out by the backend. UpdateAtomic must provide Firestore transaction semantics.

type FirestoreProjectionDeliveryStore added in v0.102.0

type FirestoreProjectionDeliveryStore struct {
	Backend FirestoreBackend
	Now     func() time.Time
	Lease   time.Duration
}

FirestoreProjectionDeliveryStore provides the atomic claim and coalesced wakeup used by ProjectionEngine. An expired claim is recoverable.

func (FirestoreProjectionDeliveryStore) ClaimDelivery added in v0.102.0

func (store FirestoreProjectionDeliveryStore) ClaimDelivery(ctx context.Context, id string) (bool, error)

func (FirestoreProjectionDeliveryStore) CommitDeliveryAndWakeup added in v0.102.0

func (store FirestoreProjectionDeliveryStore) CommitDeliveryAndWakeup(ctx context.Context, id string, wakeup Wakeup) (bool, error)

func (FirestoreProjectionDeliveryStore) HasDelivery added in v0.102.0

func (store FirestoreProjectionDeliveryStore) HasDelivery(ctx context.Context, id string) (bool, error)

func (FirestoreProjectionDeliveryStore) ReleaseDelivery added in v0.102.0

func (store FirestoreProjectionDeliveryStore) ReleaseDelivery(ctx context.Context, id string) error

type FirestoreProjectionStore added in v0.102.0

type FirestoreProjectionStore struct{ Backend FirestoreBackend }

FirestoreProjectionStore maps the documented Workbench collections to the host backend. The adapter contains no cloud.google.com imports, keeping the provider portable and letting Sneat Go supply its configured client.

func (FirestoreProjectionStore) GetLeaderboard added in v0.102.0

func (store FirestoreProjectionStore) GetLeaderboard(ctx context.Context, metric string) (LeaderboardDocument, error)

func (FirestoreProjectionStore) GetProjection added in v0.102.0

func (store FirestoreProjectionStore) GetProjection(ctx context.Context, scope Scope, id string) (ProjectionDocument, error)

func (FirestoreProjectionStore) ListProjections added in v0.102.0

func (store FirestoreProjectionStore) ListProjections(ctx context.Context, scope Scope) ([]ProjectionDocument, error)

func (FirestoreProjectionStore) ListPublicLatestMerges added in v0.102.0

func (store FirestoreProjectionStore) ListPublicLatestMerges(ctx context.Context, limit int) (PublicLatestMerges, error)

func (FirestoreProjectionStore) ListSeries added in v0.102.0

func (store FirestoreProjectionStore) ListSeries(ctx context.Context, scope Scope, id, metric string) (SeriesDocument, error)

type FirestoreProjectionWriter added in v0.102.0

type FirestoreProjectionWriter struct{ Backend FirestoreBackend }

FirestoreProjectionWriter applies complete batches by stable document key. Set is intentionally idempotent, so a retry after a crash cannot duplicate projections or public merges.

func (FirestoreProjectionWriter) WriteLatestMerges added in v0.102.0

func (writer FirestoreProjectionWriter) WriteLatestMerges(ctx context.Context, deliveryID string, records []LatestMerge) error

func (FirestoreProjectionWriter) WriteOrganizations added in v0.102.0

func (writer FirestoreProjectionWriter) WriteOrganizations(ctx context.Context, deliveryID string, records []ProjectionDocument) error

func (FirestoreProjectionWriter) WriteRepositories added in v0.102.0

func (writer FirestoreProjectionWriter) WriteRepositories(ctx context.Context, deliveryID string, records []ProjectionDocument) error

type FirestoreTransaction added in v0.102.0

type FirestoreTransaction interface {
	Get(context.Context, string, string, any) (bool, error)
	Set(context.Context, string, string, any) error
}

type HandlerOptions

type HandlerOptions struct {
	Service        Service
	ViewerResolver ViewerResolver
	AllowedOrigin  string
}

HandlerOptions supplies the narrow host bindings for the public API.

type LatestMerge

type LatestMerge struct {
	Repository     string    `json:"repository" firestore:"repository"`
	PullRequest    int       `json:"pull_request" firestore:"pull_request"`
	MergedAt       time.Time `json:"merged_at" firestore:"merged_at"`
	PullRequestURL string    `json:"pull_request_url,omitempty" firestore:"pull_request_url,omitempty"`
	IssueURL       string    `json:"issue_url,omitempty" firestore:"issue_url,omitempty"`
	MergeCommitSHA string    `json:"merge_commit_sha,omitempty" firestore:"merge_commit_sha,omitempty"`
	MergeCommitURL string    `json:"merge_commit_url,omitempty" firestore:"merge_commit_url,omitempty"`
	ReleaseURL     string    `json:"release_url,omitempty" firestore:"release_url,omitempty"`
	ReceiptURL     string    `json:"receipt_url,omitempty" firestore:"receipt_url,omitempty"`
}

LatestMerge gives the dashboard every navigable artifact around a merge.

type Leaderboard

type Leaderboard struct {
	Metric  string             `json:"metric"`
	Entries []LeaderboardEntry `json:"entries"`
}

Leaderboard groups ranked values for a requested metric.

type LeaderboardDocument added in v0.100.0

type LeaderboardDocument struct {
	Metric     string             `json:"metric" firestore:"metric"`
	Entries    []LeaderboardEntry `json:"entries" firestore:"entries"`
	PublicOnly bool               `json:"public_only" firestore:"public_only"`
}

type LeaderboardEntry

type LeaderboardEntry struct {
	Rank        int    `json:"rank" firestore:"rank"`
	SubjectID   string `json:"subject_id" firestore:"subject_id"`
	DisplayName string `json:"display_name" firestore:"display_name"`
	Value       int64  `json:"value" firestore:"value"`
}

LeaderboardEntry is intentionally small so public leaderboards do not leak private repository names or private activity counts.

type Link struct {
	Kind string `json:"kind"`
	Href string `json:"href"`
}

Link is a canonical GitHub, release, or Workbench receipt reference.

type MembershipResolver added in v0.100.0

type MembershipResolver interface {
	Member(context.Context, Viewer, Scope, string) (bool, error)
}

MembershipResolver proves GitHub installation membership for one canonical subject. A Firebase-authenticated host maps Viewer.UserID to GitHub identity; the provider never trusts browser headers or public GitHub visibility.

type ProjectionDeliveryStore added in v0.101.0

type ProjectionDeliveryStore interface {
	DeliveryStore
	ClaimDelivery(context.Context, string) (bool, error)
	ReleaseDelivery(context.Context, string) error
}

ProjectionDeliveryStore extends DeliveryStore with an atomic in-flight claim. ClaimDelivery returns false for a committed or currently claimed delivery. ReleaseDelivery makes refresh/write failures retryable; the implementation must retain its append-only audit record.

type ProjectionDocument added in v0.100.0

type ProjectionDocument struct {
	Scope             Scope              `json:"scope" firestore:"scope"`
	ID                string             `json:"id" firestore:"id"`
	DisplayName       string             `json:"display_name" firestore:"display_name"`
	Summary           Summary            `json:"summary" firestore:"summary"`
	UpdatedAt         time.Time          `json:"updated_at" firestore:"updated_at"`
	PublicOptIn       bool               `json:"public_opt_in" firestore:"public_opt_in"`
	PublicEligibility *PublicEligibility `json:"public_eligibility,omitempty" firestore:"public_eligibility,omitempty"`
}

ProjectionDocument is the durable, privacy-classified summary written by a Workbench-owned projector. Public responses require PublicOptIn; private responses require the host membership resolver below.

type ProjectionEngine added in v0.101.0

type ProjectionEngine struct {
	Deliveries          ProjectionDeliveryStore
	Reader              ProjectionReader
	Writer              ProjectionWriter
	AuthoritativeReader AuthoritativeReader
	WebhookSecret       []byte
}

ProjectionEngine coordinates authoritative refresh, durable projection writes, and delivery receipt publication. It deliberately does not import GitHub, Firebase, or Firestore clients.

func (ProjectionEngine) Process added in v0.101.0

func (engine ProjectionEngine) Process(ctx context.Context, delivery WebhookDelivery, signature string) (queued bool, processErr error)

Process verifies and applies one delivery. AuthoritativeReader is retained as a required companion to ProjectionReader so hosts cannot accidentally wire a projection reader that omits the existing refresh barrier.

type ProjectionReader added in v0.101.0

type ProjectionReader interface {
	RefreshProjection(context.Context, WebhookDelivery) (ProjectionSnapshot, error)
}

ProjectionReader refreshes and returns the authoritative records for a delivery. Implementations may coalesce equivalent repository refreshes, but must not satisfy a delivery from cache alone.

type ProjectionSnapshot added in v0.101.0

type ProjectionSnapshot struct {
	Repositories  []ProjectionDocument
	Organizations []ProjectionDocument
	LatestMerges  []LatestMerge
}

ProjectionSnapshot is the authoritative result of refreshing one GitHub App delivery. The reader owns GitHub access; the provider owns validation and the stable projection write order.

type ProjectionStore added in v0.100.0

type ProjectionStore interface {
	ListProjections(context.Context, Scope) ([]ProjectionDocument, error)
	GetProjection(context.Context, Scope, string) (ProjectionDocument, error)
	ListSeries(context.Context, Scope, string, string) (SeriesDocument, error)
	GetLeaderboard(context.Context, string) (LeaderboardDocument, error)
	ListPublicLatestMerges(context.Context, int) (PublicLatestMerges, error)
}

ProjectionStore is the narrow durable persistence adapter supplied by the host. Implementations map these operations to Firestore or another durable store; aggregation and disclosure stay in this package.

type ProjectionWriter added in v0.101.0

type ProjectionWriter interface {
	WriteRepositories(context.Context, string, []ProjectionDocument) error
	WriteOrganizations(context.Context, string, []ProjectionDocument) error
	WriteLatestMerges(context.Context, string, []LatestMerge) error
}

ProjectionWriter durably applies a complete authoritative snapshot. Every method is keyed by deliveryID and must be idempotent: a crash after a write and before DeliveryStore commits is safe to retry. Implementations should replace projections by ProjectionKey and replace the public merge view as a single logical operation.

type PublicEligibility

type PublicEligibility struct {
	Repository string    `json:"repository" firestore:"repository"`
	READMEURL  string    `json:"readme_url" firestore:"readme_url"`
	VerifiedAt time.Time `json:"verified_at" firestore:"verified_at"`
}

PublicEligibility is the auditable root-README opt-in record required before a repository can appear in unauthenticated results. It is not inferred from GitHub repository visibility alone.

func VerifyPublicEligibility added in v0.102.0

func VerifyPublicEligibility(repository, readmeURL, markdown string, verifiedAt time.Time) (PublicEligibility, error)

VerifyPublicEligibility returns auditable evidence only when the root README has an explicit Workbench opt-in. The caller supplies the canonical GitHub README URL it read and the verification time from its authoritative refresh.

type PublicLatestMerges added in v0.100.0

type PublicLatestMerges struct {
	Entries []LatestMerge `json:"entries" firestore:"entries"`
}

type ReadModel

ReadModel owns persistence and GitHub data projection. It must return only subjects whose public opt-in is recorded, unless the supplied viewer is an authenticated member of the private subject.

type Scope

type Scope string

Scope identifies the GitHub subject represented by a statistic.

const (
	ScopeRepository   Scope = "repository"
	ScopeOrganization Scope = "organization"
	ScopeUser         Scope = "user"
)

type Series

type Series struct {
	Scope  Scope         `json:"scope"`
	ID     string        `json:"id"`
	Metric string        `json:"metric"`
	Points []SeriesPoint `json:"points"`
}

Series is a named time-series for graph and table consumers.

type SeriesDocument added in v0.100.0

type SeriesDocument struct {
	Scope  Scope         `json:"scope" firestore:"scope"`
	ID     string        `json:"id" firestore:"id"`
	Metric string        `json:"metric" firestore:"metric"`
	Points []SeriesPoint `json:"points" firestore:"points"`
}

type SeriesPoint

type SeriesPoint struct {
	At    time.Time `json:"at" firestore:"at"`
	Value int64     `json:"value" firestore:"value"`
}

SeriesPoint can render either a graph point or a table row.

type Service

type Service struct {
	// Projector is the only supported webhook processor.
	Projector *ProjectionEngine
	ReadModel ReadModel
	Events    EventSource
}

Service applies disclosure policy around a Workbench read model and processes signed GitHub App webhook deliveries.

func (Service) Dashboard

func (service Service) Dashboard(ctx context.Context, viewer Viewer) (Dashboard, error)

func (Service) EventStream

func (service Service) EventStream(ctx context.Context, viewer Viewer, filter EventFilter) ([]Event, <-chan Event, error)

EventStream replays visible durable events after cursor and returns the filtered live channel. It validates monotonic order so a bad source cannot cause a browser to skip or regress a reconnect cursor.

func (Service) LatestMerges

func (service Service) LatestMerges(ctx context.Context, viewer Viewer, limit int) ([]LatestMerge, error)

func (Service) Leaderboard

func (service Service) Leaderboard(ctx context.Context, viewer Viewer, metric string) (Leaderboard, error)

func (Service) ProcessWebhook

func (service Service) ProcessWebhook(ctx context.Context, delivery WebhookDelivery, signature string) (bool, error)

ProcessWebhook delegates webhook processing to the claim-safe projection engine. Hosts without a configured projector fail closed; the legacy fields are retained only so migrating compositions remain source-compatible.

func (Service) Series

func (service Service) Series(ctx context.Context, viewer Viewer, scope Scope, id, metric string) (Series, error)

func (Service) Stats

func (service Service) Stats(ctx context.Context, viewer Viewer, scope Scope, id string) (Stat, error)

type Stat

type Stat struct {
	Scope       Scope     `json:"scope"`
	ID          string    `json:"id"`
	DisplayName string    `json:"display_name"`
	Summary     Summary   `json:"summary"`
	UpdatedAt   time.Time `json:"updated_at"`
	Links       []Link    `json:"links,omitempty"`
}

Stat is one scoped repository, organization, or user result.

type StoreReadModel added in v0.100.0

type StoreReadModel struct {
	Store      ProjectionStore
	Membership MembershipResolver
}

func (StoreReadModel) Dashboard added in v0.100.0

func (model StoreReadModel) Dashboard(ctx context.Context, viewer Viewer) (Access[Dashboard], error)

func (StoreReadModel) LatestMerges added in v0.100.0

func (model StoreReadModel) LatestMerges(ctx context.Context, viewer Viewer, limit int) (Access[[]LatestMerge], error)

func (StoreReadModel) Leaderboard added in v0.100.0

func (model StoreReadModel) Leaderboard(ctx context.Context, viewer Viewer, metric string) (Access[Leaderboard], error)

func (StoreReadModel) Series added in v0.100.0

func (model StoreReadModel) Series(ctx context.Context, viewer Viewer, scope Scope, id, metric string) (Access[Series], error)

func (StoreReadModel) Stats added in v0.100.0

func (model StoreReadModel) Stats(ctx context.Context, viewer Viewer, scope Scope, id string) (Access[Stat], error)

type Summary

type Summary struct {
	Repositories int `json:"repositories" firestore:"repositories"`
	OpenPulls    int `json:"open_pulls" firestore:"open_pulls"`
	MergedPulls  int `json:"merged_pulls" firestore:"merged_pulls"`
	OpenIssues   int `json:"open_issues" firestore:"open_issues"`
	Releases     int `json:"releases" firestore:"releases"`
}

Summary is the compact dashboard card set.

type Viewer

type Viewer struct {
	Authenticated bool
	Member        bool
	UserID        string
}

Viewer is resolved by the host before a private record is rendered.

type ViewerResolver

type ViewerResolver interface {
	Viewer(*http.Request) (Viewer, error)
}

ViewerResolver binds the host authentication and membership system to the Workbench domain. The WB domain never accepts identity headers directly.

type Visibility

type Visibility string

Visibility describes whether a response contains an explicitly opted-in public subject or a member-only private subject.

const (
	VisibilityPublic  Visibility = "public"
	VisibilityPrivate Visibility = "private"
)

type Wakeup

type Wakeup struct {
	Key        string `json:"key" firestore:"key"`
	Repository string `json:"repository" firestore:"repository"`
	Event      string `json:"event" firestore:"event"`
}

Wakeup is a durable, coalescible unit of refresh work.

type WebhookDelivery

type WebhookDelivery struct {
	ID         string
	Event      string
	Repository string
	Payload    []byte
}

WebhookDelivery is the verified, minimally parsed GitHub webhook envelope.

Jump to

Keyboard shortcuts

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