From 57efb5f96549f1bd90ae804ceccf73a7d95105e4 Mon Sep 17 00:00:00 2001 From: cproudlock Date: Fri, 10 Jul 2026 11:53:38 -0400 Subject: [PATCH] First-run creates the superadmin in-app; wizard seeds reference data No CLI needed for a UI-driven install. - Login page: when the instance has no users yet (/setup/needs-admin), it shows a "create the first admin" form instead of login. Submitting creates the admin (admin role = full access / superadmin) via /setup/create-admin, logs in, and goes to the setup wizard. - Wizard Starter Data step: "Seed core reference data" button (statuses, types, permissions, default settings via /setup/seed-reference) alongside the common vendors, so a UI-first install gets the data the app needs. - Add waitress to requirements.txt (the IIS web.config launches it but it was missing - found while validating the Windows install). Co-Authored-By: Claude Opus 4.8 (1M context) --- frontend/src/views/Login.vue | 88 ++++++++++++++++++++---------- frontend/src/views/SetupWizard.vue | 33 +++++++++-- requirements.txt | 1 + 3 files changed, 90 insertions(+), 32 deletions(-) diff --git a/frontend/src/views/Login.vue b/frontend/src/views/Login.vue index ee903d3..ab0daa2 100644 --- a/frontend/src/views/Login.vue +++ b/frontend/src/views/Login.vue @@ -4,34 +4,40 @@

ShopDB

-
- {{ error }} -
+
{{ error }}
-
+ + + + +
- +
-
- +
- @@ -41,30 +47,56 @@ + + diff --git a/frontend/src/views/SetupWizard.vue b/frontend/src/views/SetupWizard.vue index 2bceff2..cc64110 100644 --- a/frontend/src/views/SetupWizard.vue +++ b/frontend/src/views/SetupWizard.vue @@ -112,10 +112,21 @@

Starter data

-

Add common hardware vendors so you can start adding assets right away. Safe to run - it skips ones you already have.

- +

Seed the data a new site needs. Both are idempotent - safe to run more than once.

+
+
+ +

Statuses, machine/location/relationship types, permissions, default settings. Run this if you installed without the CLI seed.

+
+
+ +

Dell, HP, Lenovo, and other common hardware vendors.

+
+

{{ seedResult }}

@@ -325,6 +336,18 @@ async function togglePlugin(plugin, enabled) { } } +async function seedReference() { + seeding.value = true + try { + const response = await setupApi.seedReference() + seedResult.value = response.data?.message || 'Reference data seeded.' + } catch (err) { + toast.error(apiError(err, 'Could not seed reference data')) + } finally { + seeding.value = false + } +} + async function seedStarter() { seeding.value = true try { @@ -384,6 +407,8 @@ async function finish() { .provision-note p:last-child { margin-bottom: 0; } .provision-tables code, .provision-docs code { background: var(--bg-card); border: 1px solid var(--border); border-radius: 3px; padding: 0 0.3rem; margin-right: 0.3rem; font-size: 0.78rem; } .seed-result { margin-top: 0.75rem; color: var(--success); font-size: 0.88rem; } +.starter-actions { display: flex; flex-direction: column; gap: 1.1rem; } +.starter-actions .hint { margin: 0.35rem 0 0; } .config-block { margin-top: 1.25rem; padding-top: 1rem; border-top: 1px solid var(--border); } .config-title { margin: 0 0 0.75rem; font-size: 1rem; text-transform: capitalize; } .secret-tag { margin-left: 0.5rem; font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--warning); border: 1px solid var(--warning); border-radius: 4px; padding: 0 0.3rem; } diff --git a/requirements.txt b/requirements.txt index 4368c8c..3046104 100644 --- a/requirements.txt +++ b/requirements.txt @@ -117,3 +117,4 @@ werkzeug==3.1.8 # flask-cors # flask-jwt-extended # pytest-flask +waitress>=3.0