ORVIAN provides a complete student lifecycle: individual creation via form, bulk Excel import from SIGERD, automatic QR code generation, optional biometric facial enrollment, and section assignment through the Enrollment Hub. Every student record is automatically backed by a system user account the moment the record is created.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Elian-D/ORVIAN/llms.txt
Use this file to discover all available pages before exploring further.
Student Index
Component:StudentIndex (App\Livewire\App\Academic\Students\StudentIndex)Route:
GET /app/academic/studentsPermission:
students.view
The student index is a paginated data table built on ORVIAN’s DataTable base class. It supports the following URL-bound filters:
| Filter | Type | Description |
|---|---|---|
search | Text | Full-name or RNC free-text search |
school_section_id | Select | Filter by a specific section |
status | Select | active or inactive |
gender | Select | M (Masculino) or F (Femenino) |
has_photo | Toggle | Show only students with a profile photo |
has_face_encoding | Toggle | Show only students enrolled in biometrics |
@teleport('body')) showing the student’s photo, section, and key stats without navigating away. The index also surfaces a student quota widget that compares active student count against the school plan’s limit_students.
Inline actions from the index include:
- Withdraw — marks the student inactive with a withdrawal date and optional reason.
- Reactivate — re-enrolls the student; blocked if the school plan quota is already at its limit.
- Show QR — opens a modal displaying the student’s QR code.
Creating a Student
Component:StudentForm (App\Livewire\App\Academic\Students\StudentForm)Route:
GET /app/academic/students/createPermission:
students.create
The same StudentForm component handles both creation and editing (at /app/academic/students/{student}/edit, requiring students.edit).
Required Fields
| Field | Validation | Notes |
|---|---|---|
first_name | required, max 100 | — |
last_name | required, max 100 | — |
school_section_id | required, must exist | Section must exist in school_sections |
gender | required, M or F | — |
rnc | required, 11–15 chars | Must be unique per school |
Optional Fields
| Field | Validation | Notes |
|---|---|---|
date_of_birth | nullable, date | — |
address | nullable | Home address |
photo | nullable, image, max 2 MB | Triggers face encoding on save |
tutor_name | nullable, max 120 | Guardian name |
tutor_phone | nullable, E.164 regex | Must match +[1-9]\d{7,14} for WhatsApp |
blood_type | nullable | — |
allergies | nullable | — |
medical_notes | nullable | — |
is_active | boolean | Defaults to true |
Email Auto-Calculation
The student’s system email is automatically calculated from the RNC and is read-only in the form. As the user types the RNC, theupdatedRnc() hook fires:
StudentObserver@created at creation time and cannot be changed through the form.
If a photo is uploaded, StudentService::updatePhoto() stores it and then FaceEncodingManager::enrollStudent() is called outside the database transaction to avoid blocking the save if the facial recognition microservice is unavailable.
Student accounts start with
inactive status. The Director must manually activate each account before the student can log in to ORVIAN.Bulk Import from SIGERD
Component:StudentImportWizard (App\Livewire\App\Academic\Students\StudentImportWizard)Route:
GET /app/academic/students/importPermission:
students.import
The import wizard processes Excel (.xlsx, .xls) and CSV files exported from the Dominican Republic’s SIGERD system, up to 10 MB. It runs in three stages:
Step 1 — Upload File
The user selects the file. On upload,RawStudentImport reads the first row to extract the column headers. The headers are stored in $headers and the wizard advances to Step 2.
Step 2 — Column Mapping & Import
A visual mapping interface presents each column header from the source file alongside a dropdown of ORVIAN’s internal field names. The wizard auto-detects common SIGERD column names using keyword matching:| ORVIAN Field | Detected From (keywords) |
|---|---|
first_name | ”nombre”, “primer” |
last_name | ”apellido” |
rnc | ”cedula”, “cédula”, “rnc” |
gender | ”sexo”, “genero”, “género”, “sex” |
date_of_birth | ”nacimiento”, “birth” |
tutor_name | ”tutor”, “responsable”, “encargado” |
tutor_phone | ”tutor” + “tel”/“phone”/“celular”/“whatsapp” |
sigerd_section | ”seccion”, “sección”, “grado”, “curso” |
first_name and last_name must be mapped before proceeding. A default section can be selected as a fallback for rows where the section cannot be resolved.
Clicking Start Import dispatches the ProcessStudentImport Laravel Job. The file is stored at imports/students/{schoolId}/import_{timestamp}.{ext} and a StudentImportRecord is created with status pending. The wizard advances to Step 3.
Step 3 — Monitor Progress & Download Errors
TheimportRecord computed property polls the StudentImportRecord for status updates. The progress bar reflects the job’s advancement through the uploaded rows.
After completion, any rows that failed processing are available for download as a CSV via downloadErrors(). The error file includes all original row data plus an Error column describing the failure reason.
SIGERD-Specific Features
tutor_nameandtutor_phone: Extracted from SIGERD columns and stored on the student record for WhatsApp alerts.- Phone normalization:
tutor_phonevalues are normalized to E.164 format during import. - Section resolution uses four levels of tolerance:
- Exact match — the SIGERD section string matches a
SchoolSection.full_labelexactly. - Fuzzy match — partial or case-insensitive match against existing sections.
- Default section — the section selected by the user in the mapping step.
- Sala de Espera (Waiting Room) — if no match is found,
school_section_idis set tonullandmetadata.sigerd_sectionstores the original SIGERD value for later resolution in the Enrollment Hub.
- Exact match — the SIGERD section string matches a
Enrollment Hub (Sala de Espera)
Component:EnrollmentHub (App\Livewire\App\Academic\EnrollmentHub)Route:
GET /app/academic/enrollment-hubPermission:
students.edit
The Enrollment Hub is a double-panel interface for assigning students who are in the waiting room (school_section_id = null) to their actual sections. It is the primary workflow after a SIGERD bulk import where section resolution was incomplete.
Left panel — Unassigned Students:
- Paginated list of active students with
school_section_id = null. - Searchable by name or RNC.
- Filterable by
metadata.sigerd_section— a quick-filter dropdown lists all distinct SIGERD section values present in the waiting room along with student counts. selectBySigerdSection(string $sigerdSection)selects all waiting-room students who originally came from a given SIGERD section, enabling batch assignment in a single click.
- Active sections grouped by level, filterable by shift.
- Clicking a section sets it as
targetSectionId.
executeAssignment(), which performs a single bulk UPDATE query using JSON_SET to move students and stamp their metadata with the assignment timestamp and target section ID.
QR Code Wristbands
QR codes are generated automatically byStudentObserver@creating before the student record is saved. No manual action is required.
Two routes support printing:
| Route | Permission |
|---|---|
GET /app/academic/students/print-manager | students.import |
GET /app/academic/students/print-qr-sheet | students.import |
StudentPrintManager) provides a filterable list of students with individual QR preview and selection for batch printing. The Print QR Sheet route (StudentPrintController::printQrSheet) renders a printable layout optimized for wristband or label paper.
Biometric Enrollment
Component:BiometricKiosk (App\Livewire\App\Academic\BiometricKiosk)Route:
GET /app/academic/biometric-kioskPermission:
students.edit
The Biometric Kiosk is a dedicated interface for enrolling students in facial recognition. It shows a grid of student cards with real-time enrollment status.
Filtering:
- Filter by section (
selectedSectionId). - Filter by biometric status:
''(all),'with'(enrolled),'without'(pending). - Free-text phonetic name search.
- Click Enroll on a student card →
openEnrollModal(studentId)dispatchesopen-biometric-modalto Alpine.js. - The modal activates the device camera.
facingModeis supported: rear-facing camera on mobile, front-facing on desktop. - A live SVG overlay provides a framing guide. Frames are processed with mirror correction to account for selfie-mode inversion.
- The captured photo is uploaded as a
UploadedFilevia Livewire’sWithFileUploadsand passed toFaceEncodingManager::enrollStudent(). - On success, the 128-float face encoding is stored in
students.face_encoding. The kiosk displays a success result and auto-closes the modal after 1.5 seconds. - On failure (no face detected, poor lighting), an error message prompts a retry.
- Camera release: Closing the modal by any means (Escape key, overlay click, or close button) dispatches
close-biometric-modal, which triggers Alpine.js to stop thegetUserMediastream and release the hardware.
Student accounts are created with
inactive status by StudentObserver@created. The Director must navigate to the user management screen and manually activate each account before the student can log in.