Skip to content

Strip

Strip is the Go SSR frontend for internal/admin-style workflows.

Strip uses Go, Fiber, Templ, and Tailwind. The build order is Templ, Tailwind, then the Go binary.

Strip’s interface uses the Foxy design system: Rethink Sans for UI type and Parisienne for the wordmark and script accents, the Foxy pink/red/ink palette, fully rounded pill controls, and soft cards over a light or dark canvas. Design tokens are defined as Tailwind v4 semantic CSS variables in apps/strip/internal/app/assets/css/input.css, and the always-dark sidebar rail plus the brand wordmark/butterfly assets in apps/strip/internal/app/assets/ drive the shared chrome. When restyling, change tokens and shared components first so every page inherits the update rather than styling page by page.

  • apps/strip/cmd/
  • apps/strip/internal/app/
  • apps/strip/cmd/build-assets/

Strip talks to sirloin over the proto/sirloin/v5/ subset it consumes.

Strip decisions live under docs/src/content/docs/decisions/ when durable.

The templ CLI must be available on the host before local build commands run.

With an Admin or Root account, open Popular Examples → Media preflight. Upload the private selection.json, then select Run preflight. The selection must contain 30 distinct examples: 10 images, 15 videos and 5 five-image carousels. The Sirloin preflight documents the input format and the checks. Strip preserves the uploaded bytes and their selection hash. Do not upload credentials or media URLs.

Sirloin checks the media in a background River job using its existing database, S3 and Brain connections. Strip polls the job and displays its status and counts. Download full JSON saves every example’s result and failure reason in the complete receipt. Keep this file private. Download it within 24 hours, before completed jobs expire. Reloading the result URL retrieves the saved job rather than starting another run.

The check prepares media and builds a model request without sending it. It does not enroll examples, activate tagging, or change catalogue or Brain records. Only the job and report are stored. A matching active selection reuses its job; a different selection must wait until the active run finishes. Both RPCs check the operator’s current Admin or Root role and use the same closed-VPC trust boundary and optional service-token enforcement as other Strip RPCs.

Sources: apps/strip/internal/app/handlers/mediapreflight.go, apps/sirloin/internal/app/services/strip/stripmediapreflight.go, and apps/sirloin/internal/app/worker/mediapreflight.go.

In Characters, open Filters and set Deletion to Deleted only. Search by character name, owner email, or character ID. Open the character’s details, select Restore character, and confirm. Support, Admin, and Root roles can restore characters. The list refreshes with its filters preserved.

Restoration clears the character’s deletion timestamp and records the operator in the audit log. It does not recover deleted dataset images, retrain the character, or reverse refunds. If another active character uses the Foxy handle or occupies the same adult identity slot, restoration fails without changing either character. See apps/strip/internal/app/handlers/characterrestore.go and apps/sirloin/internal/pkg/storage/striprestorecharacter.go.

Open user details and find the selfie reset controls beside KYC. The count is account lifetime usage, including support resets. Customers can reset three times; afterward Brisket explains that they must contact support. Enter a reason and confirm using a Support, Admin or Root account with selfie-reset permission. No character or open setup session is required.

This action resets account-wide KYC immediately. Tell the customer to complete verification again. It does not issue a reusable grant, replenish the customer’s allowance, or change character adult approvals, identity anchors, assets or media. The reset history and Strip audit record the reviewer, reason and count change in the same transaction. Retrying a submitted request cannot perform another reset; stale verification requires refreshing user details.

Support overrides only the three-reset quota. Approved current KYC is still required, and the existing NSFW-media eligibility rule still applies. Deleting the relevant media or character can remove the media block, but never restores reset allowance. Adult enablement alone does not block resets. See account reset semantics and apps/sirloin/internal/pkg/storage/accountselfiereset.go.

In a user’s details, Payment processors → NSFW routing sets the NSFW processor and the merchant account (MID) Primer routes the user by. CS picks one processor and MID pair from a fixed list in Strip’s code, chosen by STRIP_STAGE: production lists the live merchant accounts, every other stage the Primer sandbox ones. A “no MID” route clears the MID, which sends the user to the workflow’s default branch; on NMI the next subscription settle backfills the MID it settled on, so a cleared NMI MID lasts only until then. MIDs are case-sensitive Primer literals, so a new merchant account is added to the list in the same release as its Primer workflow branch. Strip and Sirloin ship from the same merge; until the Sirloin that stores the MID is live, Sirloin ignores nsfw_processor_mid and still reports success, so check Current after saving. Support, Admin and Root roles can edit it, and every change is in the audit log with the MID before and after. A MID the user’s saved card cannot be charged on declines their renewals, so change it only for a user whose payments are known to belong there. See apps/strip/internal/app/config/nsfwroutes.go and apps/sirloin/internal/pkg/storage/stripupdateuser.go.

Strip authenticates operators against its own Clerk instance with STRIP_CLERK_SECRET_KEY. The user impersonation button mints Clerk actor tokens for main app users, so it must use STRIP_IMPERSONATION_CLERK_SECRET_KEY from the main app Clerk instance instead. Do not reuse Strip’s admin Clerk secret for this value.

  • cd apps/strip && make build
  • cd apps/strip && make run-tests
  • cd apps/strip && make lint

CI runs the same checks in .github/workflows/strip.yml and reports them as the strip check. CI pins golangci-lint v2.14.0, so a different local version can disagree with it. CI also fails when templ generate changes committed files, because the Railway build regenerates Templ code before go build.