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

platform-go

module
v15.3.2 Latest Latest
Warning

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

Go to latest
Published: Oct 17, 2026 License: AGPL-3.0

README

platform-go

Go Reference codecov

A Go library of the things a product has: a noun with a table, its lifecycle, its transport, its permissions and its privacy obligations. Identity, billing, audit, webhooks, sagas and the rest ship a Store, the DDL for the dialects they serve, a mock, and — for the ones that have crossed — a gRPC or HTTP surface over them. The infrastructure they are built from is primitives-go, which this module requires; Primitives and Domains is the rule that says which is which.

Module: github.com/primandproper/platform-go/v15 Go: 1.27

Project Status & Stability

main is not a release channel. Anything on main that has not been cut into a tagged release is considered under active development — alpha/beta, unstable, and unsupported. Treat it as such.

This repository follows a deliberately conservative release model:

  • Only tagged releases are supported. If it isn't behind a version tag, it can change or break without notice, and no support or compatibility is promised for it.
  • main moves ahead of the latest release. New work — including breaking changes — lands on main well before it is deemed release-worthy. Two facts locate you at any moment, and both are derived rather than written down here: the module path in go.mod is the major that main is currently building toward, and the highest version tag is the latest supported release. Whatever is on main but not yet in that tag is subject to change — and immediately after a major bump, that is the entire major.
  • Semantic Versioning, enforced by Go's module paths. Breaking changes increment the major version and the module import path (/vN → /vN+1), so a major bump can never silently break a consumer that hasn't opted in. The path bump lands in the same change that makes the break, never as a follow-up, which is why main's major is frequently one ahead of anything you can fetch by tag.
  • No stability guarantees on unreleased APIs. Interfaces, config shapes, and package boundaries on main are subject to change until they ship in a release.

If you depend on this library, pin to a released tag — and note that @latest against a major that has no tag yet resolves to a commit on main rather than to a release. If you want to track upcoming work, main is fair game — just don't expect it to hold still.

Installation

go get github.com/primandproper/platform-go/v15@latest

Because breaking changes ride the major-version import path, upgrading across majors is an explicit, opt-in edit to your import paths — never a surprise from go get -u.

Design Patterns

Store, DDL, mock. A package that owns data ships a Store interface, a SQL implementation of it, the DDL for whichever dialects the matrix below grants it, and a moq-generated mock. Its statements are rendered into a checked corpus and executed through a generated querier, so a column renamed in a migration is a failed generate rather than a runtime scan error.

A write takes a Tx; a read takes an executor. Every exported store write reads (ctx, tx database.Tx, scope tenancy.Scope, ...) and every exported read reads (ctx, q database.SQLQueryExecutor, scope tenancy.Scope, ...). A Tx is producible only inside Client.WithTransaction, so the write's signature is a compile-time claim that the caller is already in a transaction — which is the point, because a consumer's write almost never travels alone: the row, its audit entry and its outbox event are one fact. The read takes the wider type so that a caller inside a transaction sees its own uncommitted writes.

Tenancy is a column, not a convention. A component that stores consumer data stores it for somebody, and that somebody is a tenancy.Scope — an opaque owner identifier, deliberately not a string, so a scopeless call fails to compile rather than matching everything. tenancy.Global() is the scope of data belonging to no tenant, so a single-tenant application passes it everywhere and behaves exactly as it did before. Scope in the column, scope in the query, and no read path that omits it.

Config subpackages. Each package has a config subpackage with env:-tagged structs and ValidateWithContext() (via go-ozzo/ozzo-validation), and logger/tracerProvider/metricsProvider arrive as WithX options rather than positionally. Absent means noop: a caller that wants no observability names none of it. An unrecognized provider name returns errors.ErrUnknownProvider rather than a working-looking noop, because a typo that silently discards every message is a production incident that looks like a healthy process.

OpenTelemetry throughout. Every store, transport and worker here instruments through primitives-go's observability, whose logging, tracing, metrics and profiling pillars a consumer supplies once and threads everywhere.

Error handling. Uses cockroachdb/errors for rich, wrapped error context, over the sentinels primitives-go's errors package defines, conventionally imported as platformerrors. Its errors/http and errors/grpc map the primitives and cannot import the tier above them, so everything here maps itself: audit, authentication/oauth2clients, authentication/passkeys, authentication/passwordreset, authentication/signin, billing, comments, dataprivacy, entitlements, identity, issuereports, links, mediaregistry, metering, notifications, operations, sessions, settings, shredding, waitlists and webhooks each export an HTTPMapper and a GRPCMapper beside their sentinels. The composition root registers all of them in one call — errormappers.Register(), which service.Register makes for a service built from a service.Config and a service assembled by hand makes itself. operations/http.New is the single exception, registering its own HTTP mapper because it was the only surface here that both answered through errors/http and belonged to a package on that list; dataprivacy/http is a second one now and deliberately did not follow it, because one door stays one door. internal/sentinelmatrix checks that every exported sentinel in those packages has a decision recorded and that it still holds on both transports.

Package Catalog

This module is the domain tier: a noun with a table, its lifecycle, its transport, its permissions and its privacy obligations. The providers behind an interface — cache, database, email, messagequeue, observability, routing, secrets, search and the rest of what every service is built from — are primitives-go, and its README catalogues them. Primitives and Domains is the rule that sorts a new package into one or the other.

Implementations are listed in parentheses. Where an implementation is a SQL dialect, SQL Dialect Support is the full matrix.

Identity & access
Package Purpose Implementations
identity Users, accounts, memberships and invitations, the lifecycle over them, and identity/privacy, the directory's contribution to a subject access request (seam: Hooks) postgres, mysql, sqlite (+ grpc)
authentication/signin Sign-in: the order the engines and the directory are used in, owning no table of its own — (+ grpc)
authentication/signin/refreshtokens The refresh tokens sign-in rotates: digest at rest, single use, grouped into one family per login postgres, mysql, sqlite
authentication/signin/magiclinks The sign-in links the passwordless door mails: digest at rest, single use, and a redemption that proves the address it was sent to postgres, mysql, sqlite
authentication/signin/recoverycodes The recovery codes a person keeps on paper for a lost authenticator: digest at rest, single use, spent by the door they prove, and authentication/signin/recoverycodes/privacy postgres, mysql, sqlite
authentication/signin/devices Opt-in: where each login was last renewed from, recorded by a hook over signin.Hooks, read back by a SignInAnnotator, swept at the login's deadline, and authentication/signin/devices/privacy (seam: Extractor) postgres, mysql, sqlite
authentication/phonecodes Short codes texted to a person who is not a user: digest at rest, single use, dead after too many wrong guesses, one live code per number, and authentication/phonecodes/privacy postgres, mysql, sqlite
authentication/passwordreset Password reset tokens and the flow that spends them: digest at rest, single use enforced by the store, redemption and password change in one transaction, and authentication/passwordreset/privacy (seam: Hooks) postgres, mysql, sqlite
authentication/webauthnsessions Passkey ceremony state that outlives one replica postgres, mysql, sqlite
authentication/passkeys The credentials a passkey registration produces, the sign count clone detection compares against, the Service that runs registration and named and discoverable login over them (seams: UserResolver, UsernameResolver, EnrollmentGate, AlternativeSignIn, Hooks), and authentication/passkeys/privacy postgres, mysql, sqlite (+ grpc)
authentication/oauth2clients An administered OAuth2 client registry, and authentication/oauth2clients/privacy (seam: Hooks) postgres, mysql, sqlite (+ grpc)
authentication/grants The tokens a third party granted this deployment, per subject per provider: sealed at rest, refreshed by compare-and-set, revocable from either side, and authentication/grants/privacy postgres, mysql, sqlite
authentication/oauth2serverstore The OAuth2 server's client and token tables postgres, mysql, sqlite
rbac Roles and permissions as rows, behind the policy interface postgres, mysql, sqlite
sessions Server-side sessions over cookies cache, database (+ http)
callers Who is calling: the interface, its extractor, and the refusal they share —
Product & commerce
Package Purpose Implementations
billing What a deployment sells, and what its customers paid: catalog, subscriptions, purchases, ledger (seam: Hooks) postgres, mysql, sqlite
entitlements Feature access & remaining quota —
metering Durable usage metering & quotas. Ships no privacy adapter, and its doc records the ruling postgres, mysql, sqlite
settings Per-user and per-account runtime settings: definitions, per-subject values, and settings/privacy (seam: Hooks) postgres, mysql, sqlite
comments Threaded comments on consumer-declared targets (seam: Hooks) postgres, mysql, sqlite
issuereports User-submitted issue reports with a triage lifecycle (seam: Hooks) postgres, mysql, sqlite
waitlists Pre-launch waitlists: signup lifecycle, and an unsubscribe that outlives the address (seam: Hooks) postgres, mysql, sqlite
series Standing appointments: a weekly rule, its occurrences written ahead, and their skips, moves and make-ups postgres, mysql, sqlite
links Opaque, expiring, single-use action links postgres, mysql, sqlite
Records, privacy & retention
Package Purpose Implementations
audit Tamper-evident audit log postgres, mysql, sqlite (+ grpc)
recording The audit entry and the outbox event a store write owes, written once on the write's transaction; each store's RecordingHooks is built over it —
dataprivacy Subject access & erasure requests postgres, mysql, sqlite
shredding Per-subject data keys that can be destroyed postgres, mysql, sqlite
retention Policy-driven expiry deletion postgres, mysql, sqlite
mediaregistry Object metadata rows over an object store, and mediaregistry/privacy (seam: Hooks) postgres, mysql, sqlite
Coordination & delivery
Package Purpose Implementations
outbox Transactional outbox postgres, mysql, sqlite
workqueue Leased work queue (SKIP LOCKED claim/complete/expire) postgres, mysql, sqlite
timers Durable one-shot scheduling (run once at time T, fleet-wide) postgres, mysql, sqlite
operations Long-running operations with durable state, two-tier progress, and streamed updates postgres, mysql, sqlite (+ http)
saga Linear durable sagas with compensations postgres, mysql, sqlite
webhooks Outbound webhook delivery (seam: Hooks) postgres, mysql, sqlite
notifications The in-app inbox, the device registry, the notifications/push fan-out (seam: Hooks), and notifications/mail, the outbox-queued implementation of every Mailer seam with its drain postgres, mysql, sqlite (+ grpc)
searchsync Reindexing worker driven by the outbox —
Tool surfaces
Package Purpose
mcptool What an MCP tool is built on: input and output schemas reflected off Go types and their doc comments, the mcptool/mcpdocs generator that carries those comments into a binary, and a grant gate per call over callers. issuereports/mcp, waitlists/mcp and webhooks/mcp are built on it, and so is a consumer's own tool
The composition root
Package Purpose
service One walk of one config that wires both modules
errormappers The one call that tells the two transport registries what these sentinels mean
privacyadapters The one call that puts every privacy adapter this module ships in a dataprivacy.Registry
The promises
Package Purpose
conformance This module's behavioural promises, written once and assertable against a subject that is either this module's own assembly or a consumer's running service

A surface's own package asserts what its handler decides, over a server that package built. conformance asserts what a client sees, over a server somebody else built — which is the half that was only ever checked in a consumer's repository, and therefore the half this module could break and learn about from somebody else's CI. See the package documentation for the three subjects and what each one proves.

Primitives and Domains

There were two kinds of package here and they have separated: the primitives left for primitives-go, and what stays is the domain tier. The rule that sorted them is the one to check a new package against before writing it, because it now decides which of the two repositories the package is written for, and it is one property — does the package own a table, or drive one.

primitives-go ships what every service is built from and no service is. Four kinds of thing qualify: a provider behind an interface (cache, email, messagequeue, ...); a transport whose shape is decided by something other than the consumer's domain (a probe, a protocol, a middleware contract, a third party's payload); the database and schema tooling stores are built with (database and its subpackages, filtering); and the cross-cutting values both tiers have to agree on (tenancy.Scope, the errors sentinels, clock). Nothing in it owns a table.

platform-go ships what a product has: a noun with a table, its lifecycle, its transport, its permissions and its privacy obligations. The test for a new package is whether an application with no users would still need it. If yes, it is a primitive.

The table below is this module's side of that sort. It is not the whole rule's answer and is not meant to be: what the primitives are is primitives-go's README to list, and a copy of that list here would be a second answer with nothing checking it.

What it is Packages
a noun with a table, and what it owes audit, authentication/grants, authentication/oauth2clients, authentication/oauth2serverstore, authentication/passkeys, authentication/passwordreset, authentication/phonecodes, authentication/webauthnsessions, billing, comments, dataprivacy, entitlements, identity, issuereports, links, mediaregistry, metering, notifications, operations, outbox, rbac, retention, saga, searchsync, series, sessions, settings, shredding, timers, waitlists, webhooks, workqueue
a domain flow over another domain's tables authentication/signin, recording
this module's promises about its own surfaces conformance
the vocabulary a domain transport shares callers, mcptool
the composition root that registers both tiers errormappers, privacyadapters, service

The second row is the one the rule's own wording anticipates when it asks whether a package owns a table or drives one. authentication/signin owns no schema: it is the order the engines and the directory are used in — read the handle, compare the hash, check the status, ask for the code, mint the token — and every row it touches is identity's. It is still emphatically the domain tier, because an application with no users has nobody to sign in, and because the refusals it collapses are a product decision rather than a mechanism. A package like it is the shape to expect as more domains arrive: the flows over the nouns, after the nouns.

It gained four tables without becoming one, and the split is where the sentence stays true. Refresh-token rotation needs rows — a digest, a family, a deadline — so those live in authentication/signin/refreshtokens; the passwordless door needs rows of its own for the same reason, so those live in authentication/signin/magiclinks; and the recovery codes that stand in for a lost authenticator are a set of single-use rows too, so those live in authentication/signin/recoverycodes. The fourth is the one signin never reaches for: a deployment that wants its "where you're signed in" screen to say where wires authentication/signin/devices over the hooks and the annotator seam signin already exposes, and one that does not records nothing. Each is a noun with a table like any other, while the flow above them holds the seams rather than the schemas. None of the four is a row of its own in the tier sort for the reason links/database and sessions/database are not: a nested package inherits its parent's tier by longest-prefix match, so it is classified by construction and a row would be a second answer with nothing checking it. A service that names none of the stores still signs people in with a password and still owns nothing, which is what keeps this row's claim about signin itself rather than about everything under its path.

recording is the same shape over two other nouns. It owns no schema: it is the audit entry and the outbox event every store write here owes, written once on the write's transaction through audit's recorder and webhooks' emitter, so that each store's RecordingHooks is a decision about what to record rather than a copy of how. It is a domain because both halves are about a resource an application has. recording/config is what makes it the default: a service built from service.Config with audit, webhooks and an outbox configured records every platform write without registering a hook.

