Fix fresh-install migration blocker + add preflight, seed admin, first-run endpoints
Validated a clean install on MySQL 5.6 end to end and fixed the blockers. - migrations/env.py: force alembic_version.version_num to VARCHAR(128) in its own committed connection before running migrations. It was VARCHAR(32); the revision id 7d02_widen_notification_employee_cols (37 chars) truncated, so the next migration's version bump matched 0 rows and `flask db upgrade` died at 7d03 on a fresh DB. Now upgrades run clean to head. - flask db-utils preflight: checks Python, required env, DB connectivity, and the MySQL 5.6 utf8mb4 index flags (innodb_large_prefix/Barracuda) - the 767 prerequisite - and prints exact fixes. Exits non-zero on blockers. - flask seed admin --username --email [--password]: real first-admin command (generates + prints a password once). The docs referenced it but only the dev-only test-user existed. - setup endpoints for a UI-driven first run: /setup/needs-admin, /setup/create-admin (guarded to zero-users), /setup/seed-reference. - Wizard: drop the PC-access-domain question (always .device.geaerospace.net); the setting keeps its default. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -773,6 +773,15 @@ export const pluginsApi = {
|
||||
}
|
||||
|
||||
export const setupApi = {
|
||||
needsAdmin() {
|
||||
return api.get('/setup/needs-admin')
|
||||
},
|
||||
createAdmin(data) {
|
||||
return api.post('/setup/create-admin', data)
|
||||
},
|
||||
seedReference() {
|
||||
return api.post('/setup/seed-reference')
|
||||
},
|
||||
seedStarter() {
|
||||
return api.post('/setup/seed-starter')
|
||||
},
|
||||
|
||||
@@ -25,10 +25,6 @@
|
||||
<label>Site base URL <span class="hint">(blank = use the browsing origin)</span></label>
|
||||
<input v-model="form.site_base_url" type="url" class="form-control" placeholder="https://shopdb.example.net" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>PC access domain <span class="hint">(for remote-access links)</span></label>
|
||||
<input v-model="form.pc_access_domain" type="text" class="form-control" placeholder="device.geaerospace.net" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Plugins -->
|
||||
@@ -168,7 +164,7 @@ const step = ref(0)
|
||||
const current = computed(() => steps[step.value])
|
||||
|
||||
const form = ref({
|
||||
facility_name: '', site_base_url: '', pc_access_domain: '',
|
||||
facility_name: '', site_base_url: '',
|
||||
map_width: null, map_height: null,
|
||||
})
|
||||
const plugins = ref([])
|
||||
@@ -226,13 +222,13 @@ const envLines = computed(() => {
|
||||
|
||||
// Which settings each step owns, so Next only saves what changed on that step.
|
||||
const stepSettings = {
|
||||
site: ['facility_name', 'site_base_url', 'pc_access_domain'],
|
||||
site: ['facility_name', 'site_base_url'],
|
||||
map: ['map_width', 'map_height'],
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
// Load current values for the settings the wizard edits.
|
||||
const keys = ['facility_name', 'site_base_url', 'pc_access_domain', 'map_width', 'map_height']
|
||||
const keys = ['facility_name', 'site_base_url', 'map_width', 'map_height']
|
||||
for (const key of keys) {
|
||||
try {
|
||||
const response = await settingsApi.get(key)
|
||||
|
||||
Reference in New Issue
Block a user