Files
tiny-forge/CLAUDE.md
T
alexei.dolgolyov 410a131cec feat(apps): stepped creation wizard, branch previews, and app-creation fixes
This session (frontend focus):
- Rebuild /apps/new as a 4-step wizard (Basics → Configure → Trigger → Review):
  WizardRail, SourceKindPicker card grid, AppManifest review, per-step validation,
  ConfirmDialog-based unsaved-changes guard.
- Extract lib/workload/sourceForms.ts (single source of truth for source_config)
  + {Image,Compose,Static,Dockerfile}SourceForm + StaticDiscoveryWizard; fold the
  /apps/[id] edit form onto the same components (removes the duplication). Add
  vitest + sourceForms unit tests.
- Branch preview environments UI: /chain is_preview/preview_branch + a Preview
  environments panel on /apps/[id] (per-branch URLs, ConfirmDialog teardown, armed
  state); RegistryImagePicker on the registry trigger and the image source.
- Fixes: image-inspect 404 -> admin-gated POST /api/discovery/image/inspect;
  conflict-panel blur flicker; friendly localized discovery errors; CPU/Memory
  label hints; dashboard + /apps "Total workloads" count only source_kind workloads
  (drop stale trigger_kind gate); NPM cert/access-list name cache; EntityPicker
  empty-list guard.
- Update CLAUDE.md frontend conventions + add a Build & Test section.

Also captures pre-existing in-progress platform work (not from this session):
workload notifications, Prometheus metrics export, store lockfile, health probes,
backup hardening, and related store/webhook/scheduler changes.
2026-05-29 02:09:54 +03:00

2.2 KiB

Tinyforge

Dev Server

Start/restart with: ./scripts/dev-server.sh

  • Runs on port 8090 (avoids 8080 conflict with other local services)
  • Auto-generates ENCRYPTION_KEY if not set
  • Default login: admin / admin123
  • Override port: LISTEN_ADDR=:9000 ./scripts/dev-server.sh

Frontend

  • Boolean inputs use ToggleSwitch ($lib/components/ToggleSwitch.svelte) — the slide-style switch is the unified control across the WebUI. Do not introduce raw <input type="checkbox"> elements; place a <ToggleSwitch> next to a label/help block instead.
  • Confirmations & destructive actions use ConfirmDialog ($lib/components/ConfirmDialog.svelte) — never native window.confirm / alert. For navigation guards (e.g. the unsaved-changes prompt on /apps/new), cancel() the navigation in beforeNavigate, open ConfirmDialog, and re-issue the navigation with a bypass flag on confirm. Native beforeunload is acceptable only for hard tab-close/reload, where the browser forbids custom UI.
  • Source-config shape: $lib/workload/sourceForms.ts is the single source of truth (seed/serialize/validity for image/compose/static/dockerfile), consumed by both /apps/new and /apps/[id]. Don't re-inline seed/serialize logic.
  • "App" = workload with source_kind !== ''. Triggers are first-class bindings (workload_trigger_bindings), NOT on the workload row — never gate app lists/counts on trigger_kind (it's empty for plugin workloads). Legacy pre-cutover kind:project/stack/site rows have an empty source_kind and must be excluded everywhere.
  • i18n parity is mandatory — every key in BOTH web/src/lib/i18n/{en,ru}.json. A missing key is NOT a build error ($t returns the key string), so verify parity manually.

Build & Test

  • Frontend (from web/): npm run check (svelte-check — expect 0 errors), npm run build, npm run test (vitest; pure-logic units like sourceForms.test.ts).
  • Backend (repo root): go build ./..., go vet ./internal/..., go test ./internal/....
  • ./scripts/dev-server.sh rebuilds the SPA + restarts the Go server on :8090; it kills the prior process, so a previous background dev-server task reporting exit 1 is expected, not a failure.