diff --git a/README_INSTALLER.md b/README_INSTALLER.md
new file mode 100644
index 00000000..04a5e37f
--- /dev/null
+++ b/README_INSTALLER.md
@@ -0,0 +1,7 @@
+# Installer UI
+
+This document provides an overview of the installer UI and its usage.
+
+## Features
+- Standalone installer.
+- User creation functionality.
\ No newline at end of file
diff --git a/public/installer.php b/public/installer.php
new file mode 100644
index 00000000..2996fb1e
--- /dev/null
+++ b/public/installer.php
@@ -0,0 +1,525 @@
+
Installer disabled
Set INSTALLER_ENABLED=true in your .env to enable.
This installer runs common setup tasks. Make sure this is disabled (INSTALLER_ENABLED=false or remove file) after use.
+
+
+
+ Installer Key is configured. Requests must include ?key=YOUR_KEY or send key in POST/JSON.
+
+
+
+ No INSTALLER_KEY set. For safety set INSTALLER_KEY in your .env. Example: INSTALLER_KEY== $example_key ?>
+
+
+
+
+
+
+
+ Steps
+
+
+
+
+
+
+
+
+
+
+
+
+ Settings
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Create Users
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Console Output
+
+
+
+
+
+
+
+
Quick Status
+
Checking...
+
+
+ - Commands are executed on the server using CLI binaries found in PATH or as set in .env (COMPOSER_BINARY, PHP_BINARY, NPM_BINARY).
+ - Composer must be run first. Artisan commands require vendor installed.
+ - After finishing, disable the installer by setting INSTALLER_ENABLED=false.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/storage/installer/create_users.php b/storage/installer/create_users.php
new file mode 100644
index 00000000..74b00323
--- /dev/null
+++ b/storage/installer/create_users.php
@@ -0,0 +1,67 @@
+
+// JSON: { "users": [ { "name":"", "email":"", "password":"", "role":"" }, ... ] }
+
+$arg = $argv[1] ?? null;
+if (!$arg) {
+ echo "No data provided\n";
+ exit(1);
+}
+$data = json_decode(base64_decode($arg), true);
+if (!$data || !isset($data['users'])) {
+ echo "Invalid payload\n";
+ exit(1);
+}
+
+$projectRoot = dirname(__DIR__, 2);
+require $projectRoot . '/vendor/autoload.php';
+
+$app = require $projectRoot . '/bootstrap/app.php';
+$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
+$kernel->bootstrap();
+
+use Illuminate\Support\Facades\Hash;
+
+foreach ($data['users'] as $u) {
+ if (!isset($u['name'],$u['email'],$u['password'])) {
+ echo "Skipping incomplete user\n";
+ continue;
+ }
+ try {
+ // Create user using Eloquent (App\Models\User)
+ $userClass = '\App\Models\User';
+ if (!class_exists($userClass)) {
+ echo "User model not found\n";
+ continue;
+ }
+ if (call_user_func([$userClass, 'where'], 'email', $u['email'])->exists()) {
+ echo "User {$u['email']} already exists, skipping\n";
+ continue;
+ }
+ $user = $userClass::create([
+ 'name' => $u['name'],
+ 'email' => $u['email'],
+ 'password' => Hash::make($u['password']),
+ ]);
+ // Assign role if Spatie exists and user has assignRole
+ if (class_exists('\Spatie\Permission\Models\Role') && method_exists($user, 'assignRole') && !empty($u['role'])) {
+ if (!\Spatie\Permission\Models\Role::where('name', $u['role'])->exists()) {
+ \Spatie\Permission\Models\Role::create(['name' => $u['role']]);
+ }
+ $user->assignRole($u['role']);
+ echo "Created user {$u['email']} with role {$u['role']}\n";
+ } else {
+ // fallback attempt to set role attribute
+ if (array_key_exists('role', $user->getAttributes()) && isset($u['role'])) {
+ $user->role = $u['role'];
+ $user->save();
+ echo "Created user {$u['email']} (role attribute set)\n";
+ } else {
+ echo "Created user {$u['email']} (no role assigned)\n";
+ }
+ }
+ } catch (Exception $e) {
+ echo "Failed to create {$u['email']}: " . $e->getMessage() . "\n";
+ }
+}