The third row is the newer shape and it arrives for a different reason. callers owns no table either, and it is not a flow: it is the interface a consumer's authentication interceptor satisfies, the function that reads one off a context, the refusal an authorizer returns, and the optional second identity an operator acting as somebody else fills — names that every gRPC surface here reads and no two of them may disagree about. It is a domain because a principal is a user, the directory they are in and the account their request is against, and an application with no users has nobody to extract. It is a package of its own because it was declared in identity/grpc until /v14, so a consumer wiring only settings, or only comments, linked the directory, its generated querier, its migrations and its protobuf bindings in order to compile an interface with three methods on it. What makes that stay fixed is a test rather than this paragraph: callers imports nothing else in this module, and the only gRPC surface here that still reaches identity is authentication/signin/grpc, which renders a signed-in user and says so where the test can read it.

mcptool is in the same row, one transport over. The protocol is not its own — the MCP SDK is — but what it adds is: input and output schemas reflected off a domain's Go types and described by their doc comments, and the grant gate a tool call passes, reading the same callers principal and the same permission the gRPC method beside the tool declares. That gate is why it is a domain rather than a primitive, and the schemas are why it is exported rather than internal: a consumer's own tools describe a consumer's own rows, and a schema written out by hand beside a type is a second copy that drifts the day a field is added. It was internal until a consumer had tools of its own to build on it.

Eight of the paths above sit under a directory this module does not own the root of, and every one of them is under authentication/. Seven are a primitive with a store nested inside it — authentication hashes passwords and issues tokens in primitives-go, and authentication/passwordreset owns a table of them, as authentication/phonecodes owns a table of the codes texted to a person who is not a user; authentication/oauth2clients, authentication/oauth2serverstore, authentication/webauthnsessions and authentication/passkeys split the same way, the last two against one engine: the ceremony a login runs and the credential that ceremony produced are two tables, and the protocol between them is a primitive. authentication/grants is the same split facing the other way: the two OAuth2 packages are this deployment as the authorization server, and it is this deployment as the client, holding the tokens somebody else's server issued — the protocol is golang.org/x/oauth2's and the table is here. The eighth is authentication/signin, which is neither: it is a domain flow under a primitive's path, there because sign-in is what those engines are for and a signin at the root would hide that.

authentication/ is the one straddle parent that groups rather than indirects — eight related domain packages under a name a reader wants — which is why it is the one that stayed. Go is content with a parent directory holding no .go files, and six of them were exactly that: uploads/, authorization/, cryptography/ and search/ each held one child and no source, as did authentication/oauth2server/ and authentication/webauthn/. A directory in that shape shows a relationship to a package this repository does not hold — cryptography has never existed here — and a package path is the most breaking thing in Go, so the six were flattened inside the /v14 major rather than bought as a /v15 later. The children carry the relationship in their own names now: mediaregistry, rbac, shredding and searchsync at the root, and authentication/oauth2serverstore and authentication/webauthnsessions into the parent that stayed.

The nested stores are self-contained. What was not self-contained was the configuration: a config subpackage that picked a store by dispatching on a provider string named every package it might build from, so three of them named a table. The rule that predicts it is worth stating once, because it is what any future straddle will be measured against:

A config that takes a store as a parameter is clean; a config that builds one by dispatching on a provider string is stuck. The provider string exists because a second implementation exists, so it belongs with the implementation that created the choice.

So authorization/config, authentication/webauthn/config and authentication/oauth2server/config kept everything that needs no table and went to primitives-go, and the provider string, the store's own config block and the dispatch moved to a config subpackage beside the store, which stayed here: rbac/config, authentication/webauthnsessions/config and authentication/oauth2serverstore/config. The domain half embeds the primitive half's Config with no env tag on the embed, so every environment variable an operator sets resolves at the name it always did, and each package's doc.go records the decision and the two alternatives that were refused.

notifications/mobile was the mirror and needed no split at all: it named notifications only to spell a DI key, for a one-method interface it already owned, so notifications/config registers that narrowing instead and the push providers left with the other primitives.

None of this is enforced by prose. internal/tiercheck is the roster: every package in the tree is named, checked against this table in both directions, and a package ruled a primitive fails there, because a primitive is a package this repository does not hold. It checks the shape of the tree as well as the ruling on it — a directory holding no Go files and exactly one Go-bearing child fails, so a seventh indirecting parent cannot appear quietly and be discovered a tag too late. The direction the split bought — primitives-go imports platform-go from nowhere, ever — is checked on the other side, by primitives-go's internal/tierguard, which needs no roster because the answer is the same for every package in that module.

service is neither tier and is why the split did not split it: it is one walk of one config that registers both modules, and a consumer of both sees the wiring it saw before. errormappers is the small half of the same job — the one call that tells the two transport registries what the domain tier's sentinels mean — kept out of service so that a consumer wiring three packages by hand does not import the config tree to make it.

Transports

A component here that owns data ships a Store interface, a SQL implementation of it, the DDL for whichever dialects the matrix below grants it, and a mock. For most of them it stops there: the HTTP handlers over that store are not missing, they are yours, and a library that shipped them would be versioning your /api/v1/users on its own release cadence, in types your proto does not have, under a scoping rule it guessed.

All three of those were properties of a module that also held the primitives, and the split has answered each. The cadence is the domain tier's own now, since nothing else rides on a release it is in — a fix to retry is a primitives-go release a consumer takes without reading a migration note. The types are shipped: primitives-go ships filtering.proto inside its published module and a domain's .proto travels the same way from here — generated into Go beside it, and into a consumer's Swift, TypeScript and Kotlin from the same file. The scope is not guessed, because tenancy.Scope exists and a domain transport binds it off the caller rather than off a request field.

So the line moves, one domain at a time, and identity is the first across it. The paragraphs that follow are in the order they landed, and each names what its own crossing decided rather than its place in the queue: a domain that crosses next is a paragraph appended, not ten ordinals re-counted. identity/grpc serves the directory: its RPCs, the .proto they are described by, a typed client, and the permissions each one wants. What it still does not ship is the policy — who is calling is an interface the consumer's own authentication interceptor satisfies, and what each method requires is a default map a consumer composes into its own. That is the same bargain identity always stated, one layer further out: a consumer keeps its policy and whatever columns are genuinely its own, and does not keep a users table, the transaction-shaped code around one, or the service and converters over that.

authentication/signin crosses differently: it owns no table itself, and the one it drives is optional. It is sign-in — the order argon2, totp, tokens and identity are used in, which is the code every application writes over those four and the code where their bugs live. The engines each do one thing and store nothing; the directory stores what they produce and never calls them; nothing joined them up. What it decides is the refusals, and it collapses several of them into one sentinel on purpose, because telling an unknown handle from a wrong password is telling an attacker which half of the guess was right. What it refuses to decide is the rest: whether a second factor is mandatory, whether the administrative door exists, whether a sign-in outlives its token, how long each of the two lives and what a token carries are options with defaults. The one that brings a schema is WithRefreshTokenStore: name one and a sign-in hands back a rotating pair, where a spent token presented a second time ends the login rather than sharing it; name none and the service is what it was before, one token per sign-in and no rows anywhere. authentication/signin/grpc serves all of it, and is the one surface in the module that reads its tenant off the connection rather than off a caller — because a caller signing in has not become one yet.

It also turns its own tokens back into callers, which it once left to the consumer. That ruling now covers only tokens this module did not mint. For a token signin minted, resolved through identity's directory, every input was already this module's, and every consumer wrote the same interceptor over them. One consumer's copy got the part that matters most wrong: it gave an administrator's ordinary sign-in their service roles. signingrpc.NewPrincipalExtractor verifies the token and resolves the principal through the read that refuses a banned user. It carries the login's family so ListSignIns can mark the current one, and grants service roles only on a token minted through the administrative door. A seam can say what an ordinary-door token keeps; by default it keeps none. Grants come from the consumer's role policy. WithAccessTokens extends it to OAuth2 access tokens, over primitives-go's oauth2server.Verifier: the verifier owns the audience and scope checks, the directory owns the subject, and the join between them — which a WithFallback extractor could not make, since it cannot answer a missing scope as a 403 or a banned subject as anything but nobody — is written once here rather than once per resource server. A deployment that accepts a third kind of token chains its own extractor in behind this one. Its interceptors enforce a table of which methods need a caller. The table is built from each surface's own method lists, and a method nobody declared is refused. The application installs it: service builds no extractor, so a composition root names it to service.Transports and puts its interceptor in the gRPC chain and its middleware on the router.

Somebody acting as somebody else. This module once ruled impersonation not a platform notion: every layer had room for one identity, so the only way to fit an operator into a request was to put the subject's ID where the actor's belonged — a working system, and an audit trail that says the subject did it. The objection stands; it is the reason for a second slot rather than for none, because the deployments with an operator tool told that lie anyway, in their own interceptors. The platform owns the mechanism and the deployment owns the policy. callers.Delegated is the optional interface a principal answers with the operator behind it, and callers.ActorOf names who is really acting. signin.Service.IssueImpersonationToken mints a short-lived token with no refresh token behind it, carrying signin.ClaimActor, and refuses every call with ErrImpersonationDisabled until WithImpersonationPolicy names the rule — the platform names no permission for it. signingrpc's extractor turns the claim back into a Delegated caller and refuses it once the operator is banned. audit.Actor.Impersonator records the operator beside the subject the entry is filed under, in a column inside the hash chain, so audit.Query.ImpersonatorID, audit/privacy's export and audit.Erasure.CountMentions all find the operator. Whether an impersonated request carries the operator's grants or the subject's is the consumer's GrantsResolver's call, and no RPC exposes the door: it belongs behind the deployment's own operator surface.

audit crosses too, and it is the one that ships strictly narrower than its own interface. audit/grpc serves the Reader and nothing else: read one entry, page them, verify a scope's hash chain. Record is not there and cannot be — an audit entry that can commit while the change it describes rolls back, or the reverse, is not a record of what happened, which is the sharpest instance of the rule that a write already inside your transaction is not an RPC. ListAcrossScopes and GetAcrossScopes are not there either: they are the operator's reads of every tenant's events, so the scope binds off the connection and the schema reserves the field name, which makes the absence something protoc enforces rather than something a reviewer has to notice. What makes the crossing worth it is Verify — establishing that nobody edited, removed or reordered an entry is the capability a hand-written log reader never gets around to, and the one most worth calling remotely and on a schedule, which is why it is its own grant rather than a second use of the read one.

notifications crosses in both halves, and they cross for two different reasons. The inbox half is the bell icon — list, list unread, get, mark one read, mark them all read, archive — which is the screen every consumer's application has and the code every consumer otherwise writes. The registry half is the strongest RPC case anywhere in the ten, because the caller is literally a remote device: a handset re-registers on every app launch and every token rotation, and the registration converges on (platform, token) rather than inserting, so a handset that changes hands has one owner.

Three of its store methods stay behind, and they are three different shapes of machinery rather than three instances of one — which is why this is the package the distinction is worth reading in. CreateNotification is the transactional companion: it files a notification in the caller's transaction so that it commits with the thing the notification is about, and an RPC would give you a refused order that has already told somebody it shipped. ListDevicesByPrincipals is the internal fan-out, one query for the tokens an announcement has to reach. InvalidateDeviceToken is the provider callback hook, and it is the one absence that is a security property rather than a shape: it removes a token whoever it belongs to, on the word of APNs or FCM, and published as an RPC it would delete any handset's registration in any tenant on the say-so of a caller claiming a provider said so. Nor does any response carry a device token: it travels in on one message, in one direction, so listing devices cannot become the call that harvests every push address an account holds.

comments is across as well, and it is the surface where the opaque-catalog ruling is load-bearing. Threading one level deep, scoping, paging, editing, archiving and erasing is the same code in every application; what varies is the catalog of things that can be commented on, and the package already refuses to guess at it. That refusal is what makes a transport safe to ship: a target type stays an opaque string in the proto rather than becoming a generated enum, so adding a newsletter is your release and not ours, and the optional existence check stays a Go func on your side of the surface. Two other things come off the connection rather than out of a request field, and the schema reserves both names so they cannot come back: the scope, as everywhere here, and the author — a comment is a sentence attributed to somebody, and attribution a client could choose says whatever the client wanted. What that leaves is the second question a grant on the method cannot answer, whose comment this is, and comments/grpc ships it as a seam with a closed default: say nothing and authors edit and archive their own words and nobody else's.

webhooks is the one where the interesting half of the ruling is what stayed behind. Endpoint CRUD, subscription CRUD and the delivery log are on the wire, which is endpoint management: the half of webhooks that is a resource rather than a protocol, and the only half a person ever touches. The rest of its store is the delivery pipeline, and Enqueue is the one worth naming here because it is the only absence that is genuinely consumer-facing. It writes a delivery and one dispatch per endpoint in the caller's transaction, so that both commit with whatever else that transaction did; an RPC moves the write into a transaction of its own, at a moment the caller does not choose, and what you get back is a delivery for a row that rolled back or a committed row nobody was told about. The other thing that does not cross is an endpoint's signing keys: they travel in on exactly one request and there is nowhere in the schema for a response to put them, because a key readable back over an administrative API is a key anyone who can read that API can forge deliveries with.

billing crosses read-biased. billing/grpc serves part of its store: the catalog and its administration, an account's own subscriptions, purchases and ledger, an operator's page over each of those three, and the Archive* set. The absences are the interesting half. Most are writes whose caller is not a client at all — a Stripe or RevenueCat callback, or the checkout handler that created the payment intent, each already inside a transaction that is also writing an audit entry and an outbox event — and the lookups by a payment provider's identifier belong to that same callback path; the last is the existence check a write makes on its way to inserting. What the surface refuses to ship is a reading: there is no GetAccountStanding and no is_active field anywhere in billing.proto, because which reported status leaves an account entitled is your policy. Two packages beside the store are where it lives: billing/plans turns a set of subscriptions into the plan a caller is on, and billing/standing turns a status a processor reported into the standing identity stores. Each ships the strict reading as a value you pass rather than a default you inherit, so taking it is a deployment agreeing with it. billing/sync is the third package beside the store and the only one that writes: it is the order those store methods are called in when a processor delivery arrives — look the agreement up by the provider's identifier, open it or move its status and paid period, acknowledge a redelivery — on the handler's own transaction, taking the other two packages' readings as arguments rather than making either of them itself.

issuereports is the one whose interesting half is a single method. All but one of its store's methods are on the wire — the filing, the reads, the queue listings, the revision, the archive and the move — and the move is why the surface is worth having. TransitionReport is a compare-and-set: it carries the status the caller believed the report held as well as the one it should move to, and the statement requires the row to still hold the first. Without that guard, two triagers resolving the same report both succeed, the second note overwrites the first, and nothing anywhere says so. A wire widens the window between the read a decision was made from and the write that records it from microseconds to a screen and a person, so the conflict is the ordinary case there rather than the rare one, and ErrStatusConflict is a refusal a client acts on: re-read, and decide about the status it is in now.

The one that stays behind is DeleteReportsByReporter, which destroys every report one person filed. It runs inside the caller's transaction so that a subject's reports and the rest of their footprint commit or roll back together, and an RPC is exactly a caller choosing when that commit happens. It is reached through issuereports/privacy, from your own erasure run. The other thing the surface does not carry is a reporter on any write: a report is filed by whoever is calling, and one a client could name is a report filed in somebody else's words.

