preflight

package
v0.40.20 Latest Latest
Warning

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

Go to latest
Published: Nov 1, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package preflight is the read-only launch check behind `rivolt launch-preflight`: one report an operator reads before the Rivolt Pro flip (the launch runbook: rivolt-infra docs/launch-flip.md). It prints counts, names and status codes only, never a value of a setting, an id or an address, and it switches nothing on: the database part runs in a read-only transaction and the URL part is a GET of public pages.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EmailURLs

func EmailURLs() []string

EmailURLs are the pages the emails and the launch notice link to, exactly as they state them (rivolt.dev), fragments dropped.

func FoundingFromDB

func FoundingFromDB(pool *sql.DB, demo uuid.UUID) func(ctx context.Context, launch time.Time) (Founding, error)

FoundingFromDB reads the founding dry run's counts in a read-only transaction: nothing can be written through it.

func HTTPFetch

func HTTPFetch(ctx context.Context, url string) (int, error)

HTTPFetch GETs url with a short timeout and reports the status after redirects; the body is not read.

func HTTPPostUnsigned

func HTTPPostUnsigned(ctx context.Context, url string) (int, error)

HTTPPostUnsigned POSTs an empty body to url without following redirects and reports the status: what Stripe would get for an event with no signature.

func ManualSteps

func ManualSteps() []string

ManualSteps are the launch prerequisites that live in the Stripe Dashboard, Cloudflare and the Valkey pod, where this command has no view.

func URLs

func URLs(base string) []string

URLs are the pages the launch notice and the billing emails link to, on this deployment's own public base URL (the emails themselves carry rivolt.dev). Fragments are dropped; the Plan card and the export page are one path.

Types

type Founding

type Founding struct {
	Accounts int // every account
	Demo     int // 1 when the demo account exists
	Eligible int // accounts created at or before launch, the demo excluded
	Already  int // of those, with a founding row
	ToGrant  int
	After    int // accounts created after the launch instant (not granted)
}

Founding is what the founding grant would do at the launch instant, counts only.

type Input

type Input struct {
	Getenv func(string) string
	// Founding reads the counts; nil: the database part is skipped and the report says so.
	Founding func(ctx context.Context, launch time.Time) (Founding, error)
	// Fetch returns the status of a GET of url; nil skips the URL checks.
	Fetch func(ctx context.Context, url string) (int, error)
	// Webhook returns the status of an UNSIGNED, empty POST to url (Stripe's webhook endpoint); nil skips it.
	Webhook func(ctx context.Context, url string) (int, error)
	// RedisTime runs TIME as the app's Redis user, which is what the shared rate-limit script needs; nil skips it. It reports a denial
	// (the ACL) apart from the other failures.
	RedisTime func(ctx context.Context) (denied bool, err error)
	// Stripe reads the Stripe API with the configured key; nil skips it.
	Stripe func(ctx context.Context) StripeFacts
	// BillingAddress is what our Checkout sessions ask for as the billing address (stripebill.BillingAddressCollection): "required" lets the
	// webhook check the country (Rivolt Pro is sold in the US only).
	BillingAddress string
	Launch         time.Time
}

Input is everything the report reads, so a test drives it without a database, a network or the process environment.

type Report

type Report struct {
	Lines []string
	// Problems are what stops the flip; Warnings are worth a look but do not.
	Problems []string
	Warnings []string
}

Report is the result: lines to print and whether the deployment is ready for the flip.

func Run

func Run(ctx context.Context, in Input) *Report

Run builds the report.

func (*Report) Print

func (r *Report) Print(w io.Writer)

Print writes the report.

func (*Report) Ready

func (r *Report) Ready() bool

Ready is true when nothing stops the flip.

type StripeFacts

type StripeFacts struct {
	Err                 error
	Live                bool // the key and the prices are in live mode
	PricesActive        bool // both prices exist and are active
	PortalFound         bool
	TermsSet            bool // the Customer Portal's Terms of service URL
	PrivacySet          bool // and its Privacy policy URL
	PaymentMethodUpdate bool // customers can update their payment method in the portal
	// The payment method configuration our Checkout sessions use (RIVOLT_STRIPE_PAYMENT_METHOD_CONFIG): read at all, found and active, and the
	// payment method types it has on (sorted).
	PMCRead    bool
	PMCFound   bool
	PMCActive  bool
	PMCLive    bool // the configuration's livemode, to compare with the mode of the key (Live)
	PMCMethods []string
	// The account's DEFAULT configuration, which our sessions do not use but the Customer Portal's update-payment-method follows.
	CheckoutMethods []string
	CheckoutRead    bool
	TaxRead         bool // Stripe Tax's settings were read (only asked when automatic tax is on)
	TaxActive       bool // and Stripe Tax is active in this mode
}

StripeFacts is what the Stripe API says, booleans and a mode only. Err is set when the key could not read it (sanitised, no key).

Jump to

Keyboard shortcuts

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