410a131cec
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.
2.2 KiB
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_KEYif 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 nativewindow.confirm/alert. For navigation guards (e.g. the unsaved-changes prompt on/apps/new),cancel()the navigation inbeforeNavigate, openConfirmDialog, and re-issue the navigation with a bypass flag on confirm. Nativebeforeunloadis acceptable only for hard tab-close/reload, where the browser forbids custom UI. - Source-config shape:
$lib/workload/sourceForms.tsis the single source of truth (seed/serialize/validity for image/compose/static/dockerfile), consumed by both/apps/newand/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 ontrigger_kind(it's empty for plugin workloads). Legacy pre-cutoverkind:project/stack/siterows have an emptysource_kindand 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 ($treturns 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 likesourceForms.test.ts). - Backend (repo root):
go build ./...,go vet ./internal/...,go test ./internal/.... ./scripts/dev-server.shrebuilds 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.