settings is the one where the interesting half of the ruling is a proto design decision. All but one of its store's methods are on the wire, split into the two audiences the store already splits into: a catalog an operator administers, and the answers a person gives about themselves. Resolve is the point of it — a stored value falling back to the definition's default, so that anybody who has not chosen gets an answer rather than a missing row — and it is the method a hand-written service gets subtly wrong. So a resolved value crosses typed, as a oneof of the four kinds settings.Kind names, rather than as the text the row holds plus the kind to parse it with: putting the parse on the wire is putting the bug on the wire, one generated client at a time. The definition's default and its allowed values stay strings, because those are what a write is checked against byte for byte, and a typed round-trip would rewrite the bytes the check is made with. The method that is not, DeleteValuesForSubject, is erasure and stays behind for the reason every erasure does: it commits inside the transaction that removes the rest of the person.

waitlists is the one where nothing stayed behind. Every one of its store's methods is on the wire, which is unusual on this lane: every carve-out elsewhere is one test applied to different machinery — is the realistic caller a worker on a timer, a processor callback, or your own code inside your own transaction — and a waitlist has no queue protocol, no fan-out and no provider callback. What it has instead is two audiences. Five RPCs are the signup page — the open catalog, the form, the confirmation link, and the two ways off the list — and are reached by somebody who has not signed in and, on a pre-launch list, has nothing to sign in to; the rest are whoever is running the launch. So the tenant comes off the caller where there is one and off the connection where there is not, which is authentication/signin/grpc's arrangement applied to half a surface. And Withdraw is public and names a row, which no grant on a method could ever have been about, so the standing to move that row is a seam a consumer answers. The link in a mail does not need that seam: built with WithConfirmation, the surface runs the double opt-in itself — a join is held pending, a confirmation link and an unsubscribe link are minted through links and handed to the consumer's mailer, and Confirm and Unsubscribe redeem them, with the token as the whole of the standing. The read that stayed administrative is the one worth naming: "is this address on this list" is what the table holds, and answering it to anybody who can reach the port would make the surface an oracle over it.

Ten more were ruled on together, and each is to follow identity. The transport is not uniform and neither is the subset of a store that crosses:

package verdict transport carved out, and why
waitlists wire surface, full gRPC —
comments wire surface, full gRPC the two bulk deletes — erasure machinery
issuereports wire surface, full gRPC DeleteReportsByReporter — erasure machinery
settings wire surface, full gRPC DeleteValuesForSubject — erasure machinery
notifications wire surface, both halves gRPC CreateNotification, ListDevicesByPrincipals, InvalidateDeviceToken
webhooks wire surface, management + history gRPC Enqueue, EndpointsForEvent, and the delivery machinery its store documents
billing wire surface, read-biased gRPC the four status moves, whose caller is a processor callback already inside your transaction
audit wire surface, read-only and scope-bound gRPC Record, GetAcrossScopes and ListAcrossScopes
dataprivacy wire surface over the existing Service HTTP —
mediaregistry binding for the bytes, wire surface for the rows HTTP and gRPC GetObjectByKey — a key is not an address; ListObjects — an operator's read; ArchiveObjectsForOwner — erasure machinery

mediaregistry's row was first ruled a binding alone — the guarded serve, with every store method kept off the wire on the premise that a listing is a resource surface over a consumer's noun. The premise did not hold: nothing in the registry is the consumer's noun. An object is bytes in a bucket and the row saying whose they are, and every rule a product has about them — which types, how large, where in the bucket, what gets metered — is a value rather than a shape. So mediaregistry/grpc ships beside the serve route, with each of those rules an option carrying a default: uploading as a client stream that is never buffered, registering bytes already in the bucket under the caller's own part of it, and reading back what is theirs, with every refusal answered as an absence. An upload may be attached to its sender or to nothing; an attachment to one of your nouns goes through your own RPC, which authorizes the subject and calls mediaregistry.StoreAndRecord.

Seven get nothing, and saying so is the point of this section rather than leaving them unmentioned: metering, saga, timers, workqueue, outbox, retention and entitlements are machinery. Their methods are called by a worker on a timer, or by your own code inside your own transaction, which is the same test the carve-outs above are made by. Owning a store is not what puts a package on the list; having a caller who is somebody else is.

series arrived after that ruling and is on neither list yet. By the same test it is owed a surface — skip, close, end, move and make up are pressed by a person, not a timer — and only its horizon worker is machinery. It ships without one until it has its own ruling, and its first consumer draws its week view from the store in-process.

One of the ten is not the house default, and it has a stated reason. dataprivacy is on HTTP because its flow already is. Progress is answered by operations/http against Request.OperationID and the same event stream every other long-running thing here uses, Confirm is reached by somebody clicking a link in a mail the notifier sent, and the artifact arrives as a freshly minted, expiring DownloadURL. A gRPC surface would put submit, confirm and cancel on one protocol while the confirm click, the progress stream and the download all lived on another.

The flows over those nouns are the other half of the same list, and sign-in was the first of them. Password reset is the second: authentication/passwordreset ships a Service beside its Store, which mails the link after the commit rather than inside it and spends it with the password change and the revocation in one transaction. Passkeys are the third: authentication/passkeys/grpc runs the ceremonies over authentication/passkeys' Service and answers a finished login with sign-in's own token, minted through IssueForPrincipal, so a passkey is another way into the same sign-in rather than a second token stack. Session management and email verification are each their own addition over an engine this module already ships, rather than a branch inside the password flow.

The line the primitives are held to went with them. It read: a module ships a transport for a primitive only where the shape of the request is decided by something other than the consumer's domain — a probe, a protocol, a middleware contract, or a third party's payload — and the probes, the middleware and webhooks/inbound's receiver for a Stripe or GitHub callback are primitives-go's to hold to it. What is left here is the second half of that sentence, and it is the whole list.

Transport Kind Whose shape it is
billing/http binding a payment provider's callback, whose status code the provider acts on
mediaregistry/http binding an object's bytes, guarded by the row rather than by knowledge of the key
sessions/http binding a signed cookie, whose security properties are ours
audit/grpc resource surface reading the audit log and verifying its chain — over audit.Reader
authentication/oauth2clients/grpc resource surface an administered OAuth2 client registry — over oauth2clients.Service and oauth2clients.Store
authentication/passkeys/grpc resource surface enrolling a passkey and signing in with one, into sign-in's token — over passkeys.Service
authentication/passwordreset/grpc resource surface ask for a reset link, check one, spend one — over passwordreset.Service
authentication/signin/grpc resource surface sign-in and the credentials a person changes about themselves — over signin.Service
billing/grpc resource surface the catalog, the agreements, the sales and the ledger, read-biased — over billing.Store
comments/grpc resource surface one noun and its whole lifecycle — over comments.Store
dataprivacy/http resource surface submit, confirm, cancel and read a privacy request, and download an export — over dataprivacy.Service
identity/grpc resource surface the four nouns and their lifecycle — over identity.Service and identity.Store
issuereports/grpc resource surface the report queue and its guarded lifecycle — over issuereports.Store
issuereports/mcp resource surface read-only MCP tools — one report, the queue, the queue by status, one person's reports — over issuereports.Store
mediaregistry/grpc resource surface uploading, registering and reading back the caller's objects — over mediaregistry.Store and uploads.UploadManager
notifications/grpc resource surface the in-app inbox and the device registry — over notifications.Inbox and notifications.Registry
operations/http resource surface poll, list, cancel, subscribe — over Operation
settings/grpc resource surface the catalog, the answers stored against it, and what a setting resolves to — over settings.Store
waitlists/grpc resource surface the catalog, the queue and the two audiences that reach them — over waitlists.Store
waitlists/mcp resource surface read-only MCP tools — the waitlist catalog, whole and open, never the signups — over waitlists.Store
webhooks/grpc resource surface endpoint management, subscriptions and the delivery log — over webhooks.Dispatcher and webhooks.Store
webhooks/mcp resource surface read-only MCP tools — endpoints without their headers, and the event catalog — over webhooks.Store and webhooks.Dispatcher

The bindings are not surfaces. sessions/http binds a store to a cookie, and a cookie's signing, encryption, HttpOnly, Secure and SameSite are security decisions this module already made — there is no resource of yours in it.

mediaregistry/http makes the same claim about an object's bytes. Its store's documentation heads a section "Why the row is the access control" — whether this caller may read this object is answered from the owner and the scope on the row, not from the bucket — and then declines to act on it, because nothing in that package opens, reads or removes an object. The rows cross on mediaregistry/grpc; the bytes cross here, because the guarded serve is the half that gets written wrong: an unguessable key as the only protection a private document has, and a key is not a secret. What crosses instead is one route and the guard in front of it, and the decisions that come with it are security properties rather than API design — the row is read before the bucket is opened, a refusal is indistinguishable from an absence, a content type a browser executes is never served inline, and nothing is cached by a shared proxy. There is no resource of yours in that either: what is on the wire is bytes and a content type.

billing/http binds a payment provider's callback to billing/sync. The payload is the provider's and the verification is capitalism's; what is left is the status code, which the provider acts on and the hand-written endpoints got wrong — a 400 for a database that blinked tells the provider to drop the delivery. That code is decided here, once: 400 only for a delivery that failed verification or could not be parsed, 500 for anything a retry could fix.

The rest are resource surfaces, and they get there by two routes. operations/http is entirely this module's own resource: an Operation, its two-tier progress and its state machine are types you did not define, and polling one or subscribing to its server-sent events is the pattern's protocol rather than your API. Starting an operation is yours, and is deliberately not there. identity/grpc, authentication/signin/grpc, authentication/passwordreset/grpc, authentication/passkeys/grpc, authentication/oauth2clients/grpc, dataprivacy/http, audit/grpc, notifications/grpc, comments/grpc, webhooks/grpc, billing/grpc, issuereports/grpc, mediaregistry/grpc, settings/grpc and waitlists/grpc are the other kind — a domain's own transport, shipped under the rule above rather than as an exception to it, and every resource surface but operations/http has crossed this way. All of those are gRPC but one, for the reason given above: dataprivacy's flow was on HTTP before there was a handler in it.

Who may use a route. Every gRPC surface declares a namespaced permission per method in its permissions.go, and three of the HTTP ones do too, per route: dataprivacy/http, mediaregistry/http and operations/http each export a Permissions map keyed by route (POST /operations/{operationID}/cancel), the Route… constants those keys are spelled with, and OwnStandingRoutes — the routes reached on what the caller is rather than on a grant. There are three of those: following an operation by polling it or subscribing to it, which is how a person watches their own export or erasure, and dataprivacy's confirmation link. The platform declares the permissions and grants none; which a member holds is the consumer's policy, exactly as on gRPC, and withholding a route's permission is how a deployment keeps that route to its operators. Each surface checks its routes with the authorization/http enforcer the consumer builds over the grants its gRPC interceptor reads — WithEnforcer, or service.Transports.HTTPEnforcer for all three — before anything is read, so a caller without the grant is refused as 403 whether or not the identifier they named exists. A surface given no enforcer refuses every route its Permissions names rather than serving it, which is what a fail-closed gRPC enforcer does with a method nobody declared. authorization/http cannot fail closed on a route nobody guarded, so each surface's own tests mount its real handlers and check that every route is in exactly one of the two lists. The fourth HTTP surface, the OAuth 2.1 authorization server service mounts from Config.OAuth2Server, declares none: it authenticates its own callers, a client by its secret at /token and /revoke and a person at /authorize.

The table is not written by hand either. internal/cmd/readmegen emits it on make generate from the http and grpc directories the tree ships, and refuses to emit a row for one whose own doc.go does not name its kind and whose shape it is standing in for. A package that grows handlers therefore cannot reach main without somebody having said which side of the line they fall on.

The client contract

What a client of one of those transports owes is written down too, once, in docs/client-contract.md: the seams a client injects, the sign-in state machine, refresh token rotation, the error channels to branch on, and pagination. It is in no particular language, and platform-client-ts and platform-client-swift implement it rather than each reconstructing it from the proto comments.

It lives here rather than beside either client for the reason the protos do: it describes this module's wire behaviour, so a change to that behaviour updates it in the pull request making the change. Where a rule needs a server newer than some tag, it names the tag — the clients pin one, and a rule describing unreleased main is a rule that breaks a session.

SQL Dialect Support

database speaks Postgres, MySQL and SQLite, and so does every package that stores anything through it. A package that narrowed would be spoken for here — once, before you choose packages, rather than package by package as each constructor refuses at wiring time.

A ✓ means the package ships DDL for that dialect, and — for every package whose statements have been ported onto the generated tier — executes a querier emitted against it. Everything unticked returns dialect.ErrUnsupported at construction, never a partial store or a migration that creates nothing.

MySQL means MySQL 8, and that is a narrowing rather than a clarification. Every container suite here ran against MariaDB from this repository's first commit, with no reason recorded anywhere for why — so the column said mysql, the tests verified MariaDB, and nobody could tell from either which one was promised. They now agree: the suites run mysqltest's own default, which is stock MySQL 8.

The gap was not free while it lasted. MariaDB has no FOR SHARE, which shaped statements elsewhere in this module, and it answers a concurrent UPDATE that filters on the column it assigns with ER_CHECKREAD where MySQL 8 resolves the same situation internally — a failure this module carried without knowing which engine it was for.

A MariaDB deployment is therefore untested rather than unsupported. Nothing refuses it, the DDL and the statements are the constrained subset MariaDB accepts, and it will very likely work. What is gone is anybody checking — so a consumer running MariaDB owns that verification, and the honest expectation is that the next difference between the two engines is found by them rather than here.

Package Postgres MySQL SQLite
audit ✓ ✓ ✓
authentication/grants ✓ ✓ ✓
authentication/oauth2clients ✓ ✓ ✓
authentication/oauth2serverstore ✓ ✓ ✓
authentication/passkeys ✓ ✓ ✓
authentication/passwordreset ✓ ✓ ✓
authentication/phonecodes ✓ ✓ ✓
authentication/signin/devices ✓ ✓ ✓
authentication/signin/magiclinks ✓ ✓ ✓
authentication/signin/recoverycodes ✓ ✓ ✓
authentication/signin/refreshtokens ✓ ✓ ✓
authentication/webauthnsessions ✓ ✓ ✓
billing ✓ ✓ ✓
comments ✓ ✓ ✓
dataprivacy ✓ ✓ ✓
identity ✓ ✓ ✓
issuereports ✓ ✓ ✓
links/database ✓ ✓ ✓
mediaregistry ✓ ✓ ✓
metering ✓ ✓ ✓
notifications ✓ ✓ ✓
operations ✓ ✓ ✓
outbox ✓ ✓ ✓
rbac ✓ ✓ ✓
saga ✓ ✓ ✓
series ✓ ✓ ✓
sessions/database ✓ ✓ ✓
settings ✓ ✓ ✓
shredding ✓ ✓ ✓
timers ✓ ✓ ✓
waitlists ✓ ✓ ✓
webhooks ✓ ✓ ✓
workqueue ✓ ✓ ✓
Why nothing narrows

