Operator request: when MYSQL_FAKE_ENABLED=false (the dev default + the only
viable setting behind Cloudflare Tunnel since CF Tunnel doesn't carry raw
TCP), surface that in the UI so users can see the species but understand
they can't deploy it on this instance. Avoids the silent-broken case where
someone creates a mysql token, gets a connection_string artifact, points
their MySQL client at it, and just times out with no clue why.
Backend (3-line change):
- TypeDescriptor gains `Enabled bool` + optional `DisabledReason string`
- TypeDescriptors() now takes `mysqlEnabled bool`; mysql is the one whose
Enabled tracks the flag, all others are always true (they don't need
any deployment-level infra beyond HTTP)
- Handler stores mysqlEnabled, passes to descriptors call; main.go wires
cfg.MySQL.Enabled in. Handler tests updated to pass false explicitly.
Frontend (matching schema + visual treatment):
- typeDescriptorSchema picks up `enabled` (default true for backward compat)
and `disabled_reason` (optional string)
- TypeCard reads descriptor.enabled, sets `data-disabled` on the label,
disables the radio input, replaces the blurb with the disabled_reason
when present (so the user sees WHY rather than guessing), and renders
a small "disabled" pill in the top-right corner of the card
- SCSS: dashed border, muted palette, opacity 0.55, glyph faded, cursor
not-allowed, hover effect suppressed — reads as "shelf is here but the
specimen is checked out" rather than a broken button
In the operator UI: mysql card renders ghosted with the explanatory text
"Requires direct TCP exposure (port 3306). Not reachable via Cloudflare
Tunnel — only enable on a VPS with raw TCP access." Selecting it is
mechanically impossible (input is disabled), no form-level guard needed.
Flip MYSQL_FAKE_ENABLED=true in env when you stand up a VPS later and the
card re-enables with no other code changes.
Backend builds clean + token-package tests pass.
Frontend gates green: typecheck + biome + lint:scss + build (431ms).