Skip to main content

Bootstrap API

The Bootstrap API manages first-time system initialization, creating the initial administrator account and marking the system as ready for use.
One-Time Operation: Bootstrap can only be performed once. After successful initialization, all bootstrap endpoints are permanently disabled for security.

Authentication

Bootstrap endpoints do not require authentication (they run before any users exist). However, they require the correct bootstrap password from environment configuration.

Get Bootstrap Status

GET /api/bootstrap/status
Checks whether the system has been initialized.

Response

completed
boolean
Whether bootstrap has been completed
message
string
Status message

Example Request

cURL
curl -X GET https://api.example.com/api/bootstrap/status

Example Responses

Not Yet Initialized:
{
  "success": true,
  "data": {
    "completed": false,
    "message": "Sistema no inicializado. Requiere bootstrap."
  }
}
Already Initialized:
{
  "success": true,
  "data": {
    "completed": true,
    "message": "Sistema ya inicializado."
  }
}

Get Initialization Data

GET /api/bootstrap/data
Returns configuration data needed for the bootstrap UI (areas, roles, etc.).

Response

areas
array
Available organizational areas
roles
array
Available system roles
sistemaNombre
string
System name (PROD-SYS)

Example Response

{
  "success": true,
  "data": {
    "areas": [
      {"id": 1, "nombre": "Producci\u00f3n"},
      {"id": 2, "nombre": "Calidad"},
      {"id": 3, "nombre": "Mantenimiento"},
      {"id": 4, "nombre": "Administraci\u00f3n"}
    ],
    "roles": [
      {"id": 1, "nombre": "Administrador"},
      {"id": 2, "nombre": "Supervisor"},
      {"id": 3, "nombre": "Inspector"},
      {"id": 4, "nombre": "Operario"}
    ],
    "sistemaNombre": "PROD-SYS"
  }
}

Initialize System

POST /api/bootstrap/init
Performs system initialization, creating the administrator account.

Request Body

bootstrapPassword
string
required
Bootstrap password from .env file (ADMIN_PASSWORD)
newPassword
string
required
New password for the admin account (minimum 8 characters)
adminNombre
string
Administrator’s first name (defaults to “Administrador”)
adminApellido
string
Administrator’s last name (defaults to “Sistema”)

Business Logic

From bootstrap.service.js:30:
async initialize(data) {
  // 1. Check if already initialized
  const isBootstrapped = await this.repository.isBootstrapCompleted();
  if (isBootstrapped) {
    throw new AppError('El sistema ya ha sido inicializado.', 400);
  }

  // 2. Validate bootstrap password
  if (data.bootstrapPassword !== process.env.ADMIN_PASSWORD) {
    throw new AppError('Contrase\u00f1a de bootstrap incorrecta.', 401);
  }

  // 3. Create admin person record
  const personaId = await this.repository.createAdminPerson({
    nombre: data.adminNombre || 'Administrador',
    apellido: data.adminApellido || 'Sistema',
    codigo_interno: 'ADMIN-001'
  });

  // 4. Create admin user account
  const hashedPassword = await bcrypt.hash(data.newPassword, 10);
  await this.repository.createAdminUser({
    persona_id: personaId,
    username: 'admin',
    password_hash: hashedPassword,
    rol: 'Administrador'
  });

  // 5. Mark bootstrap as completed
  await this.repository.markBootstrapCompleted();

  // 6. Log audit event
  await this.auditService.logCreate('SISTEMA', 'Bootstrap', null, {
    usuario: 'admin',
    persona_id: personaId
  }, 'Sistema inicializado');

  return { success: true, username: 'admin' };
}

Example Request

cURL
curl -X POST https://api.example.com/api/bootstrap/init \\
  -H "Content-Type: application/json" \\
  -d '{
    "bootstrapPassword": "YourBootstrapPassword123!",
    "newPassword": "SecureAdminPass456!",
    "adminNombre": "Carlos",
    "adminApellido": "Admin"
  }'

Example Response

{
  "success": true,
  "data": {
    "username": "admin",
    "message": "Sistema inicializado correctamente. Puede iniciar sesi\u00f3n con el usuario 'admin'."
  }
}

Error Responses

400 Bad Request
System already initialized:
{
  "success": false,
  "error": "El sistema ya ha sido inicializado."
}
401 Unauthorized
Incorrect bootstrap password:
{
  "success": false,
  "error": "Contrase\u00f1a de bootstrap incorrecta."
}
400 Bad Request
Weak password:
{
  "success": false,
  "error": "La contrase\u00f1a debe tener al menos 8 caracteres."
}

Bootstrap Workflow

1

Check Status

Call GET /api/bootstrap/status to verify system needs initialization
2

Prepare Bootstrap

Retrieve .env file’s ADMIN_PASSWORD value
3

Initialize

POST to /api/bootstrap/init with bootstrap password and new admin password
4

Login

Use /api/auth/login with username “admin” and the new password
5

Configure System

Add more users, configure processes, import production orders

Security Considerations

Bootstrap Password Protection: The ADMIN_PASSWORD environment variable should be:
  • Changed from default value before first use
  • Strong and unique (not reused elsewhere)
  • Removed from .env after bootstrap completes (optional but recommended)
  • Never committed to version control
One-Time Execution: After bootstrap completes, the system_config table is updated:
UPDATE system_config SET value = '1' WHERE key = 'bootstrap_completed';
This flag is checked on every bootstrap request, ensuring the operation can never be repeated.

Resetting Bootstrap

Destructive Operation: Resetting bootstrap should only be done in development or emergency situations.
If you must reset bootstrap:
sqlite3 backend/database/mfcalidad.sqlite "UPDATE system_config SET value = '0' WHERE key = 'bootstrap_completed';"
Then restart the server. This allows running bootstrap again, but does not delete the existing admin user.

Bootstrap Middleware

From middlewares/bootstrap.middleware.js:
module.exports = async (req, res, next) => {
  // Allow bootstrap endpoints and login to pass through
  if (req.path.startsWith('/api/bootstrap') || req.path === '/api/auth/login') {
    return next();
  }

  // Check if bootstrap completed
  const completed = await bootstrapRepository.isBootstrapCompleted();
  
  if (!completed) {
    return res.status(403).json({
      success: false,
      error: 'Sistema no inicializado. Complete el bootstrap primero.',
      redirectTo: '/bootstrap.html'
    });
  }

  next();
};
All API endpoints (except bootstrap and login) are blocked until bootstrap completes.

Best Practices

Automated Setup Scripts: For development environments, create automated bootstrap scripts:
# wait for server to start
sleep 5

# bootstrap system
curl -X POST http://localhost:3000/api/bootstrap/init \\
  -H "Content-Type: application/json" \\
  -d '{
    "bootstrapPassword": "'$ADMIN_PASSWORD'",
    "newPassword": "dev-admin-123"
  }'
Verify After Bootstrap: Always verify successful initialization:
  1. Check status endpoint returns completed: true
  2. Login with admin credentials
  3. Access protected endpoints
  4. Verify audit log has bootstrap event

Build docs developers (and LLMs) love