One reason, and it is a claim rather than a translation. On Postgres the claim is a single statement that selects due rows, locks them with SKIP LOCKED, increments attempts, extends the lease and hands the keys back with RETURNING. MySQL has SKIP LOCKED but no RETURNING, and SQLite has neither and no row locks at all, so on those two the same claim is several statements held in one transaction: a read, an update and a read-back by the claim's name.

That is a cost rather than a reason to narrow, and workqueue and timers pay it: each keeps its Postgres claim as the one statement, and on MySQL and SQLite splits it, fenced by the name the claim mints so that a write can land only under the claim that took the row. timers locks its candidates by primary key rather than by the range that found them, because on MySQL a locking range read also locks the first row past it — the next set's earliest timer, as often as not. webhooks and outbox already claimed that way on all three, and operations followed workqueue: its guarded writes hand their row back through RETURNING on Postgres and read it back on the same transaction on the other two. No package narrows today. One that did would state where it stands in its own doc.go, and this list is that statement:

Widening one is the port workqueue, timers and operations took, not a new design: one package, a statement set per shape its dialects need, and a switch on the client's dialect at construction — never a provider subpackage per database.

Narrowings that are not rows

Some dialect-dependence is a capability inside a package that serves all three, and a row would misreport it either way:

  • outbox stores and relays on all three. Its LISTEN/NOTIFY wakeup is Postgres-only and reported as outbox.ErrNotifyUnsupported if configured elsewhere; without it a relay polls, which is later rather than wrong. Its SKIP LOCKED claim mode degrades to a lease on SQLite — which claims just as exclusively, by guarding the write on the lease it read, and only contends where the lock would have skipped.
  • workqueue queues on all three. Its LISTEN/NOTIFY wakeup is Postgres-only and reported as workqueue.ErrNotifyUnsupported if configured elsewhere; without it a worker polls, which is later rather than wrong.
  • operations runs on all three. Its LISTEN/NOTIFY push to watchers is Postgres-only and reported as operations.ErrNotifyUnsupported if configured elsewhere; without it a watcher polls, which is later rather than wrong.
  • timers schedules on all three. Its LISTEN/NOTIFY wakeup is Postgres-only and reported as timers.ErrNotifyUnsupported if configured elsewhere; without it a poller sleeps to the next instant it knows about or its poll, which is later rather than wrong. SQLite keeps instants to the millisecond, and a scheduled instant is rounded up to one, never down.
  • retention sweeps all three, and ships no DDL: the table, the timestamp column and the batch key arrive from a Policy written at run time, so there is no schema of this module's to render for a dialect.

A primitive that names a dialect is the same case and is primitives-go's to report: distributedlock/postgres and search/vector/pgvector are named providers beside memory, redis and qdrant, chosen by config the way cache/redis is, and picking one is picking Postgres, which is what its name says.

The matrix above is not written by hand. internal/cmd/readmegen emits it on make generate from the DDL each package ships, checks that against the dialects its generated querier was emitted for, and refuses to emit a short row for a package whose doc.go does not say why it is short. A package that gains or loses a dialect therefore changes this file on the next generate, and the generated-files workflow reds until that change is committed.

Development

make setup          # Install dev tools and download deps
make format         # Format all Go code (imports, field/tag alignment, gofmt)
make lint           # Run golangci-lint (Docker) + shellcheck
make test           # Run tests (race detector, shuffle, failfast)
make build          # Build all packages
make generate       # Regenerate moq mocks after changing a mocked interface
make bench          # Run benchmarks

Formatting runs locally with gci, goimports, betteralign, tagalign, and gofmt. Linting runs in Docker against the golangci/golangci-lint image (42+ linters, golangci-lint v2 format).

Testing conventions
  • stretchr/testify is banned (assert, require, and mock), enforced by depguard. Use shoenig/test for assertions (test for non-fatal, must for fatal) and matryer/moq for mocks.
  • Tests run in parallel by default and use subtests throughout.
  • Container-backed tests use testcontainers-go, live in-package (typically containers_test.go), and gate on RUN_CONTAINER_TESTS=true.
  • make test runs CGO_ENABLED=1 go test -shuffle=on -race -vet=all -failfast ./... across every package. .scripts/test.sh false runs the suite without container tests.

Contributing

Because main is a development channel and only tagged releases are supported, changes land on main freely and are stabilized before release. Follow the existing package layout (the store, its config subpackage, its migrations, its rendered query corpus and its mock), match the surrounding code, and keep make format lint test green. A package that turns out to be a primitive belongs in primitives-go instead — Primitives and Domains is the rule, and internal/tiercheck fails a roster entry that claims one.

Directories

