Add link previews and icons; make PIG_INVITE_CODE actually work

Social and icons. A 1200x630 card, apple-touch-icon, and maskable PWA icons,
generated from an HTML template by a script so the mark, wordmark and tagline
cannot drift from the product. The apple-touch-icon referenced in index.html
was a 404 until now. Icons are drawn on an opaque plate with inset because iOS
rounds corners and Android may apply a circle — an edge-to-edge mark loses its
ears to that crop. og:image is absolute, which is the single most common
reason a card unfurls blank.

PIG_INVITE_CODE was a lie. Signup validates against the invites table, so
setting the variable only flipped a label in the UI — an operator would set it,
hand the code to a colleague, and watch them be rejected. It is now reconciled
into a real invite row at boot: setting it issues, changing it rotates and
revokes the predecessor, and removing it revokes. Verified all three, plus that
a restart with an unchanged code does not duplicate.

Two bugs found while doing that:

- `uses_remaining` was jsonb, so the SQL decrement could never have worked.
  Now integer. The generated migration failed because Postgres has no implicit
  jsonb->integer cast, so the USING clause is hand-written.
- Redemption keyed off `redeemedAt`, which would have made every reusable
  invite single-use — a confusing way to lock a team out. Availability now
  comes from `usesRemaining`, and redemption records who used it most recently
  without consuming it.

Sign-in gains a password option alongside the magic link, defaulting to
password since that is the daily path. PIG stores neither; both are handled by
the identity provider and PIG only ever sees the resulting token.
autocomplete is set so password managers and iOS can fill.

Verified: full migration chain applies to a fresh Postgres, the CSP hash for
the inline theme script is unchanged by the rebuild.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-12 19:43:10 -07:00
parent 93818a2d2c
commit 0551e8dd6e
19 changed files with 6855 additions and 53 deletions
+41 -1
View File
@@ -22,10 +22,50 @@
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<meta name="apple-mobile-web-app-title" content="pig" />
<!--
Icons. The SVG is preferred by every modern browser and adapts to the
system theme; the PNG is the fallback for those that do not. The
apple-touch-icon is drawn on an opaque plate with inset, because iOS
rounds the corners itself and a transparent edge-to-edge mark loses its
ears to the crop.
-->
<link rel="icon" href="/pig.svg" type="image/svg+xml" />
<link rel="apple-touch-icon" href="/pig-touch.png" />
<link rel="icon" href="/icon-192.png" type="image/png" sizes="192x192" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<link rel="manifest" href="/manifest.webmanifest" />
<title>pig — Prime Intellect Growth</title>
<link rel="canonical" href="https://primeintellectgrowth.com/" />
<!--
Link previews. og:image must be an ABSOLUTE url — unfurlers fetch it
without a page context, so a relative path silently yields no image,
which is the single most common reason a card renders blank.
summary_large_image gives the 1200×630 card rather than a small square
thumbnail. Both og: and twitter: tags are present because Slack, Discord,
LinkedIn and iMessage read Open Graph while X prefers its own.
-->
<meta property="og:type" content="website" />
<meta property="og:site_name" content="pig" />
<meta property="og:url" content="https://primeintellectgrowth.com/" />
<meta property="og:title" content="pig — Prime Intellect Growth" />
<meta
property="og:description"
content="An open-source, agent-native CRM for companies that buy GPU capacity and sell it. Margin, utilisation and idle capacity from one ledger."
/>
<meta property="og:image" content="https://primeintellectgrowth.com/og.png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:image:alt" content="pig — Prime Intellect Growth. The CRM for companies that buy compute and sell it." />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="pig — Prime Intellect Growth" />
<meta
name="twitter:description"
content="An open-source, agent-native CRM for companies that buy GPU capacity and sell it. Margin, utilisation and idle capacity from one ledger."
/>
<meta name="twitter:image" content="https://primeintellectgrowth.com/og.png" />
<script>
// Applied before first paint so a dark-mode user never sees a white