Cybersecurity-Projects/PROJECTS/beginner/canary-token-generator/frontend
CarterPerez-dev 8d2599c01a feat(canary): mark MySQL type as disabled when mysql.enabled=false
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).
2026-05-17 22:45:53 -04:00
..
public/asset feat(canary): import operator's React + Vite frontend template 2026-05-10 05:28:09 -04:00
src feat(canary): mark MySQL type as disabled when mysql.enabled=false 2026-05-17 22:45:53 -04:00
.dockerignore feat(canary): import operator's React + Vite frontend template 2026-05-10 05:28:09 -04:00
.gitignore feat(canary): import operator's React + Vite frontend template 2026-05-10 05:28:09 -04:00
.stylelintignore fix(canary-phase1): clear all post-phase-1 audit observations + header normalization 2026-05-10 06:15:26 -04:00
biome.json feat(canary): import operator's React + Vite frontend template 2026-05-10 05:28:09 -04:00
index.html feat(canary): web fonts — Archivo Black / Space Grotesk / Departure Mono 2026-05-17 17:27:35 -04:00
package.json feat(canary): import operator's React + Vite frontend template 2026-05-10 05:28:09 -04:00
pnpm-lock.yaml feat(canary): import operator's React + Vite frontend template 2026-05-10 05:28:09 -04:00
stylelint.config.js fix(canary-phase1): clear all post-phase-1 audit observations + header normalization 2026-05-10 06:15:26 -04:00
tsconfig.app.json feat(canary): import operator's React + Vite frontend template 2026-05-10 05:28:09 -04:00
tsconfig.json feat(canary): import operator's React + Vite frontend template 2026-05-10 05:28:09 -04:00
tsconfig.node.json feat(canary): import operator's React + Vite frontend template 2026-05-10 05:28:09 -04:00
vite.config.ts fix(canary): vite dev proxy — correct backend port + stop stripping /api 2026-05-17 17:37:36 -04:00