Files
Axia4/DATA_STRUCTURE.md
copilot-swe-agent[bot] 0c362fd40b feat: SQLite DB with migrations replaces all JSON file storage
- Add db.php with PDO singleton, migration runner, and all helper functions
- Add migrations/001_initial_schema.sql (full schema)
- Add migrations/002_import_json.php (one-time JSON → DB importer)
- Add _incl/switch_tenant.php POST endpoint for tenant/centro switching
- Update tools.auth.php: DB-backed login, cookie auth, session reload, init_active_centro()
- Update all sysadmin pages (users, centros, aularios, invitations, reset_password) to use DB
- Update aulatek/index.php, aulario.php, supercafe.php, supercafe_edit.php to use DB
- Update aulatek/comedor.php and api/comedor.php to use DB
- Update aulatek/paneldiario.php: aulario config + comedor data from DB
- Update aulatek/proyectos.php: aulario config + sharing metadata from DB
- Update club/cal.php, index.php, edit_data.php, upload/upload.php to use DB
- Update account/index.php: rich profile, tenant list, aula list, session info, permissions
- Update pre-body.php account dropdown: shows active org + inline tenant switcher
- Update DATA_STRUCTURE.md to document DB approach and migration system

Co-authored-by: naielv <109038805+naielv@users.noreply.github.com>
2026-03-06 22:00:48 +00:00

6.7 KiB

Data Architecture for Axia4

Axia4 uses a SQLite database (/DATA/axia4.sqlite) for all structured data, with the filesystem reserved for binary assets (photos, uploaded files, project documents).

Database (/DATA/axia4.sqlite)

The schema is defined in public_html/_incl/migrations/001_initial_schema.sql and applied automatically on first boot via db.php.

Table Replaces
config /DATA/AuthConfig.json
users /DATA/Usuarios/*.json
invitations /DATA/Invitaciones_de_usuarios.json
centros Directory existence at .../Centros/{id}/
user_centros entreaulas.centro + entreaulas.aulas in users
aularios .../Aularios/{id}.json
supercafe_menu .../SuperCafe/Menu.json
supercafe_orders .../SuperCafe/Comandas/*.json
comedor_menu_types .../Comedor-MenuTypes.json
comedor_entries .../Comedor/{ym}/{day}/_datos.json
club_events /DATA/club/IMG/{date}/data.json
club_config /DATA/club/config.json

Migrations

Migrations live in public_html/_incl/migrations/:

  • 001_initial_schema.sql — DDL for all tables.
  • 002_import_json.php — One-time importer: reads existing JSON files and inserts them into the database. Run automatically on first boot if JSON files exist and the DB is empty.

Filesystem (binary / large assets)

DATA/
└── entreaulas/
    └── Centros/
        └── {centro_id}/
            ├── Aularios/
            │   └── {aulario_id}/
            │       ├── Alumnos/            # Student photo directories
            │       │   └── {alumno}/photo.jpg
            │       ├── Comedor/{ym}/{day}/  # Comedor pictogram images
            │       └── Proyectos/          # Project binary files
            └── Panel/
                └── Actividades/{name}/photo.jpg   # Activity photos
└── club/
    └── IMG/{date}/          # Club event photos (still on filesystem)

Multi-Tenant Support

A user can belong to multiple centros (organizations). The active centro is stored in $_SESSION['active_centro'] and can be switched at any time via POST /_incl/switch_tenant.php.

The account page (/account/) shows all assigned organizations and lets the user switch between them.

This directory contains example data files that demonstrate the structure needed for the Axia4 application.

Directory Structure

DATA/
├── Usuarios.json                          # Main application users
└── entreaulas/
    ├── Usuarios/                          # EntreAulas user files
    │   ├── user1.json
    │   └── user2.json
    └── Centros/                           # Centro data
        ├── centro1/
        │   ├── Aularios/
        │   │   ├── aulario_abc123.json
        │   │   └── aulario_xyz456.json
        │   └── SuperCafe/                 # SuperCafe data (per centro)
        │       ├── Menu.json              # Menu items / categories (optional)
        │       └── Comandas/              # One JSON file per order
        │           └── sc<id>.json
        └── centro2/
            └── Aularios/
                └── aulario_def789.json

File Examples

SuperCafe (persons come from the existing Alumnos system)

Persons are loaded automatically from the aulario Alumnos directories — no separate configuration file is needed. See the Aulario Student Names section for the alumnos data format.

SuperCafe Menu (DATA/entreaulas/Centros/{centro_id}/SuperCafe/Menu.json)

{
  "Bebidas": {
    "Café": 1,
    "Zumo": 1.5
  },
  "Comida": {
    "Bocadillo": 2.5,
    "Ensalada": 3
  }
}

SuperCafe Order (DATA/entreaulas/Centros/{centro_id}/SuperCafe/Comandas/{id}.json)

{
  "Fecha": "2024-01-15",
  "Persona": "aulario_abc123:Juan",
  "Comanda": "1x Café, 1x Bocadillo",
  "Notas": "Sin azúcar",
  "Estado": "Pedido"
}

Persona is stored as {aulario_id}:{alumno_name} and resolved to a display name at render time. Order statuses: Pedido, En preparación, Listo, Entregado, Deuda. A person with 3 or more orders in Deuda status cannot place new orders.

Main Users (DATA/Usuarios.json)

{
  "username1": {
    "password_hash": "$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi"
  },
  "username2": {
    "password_hash": "$2y$10$example_hash_here"
  }
}

EntreAulas User (DATA/entreaulas/Usuarios/username.json)

{
  "password_hash": "$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi",
  "display_name": "John Doe",
  "centro": "centro1",
  "aulas": [
    "aulario_abc123",
    "aulario_xyz456"
  ]
}

Aulario Configuration (DATA/entreaulas/Centros/{centro_id}/Aularios/{aulario_id}.json)

{
  "name": "Aulario Principal",
  "icon": "/static/logo-entreaulas.png"
}

Aulario Student Names (DATA/entreaulas/Centros/{centro_id}/Aularios/{aulario_id}/Alumnos/)

The Alumnos directory contains subdirectories for each student, where each student has:

  • A unique folder name (student identifier)
  • A photo.jpg file with the student's photo/pictogram

Example structure:

DATA/entreaulas/Centros/centro1/Aularios/aulario_abc123/Alumnos/
├── Juan/
│   └── photo.jpg
├── Maria/
│   └── photo.jpg
└── Pedro/
    └── photo.jpg

This structure is used by the "¿Quién soy?" (Who am I?) feature in Panel Diario, where students can identify themselves by selecting their photo.

Generating Password Hashes

To create password hashes for your users, use one of these methods:

Using Docker:

docker exec -it axia4-app php -r "echo password_hash('your_password', PASSWORD_DEFAULT);"

Using PHP CLI directly:

php -r "echo password_hash('your_password', PASSWORD_DEFAULT);"

Using a PHP script:

<?php
echo password_hash('your_password', PASSWORD_DEFAULT);
?>

Security Notes

  • NEVER commit the actual DATA directory with real user credentials to version control
  • The DATA directory should only exist on your production/development servers
  • Use strong, unique passwords for all accounts
  • Regularly backup the DATA directory
  • Set appropriate file permissions (755 for directories, 644 for files)