Skip to main content

Coding Standards — Quick Reference

Full rationale and decisions in the ADRs section. This page is the daily cheat sheet.

PHP

ItemConventionExample
StandardPSR-12-
Strict typesdeclare(strict_types=1) — always, first line after <?php-
NamespaceFacturaScripts\Plugins\<Plugin>\<Layer>FacturaScripts\Plugins\ObelioScheduling\Model\Appointment
ClassesPascalCase, EnglishAppointmentRoom, SurgerySession
MethodscamelCase, EnglishgetNextAppointment(), loadCompany()
ConstantsSCREAMING_SNAKE_CASESTATUS_IN_WAITING_ROOM
VariablescamelCase$patientName, $appointmentDate
CommentsEnglish, mandatoryPHPDoc on every class + method; inline // for non-obvious WHY

PHPDoc example

<?php

declare(strict_types=1);

namespace FacturaScripts\Plugins\ObelioScheduling\Model;

/**
* Represents a bookable appointment slot in the scheduling system.
*
* Each appointment belongs to one company (idEmpresa) and one clinic center (codalmacen).
* Status transitions: pending -> confirmed -> in_progress -> completed | cancelled | no_show.
*/
class Appointment extends ModelClass
{
/**
* Returns all pending appointments for the given clinic center on the given date.
*
* @param string $codalmacen FS warehouse code used as clinic center identifier
* @param string $date ISO 8601 date string (YYYY-MM-DD)
* @return self[]
*/
public function getPendingByCenter(string $codalmacen, string $date): array
{
// ...
}
}

Database

ItemConventionExample
Table namesobelio_<plugin>_<entity> — snake_case, English, singularobelio_scheduling_appointment
Column namessnake_case, Englishappointment_date, created_at
PK constraintpk_<table>pk_obelio_scheduling_appointment
FK constraintfk_<table>_<col>fk_obelio_scheduling_appointment_id_patient
Unique constraintuq_<table>_<col>uq_obelio_scheduling_appointment_code
Indexidx_<table>_<col>idx_obelio_scheduling_appointment_date
FS core joinsAccept FS naming as-isJOIN clientes ON clientes.codcliente = obelio_core_patient.id_cliente

Multi-tenant columns are mandatory on every obeliOmed table:

-- Every table must include these two columns
`idempresa` INT NOT NULL, -- FS company id (tenant separator)
`codalmacen` VARCHAR(4) NOT NULL -- FS warehouse = clinic center

Versioning (CalVer, ADR-028)

Format: AAMMDD.NN — year-month-day, dot, sequence within day.

260620.01 -> 2026-06-20, first build of the day
260620.02 -> 2026-06-20, second build
260621.01 -> 2026-06-21, first build

Git branches

develop -> integration branch (Javi merges here; do not push directly)
main -> production releases (Javi only)
NNN-description -> your feature branch; branch from develop

Examples: 016-surgery-room-model, 017-patient-guardian-fields

Merge authority

Only Javi closes PRs and merges to develop and main. Open your PR, write REVIEW.md, and stop. Never ask "can I merge this?" — Javi decides on merge days.

CSS / JS (ObelioTheme)

ItemConventionExample
Classesobelio-<entity>-<modifier> (kebab-case, prefix).obelio-appt-card, .obelio-clock
CSS variablesUse design tokens from ObelioThemevar(--obelio-color-primary)
JS modulesES modules, no globalsimport { formatDate } from '../utils/date.js'

Translations

All user-facing text goes through FacturaScripts translation keys:

// In templates
{{ i18n.trans('Appointment date') }}

// In PHP
$this->i18n->trans('Appointment date')

Translation files live in Translation/es_ES.json and Translation/en_US.json. Code is always English; translations handle language.