Installer reliability improvements (#593)

* docs: add CLAUDE.md for Claude Code guidance

* fix: handle missing settings table in installation middlewares

RedirectIfInstalled crashed with "no such table: settings" when the
database_created marker file existed but the database was empty.
Changed to use isDbCreated() which verifies actual tables, and added
try-catch around Setting queries in both middlewares.

* feat: pre-select database driver from env in installation wizard

The database step now reads DB_CONNECTION from the environment and
pre-selects the matching driver on load, including correct defaults
for hostname and port.

* feat: pre-select mail driver and config from env in installation wizard

The email step now fetches the current mail configuration on load
instead of hardcoding the driver to 'mail'. SMTP fields fall back
to Laravel config values from the environment.

* refactor: remove file-based DB marker in favor of direct DB checks

The database_created marker file was a second source of truth that
could drift out of sync with the actual database. InstallUtils now
checks the database directly via Schema::hasTable which is cached
per-request and handles all error cases gracefully.
This commit is contained in:
Darko Gjorgjijoski
2026-04-02 14:48:08 +02:00
committed by GitHub
parent 375cfc6b18
commit a38f09cf7b
12 changed files with 118 additions and 78 deletions

View File

@@ -15,7 +15,7 @@
</template>
<script>
import { ref, computed } from 'vue'
import { ref, computed, onMounted } from 'vue'
import Mysql from './database/MysqlDatabase.vue'
import Pgsql from './database/PgsqlDatabase.vue'
import Sqlite from './database/SqliteDatabase.vue'
@@ -47,8 +47,9 @@ export default {
})
async function getDatabaseConfig(connection) {
let params = {
connection,
let params = {}
if (connection) {
params.connection = connection
}
const res = await installationStore.fetchInstallationDatabase(params)
@@ -58,10 +59,16 @@ export default {
res.data.config.database_connection
}
if (connection === 'sqlite') {
if (res.data.config.database_connection === 'sqlite') {
databaseData.value.database_name = res.data.config.database_name
} else {
databaseData.value.database_name = null
if (res.data.config.database_host) {
databaseData.value.database_hostname = res.data.config.database_host
}
if (res.data.config.database_port) {
databaseData.value.database_port = res.data.config.database_port
}
}
}
@@ -127,6 +134,10 @@ export default {
}
}
onMounted(() => {
getDatabaseConfig()
})
return {
databaseData,
database_connection,

View File

@@ -41,8 +41,6 @@ export default {
const mailDriverStore = useMailDriverStore()
mailDriverStore.mail_driver = 'mail'
loadData()
function changeDriver(value) {
@@ -52,6 +50,7 @@ export default {
async function loadData() {
isFetchingInitialData.value = true
await mailDriverStore.fetchMailDrivers()
await mailDriverStore.fetchMailConfig()
isFetchingInitialData.value = false
}