Path Synopsis
Package audit is the durable, queryable, tamper-evident record of who did what to which resource.
Package audit is the durable, queryable, tamper-evident record of who did what to which resource.
config
Package auditcfg assembles the audit log from environment configuration: the Recorder applications write through, the Reader they query and verify with, and the retention.Policy that prunes it.
Package auditcfg assembles the audit log from environment configuration: the Recorder applications write through, the Reader they query and verify with, and the retention.Policy that prunes it.
grpc
Package grpc is the audit log on the wire: the gRPC service over github.com/primandproper/platform-go/v15/audit's Reader, the converters between the generated messages and its types, a typed client, and the default permission fragment a consumer composes into its policy.
Package grpc is the audit log on the wire: the gRPC service over github.com/primandproper/platform-go/v15/audit's Reader, the converters between the generated messages and its types, a typed client, and the default permission fragment a consumer composes into its policy.
grpc/client
Package client is a typed client for the audit log's gRPC service.
Package client is a typed client for the audit log's gRPC service.
internal/queries
Package queries is the audit schema described as data — the two canonical table names and their columns in the order every read projects them — and the statements run over it, rendered for each of the three dialects audit serves.
Package queries is the audit schema described as data — the two canonical table names and their columns in the order every read projects them — and the statements run over it, rendered for each of the three dialects audit serves.
internal/queriesgen command
Command queriesgen writes the canonical sqlc input for the audit schema, one file per dialect, from audit/internal/queries.
Command queriesgen writes the canonical sqlc input for the audit schema, one file per dialect, from audit/internal/queries.
migrations
Package migrations supplies the audit tables' DDL, rendered for a dialect and table prefix.
Package migrations supplies the audit tables' DDL, rendered for a dialect and table prefix.
mock
Package auditmock provides moq-generated mock implementations of interfaces in the audit package.
Package auditmock provides moq-generated mock implementations of interfaces in the audit package.
privacy
Package privacy is the audit log's contribution to a subject access request: a dataprivacy.Collector that returns the entries in which the subject acted, was acted on, or acted as somebody else.
Package privacy is the audit log's contribution to a subject access request: a dataprivacy.Collector that returns the entries in which the subject acted, was acted on, or acted as somebody else.
authentication
grants
Package grants stores the tokens a third party granted this deployment: one standing credential per subject per provider, sealed at rest, refreshed by compare-and-set, and revocable from either side.
Package grants stores the tokens a third party granted this deployment: one standing credential per subject per provider, sealed at rest, refreshed by compare-and-set, and revocable from either side.
grants/config
Package grantscfg assembles a third-party grant Store from environment configuration.
Package grantscfg assembles a third-party grant Store from environment configuration.
grants/internal/queries
Package queries is the third-party grant schema described as data: the canonical table name, its columns in the order every read projects them, and the nine statements the store executes over them.
Package queries is the third-party grant schema described as data: the canonical table name, its columns in the order every read projects them, and the nine statements the store executes over them.
grants/internal/queriesgen command
Package main renders authentication/grants/internal/queries into the canonical .sql files beside it, one per dialect, and prints the schema those files are checked against.
Package main renders authentication/grants/internal/queries into the canonical .sql files beside it, one per dialect, and prints the schema those files are checked against.
grants/migrations
Package migrations supplies the third-party grant table's DDL, rendered for a dialect and table prefix.
Package migrations supplies the third-party grant table's DDL, rendered for a dialect and table prefix.
grants/mock
Package grantsmock provides moq-generated mock implementations of interfaces in the grants package.
Package grantsmock provides moq-generated mock implementations of interfaces in the grants package.
grants/privacy
Package privacy is the third-party grant table's contribution to a subject access request: a dataprivacy.Collector that returns the accounts somebody connected, and a dataprivacy.Eraser that destroys the grants.
Package privacy is the third-party grant table's contribution to a subject access request: a dataprivacy.Collector that returns the accounts somebody connected, and a dataprivacy.Eraser that destroys the grants.
oauth2clients
Package oauth2clients is an administered registry of OAuth2 clients: the registrations an operator or a person creates on purpose, as opposed to the ones an anonymous caller mints at /register.
Package oauth2clients is an administered registry of OAuth2 clients: the registrations an operator or a person creates on purpose, as opposed to the ones an anonymous caller mints at /register.
oauth2clients/authserver
Package authserver joins an administered client registry to the OAuth 2.1 authorization server in authentication/oauth2server.
Package authserver joins an administered client registry to the OAuth 2.1 authorization server in authentication/oauth2server.
oauth2clients/config
Package oauth2clientscfg assembles an oauth2clients Store and Service from environment configuration.
Package oauth2clientscfg assembles an oauth2clients Store and Service from environment configuration.
oauth2clients/grpc
Package grpc serves the administered OAuth2 client registry over gRPC.
Package grpc serves the administered OAuth2 client registry over gRPC.
oauth2clients/grpc/client
Package client is a typed client for the OAuth2 client registry gRPC service.
Package client is a typed client for the OAuth2 client registry gRPC service.
oauth2clients/internal/queries
Package queries is the registered clients schema described as data: the canonical table name, the table's columns in the order every read projects them, and the subsets each write assigns.
Package queries is the registered clients schema described as data: the canonical table name, the table's columns in the order every read projects them, and the subsets each write assigns.
oauth2clients/internal/queriesgen command
Package main renders the canonical sqlc input for the registered clients table, one .sql per dialect, from the table description in authentication/oauth2clients/internal/queries.
Package main renders the canonical sqlc input for the registered clients table, one .sql per dialect, from the table description in authentication/oauth2clients/internal/queries.
oauth2clients/migrations
Package migrations supplies the registered clients table's DDL, rendered for a dialect and table prefix.
Package migrations supplies the registered clients table's DDL, rendered for a dialect and table prefix.
oauth2clients/mock
Package oauth2clientsmock provides moq-generated mock implementations of interfaces in the oauth2clients package.
Package oauth2clientsmock provides moq-generated mock implementations of interfaces in the oauth2clients package.
oauth2clients/privacy
Package privacy is the client registry's contribution to a subject access request: a dataprivacy.Collector that returns the applications somebody registered, and a dataprivacy.Eraser that destroys them.
Package privacy is the client registry's contribution to a subject access request: a dataprivacy.Collector that returns the applications somebody registered, and a dataprivacy.Eraser that destroys them.
oauth2serverstore
Package oauth2serverstore keeps an authorization server's state in SQL tables.
Package oauth2serverstore keeps an authorization server's state in SQL tables.
oauth2serverstore/config
Package oauth2serverstorecfg assembles an OAuth 2.1 authorization server and its Store, choosing between SQL tables and memory.
Package oauth2serverstorecfg assembles an OAuth 2.1 authorization server and its Store, choosing between SQL tables and memory.
oauth2serverstore/internal/queries
Package queries is the authorization server's schema described as data: the four canonical table names, each table's columns in the order every read projects them, and the columns a write may leave NULL.
Package queries is the authorization server's schema described as data: the four canonical table names, each table's columns in the order every read projects them, and the columns a write may leave NULL.
oauth2serverstore/internal/queriesgen command
Command queriesgen writes the canonical sqlc input for the authorization server's schema, one file per dialect, from authentication/oauth2serverstore/internal/queries.
Command queriesgen writes the canonical sqlc input for the authorization server's schema, one file per dialect, from authentication/oauth2serverstore/internal/queries.
oauth2serverstore/migrations
Package migrations supplies the authorization server's DDL, rendered for a dialect and table prefix.
Package migrations supplies the authorization server's DDL, rendered for a dialect and table prefix.
passkeys
Package passkeys stores the credentials a WebAuthn registration produces, and runs the ceremonies that produce and verify them.
Package passkeys stores the credentials a WebAuthn registration produces, and runs the ceremonies that produce and verify them.
passkeys/config
Package passkeyscfg assembles a passkeys Store and Service from environment configuration.
Package passkeyscfg assembles a passkeys Store and Service from environment configuration.
passkeys/grpc
Package grpc serves passkeys over gRPC: enrolling one, signing in with one, and the list and archive a settings page offers.
Package grpc serves passkeys over gRPC: enrolling one, signing in with one, and the list and archive a settings page offers.
passkeys/grpc/client
Package client is a typed client for the passkeys gRPC service.
Package client is a typed client for the passkeys gRPC service.
passkeys/internal/queries
Package queries is the registered-passkey schema described as data: the canonical table name, its columns in the order every read projects them, and the seven statements the store executes over them.
Package queries is the registered-passkey schema described as data: the canonical table name, its columns in the order every read projects them, and the seven statements the store executes over them.
passkeys/internal/queriesgen command
Package main renders authentication/passkeys/internal/queries into the canonical .sql files beside it, one per dialect, and prints the schema those files are checked against.
Package main renders authentication/passkeys/internal/queries into the canonical .sql files beside it, one per dialect, and prints the schema those files are checked against.
passkeys/migrations
Package migrations supplies the registered-passkey table's DDL, rendered for a dialect and table prefix.
Package migrations supplies the registered-passkey table's DDL, rendered for a dialect and table prefix.
passkeys/mock
Package passkeysmock provides moq-generated mock implementations of interfaces in the passkeys package.
Package passkeysmock provides moq-generated mock implementations of interfaces in the passkeys package.
passkeys/privacy
Package privacy is the registered-passkey table's contribution to a subject access request: a dataprivacy.Collector that returns the passkeys somebody enrolled, and a dataprivacy.Eraser that destroys them.
Package privacy is the registered-passkey table's contribution to a subject access request: a dataprivacy.Collector that returns the passkeys somebody enrolled, and a dataprivacy.Eraser that destroys them.
passwordreset
Package passwordreset stores the token that lets somebody who cannot sign in prove they own the address the account was registered with, and ships the flow that spends it.
Package passwordreset stores the token that lets somebody who cannot sign in prove they own the address the account was registered with, and ships the flow that spends it.
passwordreset/config
Package passwordresetcfg assembles a passwordreset Store and Service from environment configuration.
Package passwordresetcfg assembles a passwordreset Store and Service from environment configuration.
passwordreset/grpc
Package grpc serves the password reset flow over gRPC.
Package grpc serves the password reset flow over gRPC.
passwordreset/internal/queries
Package queries is the password reset token schema described as data: the canonical table name, its columns in the order every read projects them, the subsets a write assigns, and the seven statements the store executes over them.
Package queries is the password reset token schema described as data: the canonical table name, its columns in the order every read projects them, the subsets a write assigns, and the seven statements the store executes over them.
passwordreset/internal/queriesgen command
Command queriesgen writes the canonical sqlc input for the password reset token schema, one file per dialect, from authentication/passwordreset/internal/queries.
Command queriesgen writes the canonical sqlc input for the password reset token schema, one file per dialect, from authentication/passwordreset/internal/queries.
passwordreset/migrations
Package migrations supplies the password reset token table's DDL, rendered for a dialect and table prefix.
Package migrations supplies the password reset token table's DDL, rendered for a dialect and table prefix.
passwordreset/mock
Package passwordresetmock provides moq-generated mock implementations of interfaces in the passwordreset package.
Package passwordresetmock provides moq-generated mock implementations of interfaces in the passwordreset package.
passwordreset/privacy
Package privacy is the reset token table's contribution to a subject access request: a dataprivacy.Collector that returns when somebody asked to reset their password, and a dataprivacy.Eraser that destroys the record.
Package privacy is the reset token table's contribution to a subject access request: a dataprivacy.Collector that returns when somebody asked to reset their password, and a dataprivacy.Eraser that destroys the record.
phonecodes
Package phonecodes is where a texted code lives: a short numeric credential sent to a phone number, stored as a digest, spent once, and dead after a handful of wrong guesses — for a person who is not a user.
Package phonecodes is where a texted code lives: a short numeric credential sent to a phone number, stored as a digest, spent once, and dead after a handful of wrong guesses — for a person who is not a user.
phonecodes/config
Package phonecodescfg assembles a texted-code Store from environment configuration.
Package phonecodescfg assembles a texted-code Store from environment configuration.
phonecodes/internal/queries
Package queries is the texted-code schema described as data: the canonical table name, its columns in the order every read projects them, and the eight statements the store executes over them.
Package queries is the texted-code schema described as data: the canonical table name, its columns in the order every read projects them, and the eight statements the store executes over them.
phonecodes/internal/queriesgen command
Command queriesgen writes the canonical sqlc input for the texted-code schema, one file per dialect, from authentication/phonecodes/internal/queries.
Command queriesgen writes the canonical sqlc input for the texted-code schema, one file per dialect, from authentication/phonecodes/internal/queries.
phonecodes/migrations
Package migrations supplies the texted-code table's DDL, rendered for a dialect and table prefix.
Package migrations supplies the texted-code table's DDL, rendered for a dialect and table prefix.
phonecodes/mock
Package phonecodesmock provides moq-generated mock implementations of interfaces in the phonecodes package.
Package phonecodesmock provides moq-generated mock implementations of interfaces in the phonecodes package.
phonecodes/privacy
Package privacy is the texted-code table's contribution to a subject access request: a dataprivacy.Collector that returns the numbers a person was texted a code at, and a dataprivacy.Eraser that destroys the rows.
Package privacy is the texted-code table's contribution to a subject access request: a dataprivacy.Collector that returns the numbers a person was texted a code at, and a dataprivacy.Eraser that destroys the rows.
signin
Package signin is the service every application rewrites: proving somebody is who they say they are, and handing back a token that says so.
Package signin is the service every application rewrites: proving somebody is who they say they are, and handing back a token that says so.
signin/config
Package signincfg assembles a signin Service from environment configuration.
Package signincfg assembles a signin Service from environment configuration.
signin/devices
Package devices records where each login was last renewed from, and answers it back on a "where you're signed in" screen.
Package devices records where each login was last renewed from, and answers it back on a "where you're signed in" screen.
signin/devices/internal/queries
Package queries is the sign-in device schema described as data: the canonical table name, its columns in the order every read projects them, the subsets a write assigns, and the five statements the store executes over them.
Package queries is the sign-in device schema described as data: the canonical table name, its columns in the order every read projects them, the subsets a write assigns, and the five statements the store executes over them.
signin/devices/internal/queriesgen command
Command queriesgen writes the canonical sqlc input for the sign-in device schema, one file per dialect, from authentication/signin/devices/internal/queries.
Command queriesgen writes the canonical sqlc input for the sign-in device schema, one file per dialect, from authentication/signin/devices/internal/queries.
signin/devices/migrations
Package migrations supplies the sign-in device table's DDL, rendered for a dialect and table prefix.
Package migrations supplies the sign-in device table's DDL, rendered for a dialect and table prefix.
signin/devices/mock
Package devicesmock provides moq-generated mock implementations of interfaces in the devices package.
Package devicesmock provides moq-generated mock implementations of interfaces in the devices package.
signin/devices/privacy
Package privacy is the sign-in device table's contribution to a subject access request: a dataprivacy.Collector that returns every address, user agent and device name recorded against a subject's logins, and a dataprivacy.Eraser that deletes them.
Package privacy is the sign-in device table's contribution to a subject access request: a dataprivacy.Collector that returns every address, user agent and device name recorded against a subject's logins, and a dataprivacy.Eraser that deletes them.
signin/grpc
Package grpc serves the sign-in service over gRPC.
Package grpc serves the sign-in service over gRPC.
signin/grpc/client
Package client is a typed client for the sign-in gRPC service.
Package client is a typed client for the sign-in gRPC service.
signin/magiclinks
Package magiclinks is where a sign-in link's tokens live: a digest-keyed, single-use credential mailed to an address and spent for a session.
Package magiclinks is where a sign-in link's tokens live: a digest-keyed, single-use credential mailed to an address and spent for a session.
signin/magiclinks/internal/queries
Package queries is the sign-in link schema described as data: the canonical table name, its columns in the order every read projects them, the subsets a write assigns, and the five statements the store executes over them.
Package queries is the sign-in link schema described as data: the canonical table name, its columns in the order every read projects them, the subsets a write assigns, and the five statements the store executes over them.
signin/magiclinks/internal/queriesgen command
Command queriesgen writes the canonical sqlc input for the sign-in sign-in link schema, one file per dialect, from authentication/signin/magiclinks/internal/queries.
Command queriesgen writes the canonical sqlc input for the sign-in sign-in link schema, one file per dialect, from authentication/signin/magiclinks/internal/queries.
signin/magiclinks/migrations
Package migrations supplies the sign-in link table's DDL, rendered for a dialect and table prefix.
Package migrations supplies the sign-in link table's DDL, rendered for a dialect and table prefix.
signin/recoverycodes
Package recoverycodes is where a user's recovery codes live: a set of single-use, digest-at-rest second factors a person keeps on paper for the day they no longer have the authenticator they enrolled.
Package recoverycodes is where a user's recovery codes live: a set of single-use, digest-at-rest second factors a person keeps on paper for the day they no longer have the authenticator they enrolled.
signin/recoverycodes/internal/queries
Package queries is the recovery code schema described as data: the canonical table name, its columns in the order every read projects them, the subsets a write assigns, and the six statements the store executes over them.
Package queries is the recovery code schema described as data: the canonical table name, its columns in the order every read projects them, the subsets a write assigns, and the six statements the store executes over them.
signin/recoverycodes/internal/queriesgen command
Command queriesgen writes the canonical sqlc input for the sign-in recovery code schema, one file per dialect, from authentication/signin/recoverycodes/internal/queries.
Command queriesgen writes the canonical sqlc input for the sign-in recovery code schema, one file per dialect, from authentication/signin/recoverycodes/internal/queries.
signin/recoverycodes/migrations
Package migrations supplies the recovery code table's DDL, rendered for a dialect and table prefix.
Package migrations supplies the recovery code table's DDL, rendered for a dialect and table prefix.
signin/recoverycodes/mock
Package recoverycodesmock provides moq-generated mock implementations of interfaces in the recoverycodes package.
Package recoverycodesmock provides moq-generated mock implementations of interfaces in the recoverycodes package.
signin/recoverycodes/privacy
Package privacy is the recovery code table's contribution to a subject access request: a dataprivacy.Collector that returns when somebody was issued a set of recovery codes and which of them they spent, and a dataprivacy.Eraser that destroys the set.
Package privacy is the recovery code table's contribution to a subject access request: a dataprivacy.Collector that returns when somebody was issued a set of recovery codes and which of them they spent, and a dataprivacy.Eraser that destroys the set.
signin/refreshtokens
Package refreshtokens is where a sign-in's refresh tokens live: a digest-keyed, single-use credential grouped into families, one family per login.
Package refreshtokens is where a sign-in's refresh tokens live: a digest-keyed, single-use credential grouped into families, one family per login.
signin/refreshtokens/internal/queries
Package queries is the sign-in refresh token schema described as data: the canonical table name, its columns in the order every read projects them, the subsets a write assigns, and the statements the store executes over them.
Package queries is the sign-in refresh token schema described as data: the canonical table name, its columns in the order every read projects them, the subsets a write assigns, and the statements the store executes over them.
signin/refreshtokens/internal/queriesgen command
Command queriesgen writes the canonical sqlc input for the sign-in refresh token schema, one file per dialect, from authentication/signin/refreshtokens/internal/queries.
Command queriesgen writes the canonical sqlc input for the sign-in refresh token schema, one file per dialect, from authentication/signin/refreshtokens/internal/queries.
signin/refreshtokens/migrations
Package migrations supplies the sign-in refresh token table's DDL, rendered for a dialect and table prefix.
Package migrations supplies the sign-in refresh token table's DDL, rendered for a dialect and table prefix.
webauthnsessions
Package webauthnsessions stores WebAuthn ceremony state in a SQL table.
Package webauthnsessions stores WebAuthn ceremony state in a SQL table.
webauthnsessions/config
Package webauthnsessionscfg assembles a WebAuthn relying party and its ceremony store, choosing between a SQL table and a cache.
Package webauthnsessionscfg assembles a WebAuthn relying party and its ceremony store, choosing between a SQL table and a cache.
webauthnsessions/internal/queries
Package queries is the WebAuthn ceremony session schema described as data: the canonical table name, its columns in the order every read projects them, and the four statements the store executes over them.
Package queries is the WebAuthn ceremony session schema described as data: the canonical table name, its columns in the order every read projects them, and the four statements the store executes over them.
webauthnsessions/internal/queriesgen command
Command queriesgen writes the canonical sqlc input for the WebAuthn ceremony session schema, one file per dialect, from authentication/webauthnsessions/internal/queries.
Command queriesgen writes the canonical sqlc input for the WebAuthn ceremony session schema, one file per dialect, from authentication/webauthnsessions/internal/queries.
webauthnsessions/migrations
Package migrations supplies the WebAuthn ceremony session table's DDL, rendered for a dialect and table prefix.
Package migrations supplies the WebAuthn ceremony session table's DDL, rendered for a dialect and table prefix.
Package billing stores what a deployment sells and what its customers paid.
Package billing stores what a deployment sells and what its customers paid.
config
Package billingcfg assembles a billing Store from environment configuration.
Package billingcfg assembles a billing Store from environment configuration.
grpc
Package grpc is billing on the wire: the gRPC service over github.com/primandproper/platform-go/v15/billing's Store, the converters between the generated messages and its types, a typed client, and the default permission fragment a consumer composes into their policy.
Package grpc is billing on the wire: the gRPC service over github.com/primandproper/platform-go/v15/billing's Store, the converters between the generated messages and its types, a typed client, and the default permission fragment a consumer composes into their policy.
grpc/client
Package client is a typed client for the billing gRPC service.
Package client is a typed client for the billing gRPC service.
http
Package http is a payment provider's webhook endpoint: verify the delivery, reconcile it into billing, and answer with the status code the provider acts on.
Package http is a payment provider's webhook endpoint: verify the delivery, reconcile it into billing, and answer with the status code the provider acts on.
internal/queries
Package queries is the billing schema described as data: the canonical table names, each table's columns in the order every read projects them, and the subsets a write may assign.
Package queries is the billing schema described as data: the canonical table names, each table's columns in the order every read projects them, and the subsets a write may assign.
internal/queriesgen command
Command queriesgen writes the canonical sqlc input for the billing schema, one file per dialect, from billing/internal/queries.
Command queriesgen writes the canonical sqlc input for the billing schema, one file per dialect, from billing/internal/queries.
migrations
Package migrations supplies the billing tables' DDL, rendered for a dialect and table prefix.
Package migrations supplies the billing tables' DDL, rendered for a dialect and table prefix.
mock
Package billingmock provides moq-generated mock implementations of interfaces in the billing package.
Package billingmock provides moq-generated mock implementations of interfaces in the billing package.
plans
Package plans answers entitlements' plan question and metering's billing-period question from the billing store.
Package plans answers entitlements' plan question and metering's billing-period question from the billing store.
privacy
Package privacy is the billing tables' contribution to a subject access request: a dataprivacy.Collector that returns what somebody was sold and what they paid.
Package privacy is the billing tables' contribution to a subject access request: a dataprivacy.Collector that returns what somebody was sold and what they paid.
standing
Package standing maps what a payment processor reported onto the standing an account is stored with.
Package standing maps what a payment processor reported onto the standing an account is stored with.
sync
Package sync reconciles a payment processor's deliveries into the billing store: the webhook handler every consumer writes, with the two things they get wrong.
Package sync reconciles a payment processor's deliveries into the billing store: the webhook handler every consumer writes, with the two things they get wrong.
Package callers is who is calling, as every gRPC surface in this module reads them: the interface a consumer's own authentication interceptor satisfies, the function that reads one off a request context, and the refusal a surface returns to a caller who may make this call and may not make it against the row they named.
Package callers is who is calling, as every gRPC surface in this module reads them: the interface a consumer's own authentication interceptor satisfies, the function that reads one off a request context, and the refusal a surface returns to a caller who may make this call and may not make it against the row they named.
Package comments is the durable half of letting your users talk about your things: a scoped table of what was said, threaded one level deep, about targets this package deliberately cannot see.
Package comments is the durable half of letting your users talk about your things: a scoped table of what was said, threaded one level deep, about targets this package deliberately cannot see.
config
Package commentscfg assembles a comments Store from environment configuration.
Package commentscfg assembles a comments Store from environment configuration.
grpc
Package grpc is comments on the wire: the gRPC service over github.com/primandproper/platform-go/v15/comments's Store, the converters between the generated messages and its types, a typed client, and the default permission fragment a consumer composes into their policy.
Package grpc is comments on the wire: the gRPC service over github.com/primandproper/platform-go/v15/comments's Store, the converters between the generated messages and its types, a typed client, and the default permission fragment a consumer composes into their policy.
grpc/client
Package client is a typed client for the comments gRPC service.
Package client is a typed client for the comments gRPC service.
internal/queries
Package queries is the comments schema described as data: the canonical table name, the table's columns in the order every read projects them, and the subsets each write assigns.
Package queries is the comments schema described as data: the canonical table name, the table's columns in the order every read projects them, and the subsets each write assigns.
internal/queriesgen command
Package main renders the canonical sqlc input for the comments table, one .sql per dialect, from the table description in comments/internal/queries.
Package main renders the canonical sqlc input for the comments table, one .sql per dialect, from the table description in comments/internal/queries.
migrations
Package migrations supplies the comments table's DDL, rendered for a dialect and table prefix.
Package migrations supplies the comments table's DDL, rendered for a dialect and table prefix.
mock
Package commentsmock provides moq-generated mock implementations of interfaces in the comments package.
Package commentsmock provides moq-generated mock implementations of interfaces in the comments package.
privacy
Package privacy is the comments table's contribution to a subject access request: a dataprivacy.Collector that returns what somebody wrote, and a dataprivacy.Eraser that destroys it.
Package privacy is the comments table's contribution to a subject access request: a dataprivacy.Collector that returns what somebody wrote, and a dataprivacy.Eraser that destroys it.
Package conformance is this module's promises, written once and assertable against three different subjects.
Package conformance is this module's promises, written once and assertable against three different subjects.
all
Package all links every conformance suite this module ships.
Package all links every conformance suite this module ships.
anonymous
Package anonymous asserts what every RPC in this module does with a request carrying no caller.
Package anonymous asserts what every RPC in this module does with a request carrying no caller.
assembled
Package assembled is the conformance suite run against a service this module's composition root built, rather than one a harness built by hand.
Package assembled is the conformance suite run against a service this module's composition root built, rather than one a harness built by hand.
audit
Package audit is the audit surface's promises, assertable against any subject that mounts it.
Package audit is the audit surface's promises, assertable against any subject that mounts it.
billing
Package billing is the ledger surface's promises, assertable against any subject that mounts it.
Package billing is the ledger surface's promises, assertable against any subject that mounts it.
comments
Package comments is the discussion surface's promises, assertable against any subject that mounts it.
Package comments is the discussion surface's promises, assertable against any subject that mounts it.
dataprivacy
Package dataprivacy is the privacy-request surface's promises, and the promise operations/http makes about the work that fulfills one, asserted over HTTP against any subject that serves them.
Package dataprivacy is the privacy-request surface's promises, and the promise operations/http makes about the work that fulfills one, asserted over HTTP against any subject that serves them.
filters
Package filters asserts that every paged read in this module refuses a malformed filter, rather than answering a page it half-applied.
Package filters asserts that every paged read in this module refuses a malformed filter, rather than answering a page it half-applied.
identity
Package identity is the directory surface's promises, assertable against any subject that mounts it.
Package identity is the directory surface's promises, assertable against any subject that mounts it.
internal/httpcall
Package httpcall is how the suites asserting this module's HTTP surfaces make a request as a caller and read what the router answered.
Package httpcall is how the suites asserting this module's HTTP surfaces make a request as a caller and read what the router answered.
internal/pagedrpc
Package pagedrpc finds every paged read this module serves over gRPC — every RPC whose request carries a filtering.v1.QueryFilter — and builds a request for each that is answerable apart from its filter.
Package pagedrpc finds every paged read this module serves over gRPC — every RPC whose request carries a filtering.v1.QueryFilter — and builds a request for each that is answerable apart from its filter.
internal/people
Package people mints the pair a person-owned confinement is asserted between: two different people in one directory.
Package people mints the pair a person-owned confinement is asserted between: two different people in one directory.
internal/services
Package services is the gRPC services this module mounts, as the cross-cutting suites find them: a name, a message from the service's package to reach its descriptor through, and the field of conformance.Surfaces it is called through.
Package services is the gRPC services this module mounts, as the cross-cutting suites find them: a name, a message from the service's package to reach its descriptor through, and the field of conformance.Surfaces it is called through.
issuereports
Package issuereports is the report queue's promises, assertable against any subject that mounts it.
Package issuereports is the report queue's promises, assertable against any subject that mounts it.
mediaregistry
Package mediaregistry is the media registry's promises, asserted against any subject that serves them: the guarded object read over HTTP, and the resource surface over gRPC.
Package mediaregistry is the media registry's promises, asserted against any subject that serves them: the guarded object read over HTTP, and the resource surface over gRPC.
notifications
Package notifications is the inbox and device surface's promises, assertable against any subject that mounts it.
Package notifications is the inbox and device surface's promises, assertable against any subject that mounts it.
oauth2clients
Package oauth2clients is the administered half of the OAuth2 client registry's promises, assertable against any subject that mounts it.
Package oauth2clients is the administered half of the OAuth2 client registry's promises, assertable against any subject that mounts it.
oauth2server
Package oauth2server is the OAuth 2.1 authorization server's storage promises, assertable against any subject that serves it.
Package oauth2server is the OAuth 2.1 authorization server's storage promises, assertable against any subject that serves it.
operations
Package operations is the operations surface's promises, asserted over HTTP against any subject that serves it: an operation is read, listed, cancelled and followed by its owners, and by nobody else.
Package operations is the operations surface's promises, asserted over HTTP against any subject that serves it: an operation is read, listed, cancelled and followed by its owners, and by nobody else.
pagination
Package pagination asserts that every paged read in this module reports the filter it actually applied.
Package pagination asserts that every paged read in this module reports the filter it actually applied.
passkeys
Package passkeys is the passkey surface, as promises assertable against any subject that mounts it.
Package passkeys is the passkey surface, as promises assertable against any subject that mounts it.
passwordreset
Package passwordreset is the way back in for somebody who cannot sign in, as promises assertable against any subject that mounts it.
Package passwordreset is the way back in for somebody who cannot sign in, as promises assertable against any subject that mounts it.
reservations
Package reservations asserts that a deployment refuses its members the calls it says it reserves.
Package reservations asserts that a deployment refuses its members the calls it says it reserves.
settings
Package settings is the settings surface's promises, assertable against any subject that mounts it.
Package settings is the settings surface's promises, assertable against any subject that mounts it.
signin
Package signin is the credential surface's promises, assertable against any subject that mounts it.
Package signin is the credential surface's promises, assertable against any subject that mounts it.
waitlists
Package waitlists is the signup surface's promises, assertable against any subject that mounts it.
Package waitlists is the signup surface's promises, assertable against any subject that mounts it.
webhooks
Package webhooks is the outbound webhook surface's promises, assertable against any subject that mounts it.
Package webhooks is the outbound webhook surface's promises, assertable against any subject that mounts it.
Package dataprivacy fulfills GDPR and CCPA subject access and erasure requests as durable, auditable operations.
Package dataprivacy fulfills GDPR and CCPA subject access and erasure requests as durable, auditable operations.
auditerasure
Package auditerasure supplies a dataprivacy.Eraser for the audit log.
Package auditerasure supplies a dataprivacy.Eraser for the audit log.
config
Package dataprivacycfg assembles the data privacy machinery from environment configuration: the Store every part shares, the Service applications submit through, the Fulfiller that does the work, and the Sweeper that expires.
Package dataprivacycfg assembles the data privacy machinery from environment configuration: the Store every part shares, the Service applications submit through, the Fulfiller that does the work, and the Sweeper that expires.
http
Package http mounts the data-privacy request surface on a routing.Router.
Package http mounts the data-privacy request surface on a routing.Router.
internal/queries
Package queries is the dataprivacy schema described as data: the canonical table name, its columns in the order every read projects them, and the arguments the guarded writes bind their comparands under.
Package queries is the dataprivacy schema described as data: the canonical table name, its columns in the order every read projects them, and the arguments the guarded writes bind their comparands under.
internal/queriesgen command
Command queriesgen writes the canonical sqlc input for the dataprivacy schema, one file per dialect, from dataprivacy/internal/queries.
Command queriesgen writes the canonical sqlc input for the dataprivacy schema, one file per dialect, from dataprivacy/internal/queries.
migrations
Package migrations supplies the data-privacy request table's DDL, rendered for a dialect and table prefix.
Package migrations supplies the data-privacy request table's DDL, rendered for a dialect and table prefix.
mock
Package dataprivacymock provides moq-generated mock implementations of interfaces in the dataprivacy package.
Package dataprivacymock provides moq-generated mock implementations of interfaces in the dataprivacy package.
Package entitlements answers "may this account use this feature, and how much is left".
Package entitlements answers "may this account use this feature, and how much is left".
config
Package entitlementscfg assembles the entitlements machinery from configuration: the Catalog plans are read into, the Checker that answers questions against it, and the metering.QuotaSource that keeps metering enforcing the catalog's limits rather than its own.
Package entitlementscfg assembles the entitlements machinery from configuration: the Catalog plans are read into, the Checker that answers questions against it, and the metering.QuotaSource that keeps metering enforcing the catalog's limits rather than its own.
mock
Package entitlementsmock provides moq-generated mock implementations of interfaces in the entitlements package.
Package entitlementsmock provides moq-generated mock implementations of interfaces in the entitlements package.
Package errormappers registers this module's domain tier with the two transport registries, in one call.
Package errormappers registers this module's domain tier with the two transport registries, in one call.
Package identity stores the thing being authenticated.
Package identity stores the thing being authenticated.
config
Package identitycfg assembles identity's three layers from environment configuration: the Store, the Service over it, and the gRPC server over that.
Package identitycfg assembles identity's three layers from environment configuration: the Store, the Service over it, and the gRPC server over that.
grpc
Package grpc is identity on the wire: the gRPC service over github.com/primandproper/platform-go/v15/identity's Service and Store, the converters between the generated messages and its types, a typed client, and the default permission fragment a consumer composes into its policy.
Package grpc is identity on the wire: the gRPC service over github.com/primandproper/platform-go/v15/identity's Service and Store, the converters between the generated messages and its types, a typed client, and the default permission fragment a consumer composes into its policy.
grpc/client
Package client is a typed client for identity's gRPC service.
Package client is a typed client for identity's gRPC service.
internal/queries
Package queries is the identity schema described as data: the canonical table names, each table's columns in the order every read projects them, and the two subsets a write may assign.
Package queries is the identity schema described as data: the canonical table names, each table's columns in the order every read projects them, and the two subsets a write may assign.
internal/queriesgen command
Command queriesgen writes the canonical sqlc input for the identity schema, one file per dialect, from identity/internal/queries.
Command queriesgen writes the canonical sqlc input for the identity schema, one file per dialect, from identity/internal/queries.
migrations
Package migrations supplies the identity tables' DDL, rendered for a dialect and table prefix, as the versions it has shipped in.
Package migrations supplies the identity tables' DDL, rendered for a dialect and table prefix, as the versions it has shipped in.
mock
Package identitymock provides moq-generated mock implementations of interfaces in the identity package.
Package identitymock provides moq-generated mock implementations of interfaces in the identity package.
privacy
Package privacy is the identity tables' contribution to a subject access request: a dataprivacy.Collector that returns who somebody is to the directory, and a dataprivacy.Eraser that destroys them.
Package privacy is the identity tables' contribution to a subject access request: a dataprivacy.Collector that returns who somebody is to the directory, and a dataprivacy.Eraser that destroys them.
internal
archivegate
Package archivegate is the one door from a wire filter to a store filter on this module's gRPC surfaces, and the archive grant every paged read has to name to pass through it.
Package archivegate is the one door from a wire filter to a store filter on this module's gRPC surfaces, and the archive grant every paged read has to name to pass through it.
cmd/benchtable command
Command benchtable turns raw `go test -bench` output into a markdown reference table.
Command benchtable turns raw `go test -bench` output into a markdown reference table.
cmd/conformancesummary command
Command conformancesummary reads `go test -json` output for the conformance tree on stdin and reports, per suite and per subject, how many assertions passed, skipped and failed.
Command conformancesummary reads `go test -json` output for the conformance tree on stdin and reports, per suite and per subject, how many assertions passed, skipped and failed.
cmd/readmegen command
Command readmegen writes the two README sections that are rosters of the tree — "Stores and Transports" and "SQL Dialect Support" — from the tree itself.
Command readmegen writes the two README sections that are rosters of the tree — "Stores and Transports" and "SQL Dialect Support" — from the tree itself.
collapsedruns
Package collapsedruns is where the two schemas that were versioned runs in v14 are pinned to the tables those runs left behind, and it holds nothing else.
Package collapsedruns is where the two schemas that were versioned runs in v14 are pinned to the tables those runs left behind, and it holds nothing else.
configroster
Package configroster holds the tests that walk every config subpackage in the module at once: the one that says a zero-valued config either validates or says why it cannot, the one that says a config naming a provider must carry that provider's block, and the one that says the first of those names every config subpackage this module ships.
Package configroster holds the tests that walk every config subpackage in the module at once: the one that says a zero-valued config either validates or says why it cannot, the one that says a config naming a provider must carry that provider's block, and the one that says the first of those names every config subpackage this module ships.
countwidth
Package countwidth is where the width of every exported count in this module is checked against one rule, and it holds nothing else.
Package countwidth is where the width of every exported count in this module is checked against one rule, and it holds nothing else.
directrequires
Package directrequires is where go.mod's account of which modules this module's own source imports is checked against the source, and it holds nothing else.
Package directrequires is where go.mod's account of which modules this module's own source imports is checked against the source, and it holds nothing else.
hookroster
Package hookroster is where every store write in this module is checked against the hook it owes, and it holds nothing else.
Package hookroster is where every store write in this module is checked against the hook it owes, and it holds nothing else.
mcptoolfixture
Package mcptoolfixture holds the documented structs mcptool's suite extracts and reflects.
Package mcptoolfixture holds the documented structs mcptool's suite extracts and reflects.
protoconvention
Package protoconvention is where the JSON spelling of every field in every .proto this module ships is checked against one rule, and it holds nothing else.
Package protoconvention is where the JSON spelling of every field in every .proto this module ships is checked against one rule, and it holds nothing else.
routeguard
Package routeguard is the permission check in front of an HTTP surface's guarded routes, shared by the three surfaces that have them.
Package routeguard is the permission check in front of an HTTP surface's guarded routes, shared by the three surfaces that have them.
scheduledjob
Package scheduledjob is the one place the self-scheduling stores turn their jobscfg.JobConfig into the jobs a scheduler registers.
Package scheduledjob is the one place the self-scheduling stores turn their jobscfg.JobConfig into the jobs a scheduler registers.
schemaconvention
Package schemaconvention is where the module's schema convention is asserted, and it holds nothing else.
Package schemaconvention is where the module's schema convention is asserted, and it holds nothing else.
scopeddl
Package scopeddl is where every tenancy column this module's schemas ship is enumerated, and it holds nothing else.
Package scopeddl is where every tenancy column this module's schemas ship is enumerated, and it holds nothing else.
sentinelmatrix
Package sentinelmatrix is where this module's domain sentinels are checked against the statuses they resolve to, and it holds nothing else.
Package sentinelmatrix is where this module's domain sentinels are checked against the statuses they resolve to, and it holds nothing else.
sqltier
Package sqltier is where every package in this module that holds SQL is named with the tier its statements execute on, and it holds nothing else.
Package sqltier is where every package in this module that holds SQL is named with the tier its statements execute on, and it holds nothing else.
tiercheck
Package tiercheck is where every package in this module is named with the tier it belongs to, and it holds nothing else.
Package tiercheck is where every package in this module is named with the tier it belongs to, and it holds nothing else.
txcount
Package txcount counts the statements a store sends through a transaction, and holds nothing else.
Package txcount counts the statements a store sends through a transaction, and holds nothing else.
Package issuereports is the durable half of asking your users what is wrong: a scoped table of what they told you, and where each report stands.
Package issuereports is the durable half of asking your users what is wrong: a scoped table of what they told you, and where each report stands.
config
Package issuereportscfg assembles an issuereports Store from environment configuration.
Package issuereportscfg assembles an issuereports Store from environment configuration.
grpc
Package grpc serves the issue report queue over gRPC.
Package grpc serves the issue report queue over gRPC.
grpc/client
Package client is a typed client for the issue reports gRPC service.
Package client is a typed client for the issue reports gRPC service.
internal/queries
Package queries is the issue reports schema described as data: the canonical table name, the table's columns in the order every read projects them, and the subsets each write assigns.
Package queries is the issue reports schema described as data: the canonical table name, the table's columns in the order every read projects them, and the subsets each write assigns.
internal/queriesgen command
Package main renders the canonical sqlc input for the issue reports table, one .sql per dialect, from the table description in issuereports/internal/queries.
Package main renders the canonical sqlc input for the issue reports table, one .sql per dialect, from the table description in issuereports/internal/queries.
mcp
Package mcp serves the issue report queue to a model, as read-only Model Context Protocol tools.
Package mcp serves the issue report queue to a model, as read-only Model Context Protocol tools.
migrations
Package migrations supplies the issue reports table's DDL, rendered for a dialect and table prefix.
Package migrations supplies the issue reports table's DDL, rendered for a dialect and table prefix.
mock
Package issuereportsmock provides moq-generated mock implementations of interfaces in the issuereports package.
Package issuereportsmock provides moq-generated mock implementations of interfaces in the issuereports package.
privacy
Package privacy is the issue reports table's contribution to a subject access request: a dataprivacy.Collector that returns what somebody filed, and a dataprivacy.Eraser that destroys it.
Package privacy is the issue reports table's contribution to a subject access request: a dataprivacy.Collector that returns what somebody filed, and a dataprivacy.Eraser that destroys it.
Package links mints URLs that prove their bearer was sent them, once, until they expire.
Package links mints URLs that prove their bearer was sent them, once, until they expire.
config
Package linkscfg assembles a links.Minter from environment configuration.
Package linkscfg assembles a links.Minter from environment configuration.
database
Package database stores action link records in a SQL table.
Package database stores action link records in a SQL table.
database/internal/queries
Package queries is the action link schema described as data: the table's name, its columns in the order every statement lists them, the subset a resolution may assign, and the two that may be NULL.
Package queries is the action link schema described as data: the table's name, its columns in the order every statement lists them, the subset a resolution may assign, and the two that may be NULL.
database/internal/queriesgen command
Command queriesgen writes the canonical sqlc input for the action link schema, one file per dialect, from links/database/internal/queries.
Command queriesgen writes the canonical sqlc input for the action link schema, one file per dialect, from links/database/internal/queries.
database/migrations
Package migrations supplies the action link table's DDL, rendered for a dialect and table prefix.
Package migrations supplies the action link table's DDL, rendered for a dialect and table prefix.
mock
Package linksmock provides moq-generated mock implementations of interfaces in the links package.
Package linksmock provides moq-generated mock implementations of interfaces in the links package.
Package mcptool is what a Model Context Protocol tool surface is built on: the schema a tool's input and output are described with, and the gate every call passes before it reaches a store.
Package mcptool is what a Model Context Protocol tool surface is built on: the schema a tool's input and output are described with, and the gate every call passes before it reaches a store.
mcpdocs command
Command mcpdocs writes the field doc comments a package's MCP tool schemas describe their properties with, as a generated Go file.
Command mcpdocs writes the field doc comments a package's MCP tool schemas describe their properties with, as a generated Go file.
Package mediaregistry records what was uploaded: one row per object in storage, saying who put it there, into which tenant, what it is, how big it is, and what it belongs to.
Package mediaregistry records what was uploaded: one row per object in storage, saying who put it there, into which tenant, what it is, how big it is, and what it belongs to.
config
Package mediaregistrycfg assembles an upload registry Store from environment configuration.
Package mediaregistrycfg assembles an upload registry Store from environment configuration.
grpc
Package grpc is the media registry's resource surface: putting an object in the bucket as the caller's, registering one that arrived some other way, and reading back what is theirs.
Package grpc is the media registry's resource surface: putting an object in the bucket as the caller's, registering one that arrived some other way, and reading back what is theirs.
grpc/client
Package client is a typed client for the media registry gRPC service.
Package client is a typed client for the media registry gRPC service.
http
Package http serves the bytes behind a mediaregistry row, to the callers the row entitles.
Package http serves the bytes behind a mediaregistry row, to the callers the row entitles.
internal/queries
Package queries is the upload registry's schema described as data: the canonical table name, its columns in the order every read projects them, and the subsets a write may assign.
Package queries is the upload registry's schema described as data: the canonical table name, its columns in the order every read projects them, and the subsets a write may assign.
internal/queriesgen command
Command queriesgen writes the canonical sqlc input for the upload registry schema, one file per dialect, from mediaregistry/internal/queries.
Command queriesgen writes the canonical sqlc input for the upload registry schema, one file per dialect, from mediaregistry/internal/queries.
migrations
Package migrations supplies the upload registry's DDL, rendered for a dialect and table prefix.
Package migrations supplies the upload registry's DDL, rendered for a dialect and table prefix.
mock
Package mediaregistrymock provides moq-generated mock implementations of interfaces in the mediaregistry package.
Package mediaregistrymock provides moq-generated mock implementations of interfaces in the mediaregistry package.
privacy
Package privacy is the registry table's contribution to a subject access request: a dataprivacy.Collector that returns what somebody uploaded, and a dataprivacy.Eraser that withdraws it and says what is left.
Package privacy is the registry table's contribution to a subject access request: a dataprivacy.Collector that returns what somebody uploaded, and a dataprivacy.Eraser that withdraws it and says what is left.
Package metering counts what customers consume and enforces what they are allowed to, durably enough to invoice from.
Package metering counts what customers consume and enforces what they are allowed to, durably enough to invoice from.
config
Package meteringcfg assembles the usage metering machinery from environment configuration: the Store every part shares, the Recorder usage arrives through, the Enforcer quotas are checked against, and the Flusher that posts to the billing provider.
Package meteringcfg assembles the usage metering machinery from environment configuration: the Store every part shares, the Recorder usage arrives through, the Enforcer quotas are checked against, and the Flusher that posts to the billing provider.
internal/queries
Package queries is metering's two tables described as data: their canonical names, their columns in the order every read projects them, the subsets each write assigns, and the natural key every statement addresses a row by.
Package queries is metering's two tables described as data: their canonical names, their columns in the order every read projects them, the subsets each write assigns, and the natural key every statement addresses a row by.
internal/queriesgen command
Package main renders the canonical sqlc input for metering's two tables, and the DDL those queries are checked against.
Package main renders the canonical sqlc input for metering's two tables, and the DDL those queries are checked against.
migrations
Package migrations supplies the usage metering tables' DDL, rendered for a dialect and table prefix.
Package migrations supplies the usage metering tables' DDL, rendered for a dialect and table prefix.
mock
Package meteringmock provides moq-generated mock implementations of interfaces in the metering package.
Package meteringmock provides moq-generated mock implementations of interfaces in the metering package.
Package notifications is the durable half of telling somebody something: the in-app inbox, and the registry of devices a push can be addressed to.
Package notifications is the durable half of telling somebody something: the in-app inbox, and the registry of devices a push can be addressed to.
config
Package notificationscfg assembles a notifications store — the in-app inbox and the device registry — from environment configuration.
Package notificationscfg assembles a notifications store — the in-app inbox and the device registry — from environment configuration.
grpc
Package grpc serves the in-app inbox and the device registry over gRPC.
Package grpc serves the in-app inbox and the device registry over gRPC.
grpc/client
Package client is a typed client for the notifications gRPC service.
Package client is a typed client for the notifications gRPC service.
internal/queries
Package queries is the notifications schema described as data: the canonical table names, each table's columns in the order every read projects them, and the subsets a write may assign.
Package queries is the notifications schema described as data: the canonical table names, each table's columns in the order every read projects them, and the subsets a write may assign.
internal/queriesgen command
Command queriesgen writes the canonical sqlc input for the notifications schema, one file per dialect, from notifications/internal/queries.
Command queriesgen writes the canonical sqlc input for the notifications schema, one file per dialect, from notifications/internal/queries.
mail
Package mail is the queued transport for the mail this module's services owe: one QueuedMailer that satisfies every Mailer seam here by enqueuing the mail on the outbox, and one Drainer that takes it off the topic, renders it through the consumer's Renderer and sends it through an email.Emailer.
Package mail is the queued transport for the mail this module's services owe: one QueuedMailer that satisfies every Mailer seam here by enqueuing the mail on the outbox, and one Drainer that takes it off the topic, renders it through the consumer's Renderer and sends it through an email.Emailer.
migrations
Package migrations supplies the notification tables' DDL, rendered for a dialect and table prefix.
Package migrations supplies the notification tables' DDL, rendered for a dialect and table prefix.
mock
Package notificationsmock provides moq-generated mock implementations of interfaces in the notifications package.
Package notificationsmock provides moq-generated mock implementations of interfaces in the notifications package.
privacy
Package privacy is notifications' contribution to a subject access request: what somebody was told, what handsets they registered, and the destruction of both.
Package privacy is notifications' contribution to a subject access request: what somebody was told, what handsets they registered, and the destruction of both.
push
Package push is the fan-out: one announcement, every handset the people named have registered, and the dead tokens pruned on the way.
Package push is the fan-out: one announcement, every handset the people named have registered, and the dead tokens pruned on the way.
Package operations runs work that outlives the request that asked for it, and gives the client something to watch while it does.
Package operations runs work that outlives the request that asked for it, and gives the client something to watch while it does.
config
Package operationscfg assembles the long-running-operations tier — the store, the service, the worker that runs operations, and the watcher that streams them — from environment configuration.
Package operationscfg assembles the long-running-operations tier — the store, the service, the worker that runs operations, and the watcher that streams them — from environment configuration.
http
Package http mounts the operations read surface on a routing.Router.
Package http mounts the operations read surface on a routing.Router.
internal/queries
Package queries is the operations schema described as data — the canonical table name and the column list every read projects — together with the statements the operations store executes.
Package queries is the operations schema described as data — the canonical table name and the column list every read projects — together with the statements the operations store executes.
internal/queriesgen command
Command queriesgen writes the canonical sqlc input for the operations schema, one file per dialect it serves, from operations/internal/queries.
Command queriesgen writes the canonical sqlc input for the operations schema, one file per dialect it serves, from operations/internal/queries.
migrations
Package migrations supplies the operations table's DDL, rendered for a dialect and table prefix.
Package migrations supplies the operations table's DDL, rendered for a dialect and table prefix.
mock
Package operationsmock provides moq-generated mock implementations of interfaces in the operations package.
Package operationsmock provides moq-generated mock implementations of interfaces in the operations package.
Package outbox makes "write a row and publish an event" atomic.
Package outbox makes "write a row and publish an event" atomic.
config
Package outboxcfg assembles the outbox from environment configuration: a Writer for the transactional side and a Relay, with its publisher provider, for the delivery side.
Package outboxcfg assembles the outbox from environment configuration: a Writer for the transactional side and a Relay, with its publisher provider, for the delivery side.
internal/queries
Package queries is the outbox schema described as data — the canonical table name and its columns in the order every statement names them — together with the statements the Writer and the Relay execute, rendered from it.
Package queries is the outbox schema described as data — the canonical table name and its columns in the order every statement names them — together with the statements the Writer and the Relay execute, rendered from it.
internal/queriesgen command
Command queriesgen writes the canonical sqlc input for the outbox schema, one file per dialect it serves, from outbox/internal/queries.
Command queriesgen writes the canonical sqlc input for the outbox schema, one file per dialect it serves, from outbox/internal/queries.
migrations
Package migrations supplies the outbox table's DDL, rendered for a dialect and table prefix.
Package migrations supplies the outbox table's DDL, rendered for a dialect and table prefix.
Package privacyadapters registers the privacy adapters this module ships into a dataprivacy.Registry, in one call.
Package privacyadapters registers the privacy adapters this module ships into a dataprivacy.Registry, in one call.
Package rbac stores authorization policy in SQL tables.
Package rbac stores authorization policy in SQL tables.
config
Package rbaccfg selects and builds an authorization.PolicyResolver, choosing between policy declared in configuration and policy stored in SQL.
Package rbaccfg selects and builds an authorization.PolicyResolver, choosing between policy declared in configuration and policy stored in SQL.
internal/queries
Package queries is the authorization policy schema described as data: the four canonical table names, the column list the two named tables share, and the statements the resolver runs over them.
Package queries is the authorization policy schema described as data: the four canonical table names, the column list the two named tables share, and the statements the resolver runs over them.
internal/queriesgen command
Command queriesgen writes the canonical sqlc input for the authorization policy schema, one file per dialect it serves, from rbac/internal/queries.
Command queriesgen writes the canonical sqlc input for the authorization policy schema, one file per dialect it serves, from rbac/internal/queries.
migrations
Package migrations supplies the authorization policy tables' DDL, rendered for a dialect and table prefix.
Package migrations supplies the authorization policy tables' DDL, rendered for a dialect and table prefix.
Package recording writes the companions a store write owes, on the write's own transaction: the audit entries that say what happened and who did it, and the one domain event that tells everybody else.
Package recording writes the companions a store write owes, on the write's own transaction: the audit entries that say what happened and who did it, and the one domain event that tells everybody else.
config
Package recordingcfg assembles a recording.Recorder from environment configuration, and is where every other config package here asks whether one exists.
Package recordingcfg assembles a recording.Recorder from environment configuration, and is where every other config package here asks whether one exists.
Package retention deletes data on a clock, from policies given as data.
Package retention deletes data on a clock, from policies given as data.
config
Package retentioncfg assembles a retention Sweeper from environment configuration.
Package retentioncfg assembles a retention Sweeper from environment configuration.
Package saga runs a linear sequence of steps durably, and unwinds it when a step fails.
Package saga runs a linear sequence of steps durably, and unwinds it when a step fails.
config
Package sagacfg assembles the saga machinery from environment configuration: the Store the runner and the worker share, and the Worker that advances instances.
Package sagacfg assembles the saga machinery from environment configuration: the Store the runner and the worker share, and the Worker that advances instances.
internal/queries
Package queries is the saga schema described as data — the canonical table name and its columns in the order every read projects them — and the statements the store runs over it, rendered for each of the three dialects it serves.
Package queries is the saga schema described as data — the canonical table name and its columns in the order every read projects them — and the statements the store runs over it, rendered for each of the three dialects it serves.
internal/queriesgen command
Command queriesgen writes the canonical sqlc input for the saga schema, one file per dialect, from saga/internal/queries.
Command queriesgen writes the canonical sqlc input for the saga schema, one file per dialect, from saga/internal/queries.
migrations
Package migrations supplies the saga instance table's DDL, rendered for a dialect and table prefix.
Package migrations supplies the saga instance table's DDL, rendered for a dialect and table prefix.
mock
Package sagamock provides moq-generated mock implementations of interfaces in the saga package.
Package sagamock provides moq-generated mock implementations of interfaces in the saga package.
Package searchsync keeps a search index in step with the database it is derived from.
Package searchsync keeps a search index in step with the database it is derived from.
source
Package syncsource adapts a repository to the two read seams searchsync defines: searchsync.Fetcher, which the change feed reads one document per event through, and searchsync.Scanner, which a reindex walks the whole source with.
Package syncsource adapts a repository to the two read seams searchsync defines: searchsync.Fetcher, which the change feed reads one document per event through, and searchsync.Scanner, which a reindex walks the whole source with.
Package series stores standing appointments: a weekly rule ("Tuesdays at 4pm, every week, from September 2"), the concrete occurrences it implies, and the exceptions those occurrences accumulate — each one skipped, moved or replaced without touching the rule.
Package series stores standing appointments: a weekly rule ("Tuesdays at 4pm, every week, from September 2"), the concrete occurrences it implies, and the exceptions those occurrences accumulate — each one skipped, moved or replaced without touching the rule.
config
Package seriescfg assembles a series Store, and optionally the horizon worker that writes it forward, from environment configuration.
Package seriescfg assembles a series Store, and optionally the horizon worker that writes it forward, from environment configuration.
internal/queries
Package queries is the series schema described as data: the canonical table names, their columns in the order every read projects them, and the statements the store executes over them.
Package queries is the series schema described as data: the canonical table names, their columns in the order every read projects them, and the statements the store executes over them.
internal/queriesgen command
Package main renders series/internal/queries into the canonical .sql files beside it, one per dialect, and prints the schema those files are checked against.
Package main renders series/internal/queries into the canonical .sql files beside it, one per dialect, and prints the schema those files are checked against.
migrations
Package migrations supplies the series and occurrence tables' DDL, rendered for a dialect and table prefix.
Package migrations supplies the series and occurrence tables' DDL, rendered for a dialect and table prefix.
mock
Package seriesmock provides moq-generated mock implementations of interfaces in the series package.
Package seriesmock provides moq-generated mock implementations of interfaces in the series package.
Package service is platform-go's composition root: one config struct describing a whole service, and one walk that registers everything it names with a samber/do injector.
Package service is platform-go's composition root: one config struct describing a whole service, and one walk that registers everything it names with a samber/do injector.
Package sessions keeps session state on the server and gives the client only an identifier.
Package sessions keeps session state on the server and gives the client only an identifier.
cache
Package cache stores session records in a cache.Cache.
Package cache stores session records in a cache.Cache.
config
Package sessionscfg assembles a session store, and optionally a cookie-bound manager, from environment configuration.
Package sessionscfg assembles a session store, and optionally a cookie-bound manager, from environment configuration.
database
Package database stores session records in a SQL table.
Package database stores session records in a SQL table.
database/internal/queries
Package queries is the session schema described as data: the table's name, its columns in the order every statement lists them, the subset a write may assign, and the one column that may be NULL.
Package queries is the session schema described as data: the table's name, its columns in the order every statement lists them, the subset a write may assign, and the one column that may be NULL.
database/internal/queriesgen command
Command queriesgen writes the canonical sqlc input for the session schema, one file per dialect, from sessions/database/internal/queries.
Command queriesgen writes the canonical sqlc input for the session schema, one file per dialect, from sessions/database/internal/queries.
database/migrations
Package migrations supplies the session table's DDL, rendered for a dialect and table prefix.
Package migrations supplies the session table's DDL, rendered for a dialect and table prefix.
http
Package http binds a sessions.Store to a signed cookie and to net/http.
Package http binds a sessions.Store to a signed cookie and to net/http.
mock
Package sessionsmock provides moq-generated mock implementations of interfaces in the sessions package.
Package sessionsmock provides moq-generated mock implementations of interfaces in the sessions package.
Package settings stores the runtime settings a user or an account sets about themselves: administrator-defined definitions with a kind, a default and an enumeration, and per-subject values stored against them.
Package settings stores the runtime settings a user or an account sets about themselves: administrator-defined definitions with a kind, a default and an enumeration, and per-subject values stored against them.
config
Package settingscfg assembles a settings Store from environment configuration.
Package settingscfg assembles a settings Store from environment configuration.
grpc
Package grpc is settings on the wire: the gRPC service over github.com/primandproper/platform-go/v15/settings's Store, the converters between the generated messages and its types, a typed client, and the default permission fragment a consumer composes into its policy.
Package grpc is settings on the wire: the gRPC service over github.com/primandproper/platform-go/v15/settings's Store, the converters between the generated messages and its types, a typed client, and the default permission fragment a consumer composes into its policy.
grpc/client
Package client is a typed client for the settings gRPC service.
Package client is a typed client for the settings gRPC service.
internal/queries
Package queries is the settings schema described as data: the canonical table names, each table's columns in the order every read projects them, and the two subsets a write may assign.
Package queries is the settings schema described as data: the canonical table names, each table's columns in the order every read projects them, and the two subsets a write may assign.
internal/queriesgen command
Command queriesgen writes the canonical sqlc input for the settings schema, one file per dialect, from settings/internal/queries.
Command queriesgen writes the canonical sqlc input for the settings schema, one file per dialect, from settings/internal/queries.
migrations
Package migrations supplies the settings tables' DDL, rendered for a dialect and table prefix.
Package migrations supplies the settings tables' DDL, rendered for a dialect and table prefix.
mock
Package settingsmock provides moq-generated mock implementations of interfaces in the settings package.
Package settingsmock provides moq-generated mock implementations of interfaces in the settings package.
privacy
Package privacy is the settings values table's contribution to a subject access request: a dataprivacy.Collector that returns what somebody chose, and a dataprivacy.Eraser that destroys it.
Package privacy is the settings values table's contribution to a subject access request: a dataprivacy.Collector that returns what somebody chose, and a dataprivacy.Eraser that destroys it.
Package shredding provides per-subject data keys that can be destroyed, so that erasure reaches media nothing can write to.
Package shredding provides per-subject data keys that can be destroyed, so that erasure reaches media nothing can write to.
config
Package shreddingcfg assembles per-subject data keys from environment configuration: the Store the keys live in, the Keys surface that uses them, and the Broadcaster that tells the rest of the fleet when one is destroyed.
Package shreddingcfg assembles per-subject data keys from environment configuration: the Store the keys live in, the Keys surface that uses them, and the Broadcaster that tells the rest of the fleet when one is destroyed.
internal/queries
Package queries is the subject-key table described as data: its canonical name, its columns in the order every read projects them, and the natural key every statement addresses a row by.
Package queries is the subject-key table described as data: its canonical name, its columns in the order every read projects them, and the natural key every statement addresses a row by.
internal/queriesgen command
Package main renders the canonical sqlc input for the subject-key table, and the DDL those queries are checked against.
Package main renders the canonical sqlc input for the subject-key table, and the DDL those queries are checked against.
migrations
Package migrations supplies the subject-key table's DDL, rendered for a dialect and table prefix.
Package migrations supplies the subject-key table's DDL, rendered for a dialect and table prefix.
mock
Package shreddingmock provides moq-generated mock implementations of the shredding package's interfaces.
Package shreddingmock provides moq-generated mock implementations of the shredding package's interfaces.
Package timers is durable one-shot scheduling over a SQL table: run this once at instant T, exactly once across the fleet, surviving restarts.
Package timers is durable one-shot scheduling over a SQL table: run this once at instant T, exactly once across the fleet, surviving restarts.
config
Package timerscfg assembles a timer set, and optionally the worker that fires it, from environment configuration.
Package timerscfg assembles a timer set, and optionally the worker that fires it, from environment configuration.
internal/queries
Package queries is the timers schema described as data — the canonical table name and the columns its statements touch — together with the statements the timer set executes.
Package queries is the timers schema described as data — the canonical table name and the columns its statements touch — together with the statements the timer set executes.
internal/queriesgen command
Command queriesgen writes the canonical sqlc input for the timers schema, one file per dialect it serves, from timers/internal/queries.
Command queriesgen writes the canonical sqlc input for the timers schema, one file per dialect it serves, from timers/internal/queries.
migrations
Package migrations supplies the timer table's DDL, rendered for a dialect and table prefix.
Package migrations supplies the timer table's DDL, rendered for a dialect and table prefix.
Package waitlists stores the queue people join before the thing they are queueing for exists: named lists with a closing time, and the signups against them with a lifecycle of their own.
Package waitlists stores the queue people join before the thing they are queueing for exists: named lists with a closing time, and the signups against them with a lifecycle of their own.
config
Package waitlistscfg assembles a waitlists Store from environment configuration.
Package waitlistscfg assembles a waitlists Store from environment configuration.
grpc
Package grpc is waitlists on the wire: the gRPC service over github.com/primandproper/platform-go/v15/waitlists's Store, the converters between the generated messages and its types, a typed client, and the default permission fragment a consumer composes into its policy.
Package grpc is waitlists on the wire: the gRPC service over github.com/primandproper/platform-go/v15/waitlists's Store, the converters between the generated messages and its types, a typed client, and the default permission fragment a consumer composes into its policy.
grpc/client
Package client is a typed client for the waitlists gRPC service.
Package client is a typed client for the waitlists gRPC service.
internal/queries
Package queries is the waitlist schema described as data: the canonical table names, each table's columns in the order every read projects them, and the subsets a write may assign.
Package queries is the waitlist schema described as data: the canonical table names, each table's columns in the order every read projects them, and the subsets a write may assign.
internal/queriesgen command
Command queriesgen writes the canonical sqlc input for the waitlist schema, one file per dialect, from waitlists/internal/queries.
Command queriesgen writes the canonical sqlc input for the waitlist schema, one file per dialect, from waitlists/internal/queries.
mcp
Package mcp serves the waitlist catalog to a model, as read-only Model Context Protocol tools.
Package mcp serves the waitlist catalog to a model, as read-only Model Context Protocol tools.
migrations
Package migrations supplies the waitlist tables' DDL, rendered for a dialect and table prefix.
Package migrations supplies the waitlist tables' DDL, rendered for a dialect and table prefix.
mock
Package waitlistsmock provides moq-generated mock implementations of interfaces in the waitlists package.
Package waitlistsmock provides moq-generated mock implementations of interfaces in the waitlists package.
privacy
Package privacy is the waitlist signups table's contribution to a subject access request: a dataprivacy.Collector that returns the signups somebody holds, and a dataprivacy.Eraser that withdraws them.
Package privacy is the waitlist signups table's contribution to a subject access request: a dataprivacy.Collector that returns the signups somebody holds, and a dataprivacy.Eraser that withdraws them.
Package webhooks delivers outbound webhooks: signed, retried, ordered, and replayable.
Package webhooks delivers outbound webhooks: signed, retried, ordered, and replayable.
config
Package webhookscfg assembles the webhook machinery from environment configuration: the Store both halves share, the Dispatcher applications write through, the Worker that delivers, and the Emitter that writes an event to the outbox and dispatches it in one call.
Package webhookscfg assembles the webhook machinery from environment configuration: the Store both halves share, the Dispatcher applications write through, the Worker that delivers, and the Emitter that writes an event to the outbox and dispatches it in one call.
grpc
Package grpc is webhook endpoint management on the wire: the gRPC service over github.com/primandproper/platform-go/v15/webhooks's Dispatcher and Store, the converters between the generated messages and its types, a typed client, and the default permission fragment a consumer composes into its policy.
Package grpc is webhook endpoint management on the wire: the gRPC service over github.com/primandproper/platform-go/v15/webhooks's Dispatcher and Store, the converters between the generated messages and its types, a typed client, and the default permission fragment a consumer composes into its policy.
grpc/client
Package client is a typed client for the webhooks gRPC service.
Package client is a typed client for the webhooks gRPC service.
internal/queries
Package queries is the webhooks schema described as data — the canonical table names and each table's columns in the order every read projects them — together with the thirty statements the store executes, rendered from it.
Package queries is the webhooks schema described as data — the canonical table names and each table's columns in the order every read projects them — together with the thirty statements the store executes, rendered from it.
internal/queriesgen command
Command queriesgen writes the canonical sqlc input for the webhooks schema, one file per dialect, from webhooks/internal/queries.
Command queriesgen writes the canonical sqlc input for the webhooks schema, one file per dialect, from webhooks/internal/queries.
mcp
Package mcp serves webhook endpoints and the event catalog to a model, as read-only Model Context Protocol tools.
Package mcp serves webhook endpoints and the event catalog to a model, as read-only Model Context Protocol tools.
migrations
Package migrations supplies the webhook tables' DDL, rendered for a dialect and table prefix.
Package migrations supplies the webhook tables' DDL, rendered for a dialect and table prefix.
mock
Package webhooksmock provides moq-generated mock implementations of interfaces in the webhooks package.
Package webhooksmock provides moq-generated mock implementations of interfaces in the webhooks package.
recordinghooks
Package recordinghooks is the webhooks.Hooks a deployment that keeps an audit log and publishes events installs on its webhooks store: every endpoint and subscription write records an audit entry naming the row and emits one of the events webhooks.EventCatalog describes, both on the write's transaction, through a recording.Recorder.
Package recordinghooks is the webhooks.Hooks a deployment that keeps an audit log and publishes events installs on its webhooks store: every endpoint and subscription write records an audit entry naming the row and emits one of the events webhooks.EventCatalog describes, both on the write's transaction, through a recording.Recorder.
Package workqueue is a leased work queue over a SQL table: the SELECT … FOR UPDATE SKIP LOCKED claim/complete/expire pattern, generic over the key that names a unit of work, on Postgres, MySQL and SQLite.
Package workqueue is a leased work queue over a SQL table: the SELECT … FOR UPDATE SKIP LOCKED claim/complete/expire pattern, generic over the key that names a unit of work, on Postgres, MySQL and SQLite.
config
Package workqueuecfg assembles a work queue, and optionally the runner that drains it, from environment configuration.
Package workqueuecfg assembles a work queue, and optionally the runner that drains it, from environment configuration.
internal/queries
Package queries is the work queue schema described as data — the canonical table name and the columns its statements touch — together with the statements the queue executes.
Package queries is the work queue schema described as data — the canonical table name and the columns its statements touch — together with the statements the queue executes.
internal/queriesgen command
Command queriesgen writes the canonical sqlc input for the work queue schema, one file per dialect it serves, from workqueue/internal/queries.
Command queriesgen writes the canonical sqlc input for the work queue schema, one file per dialect it serves, from workqueue/internal/queries.
migrations
Package migrations supplies the work queue table's DDL, rendered for a dialect and table prefix.
Package migrations supplies the work queue table's DDL, rendered for a dialect and table prefix.

Jump to

Keyboard shortcuts

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