← Blog

Un portal para residentes de una asociación de propietarios — en PHP y SQLite sencillos

DEENESRUUK

No todos los proyectos necesitan un framework de JavaScript y una base de datos gestionada. Este —un armario web privado para los miembros de una asociación de propietarios de apartamentos de Kyiv (ОСББ)— es deliberadamente aburrido por dentro: PHP 8.3 hablando con un archivo SQLite, servido por nginx + PHP-FPM. Sin framework, sin paso de compilación, sin MySQL. Se ejecuta en osbb-wh.pp.ua.

La restricción interesante no fue la pila tecnológica, sino los usuarios. Los residentes no son desarrolladores; muchos no son jóvenes. Todo tenía que ser obvio, rápido en un teléfono barato y en su idioma.

Qué hace

  • Acceso cerrado — los residentes inician sesión con sus apartamentos, con activación por correo electrónico para cuentas nuevas.
  • Anuncios, documentos y actas de reuniones — la junta publica, los residentes leen, en ucraniano y ruso.
  • Un registro de vehículos con OCR. Los residentes añaden sus coches con una foto, y Tesseract lee la matrícula de la imagen (con preprocesamiento de ImageMagick) para que el número se capture sin tecleo manual.
  • Tickets a la junta — un hilo de soporte simple entre un residente y la administración.
  • Encuestas con una estricta regla de un apartamento, un voto.
  • Correo interno entre residentes (con eliminación suave).
  • Widgets en vivo — clima y calidad del aire de Kyiv, obtenidos del lado del servidor y cacheados para que el cliente nunca llame a un tercero directamente.
  • Herramientas de administración — CRUD de residentes, gestión de roles y moderación de contenido.

Vigilando el edificio, con seguridad

Una de las partes más interesantes es la transmisión de cámaras. Los residentes pueden ver las cámaras de entrada y del patio del edificio desde su cuenta, pero las cámaras en sí nunca están expuestas a internet.

Las cámaras hablan RTSP, que los navegadores no pueden reproducir, y viven en la red privada. Así que un servidor multimedia MediaMTX se sitúa delante: ingiere las transmisiones RTSP y las republica como flujos de baja latencia aptos para navegadores (HLS / WebRTC). El portal incrusta estos detrás del inicio de sesión del residente; el navegador solo habla con mi servidor, nunca con una cámara.

Esa única indirección lo compra todo. Las cámaras mantienen su firmware de fábrica fuera de internet público (donde sería encontrado y forzado en cuestión de horas), la pesada tarea de transcodificación/reempaquetado es trabajo de MediaMTX en lugar de PHP, el acceso está ligado al mismo sistema de cuentas que todo lo demás, y hay un solo lugar para revocarlo. Se reutiliza un patrón similar de proxy del lado del servidor + caché para los widgets de clima y calidad del aire en vivo de Kyiv, por lo que el cliente tampoco llama a un tercero directamente.

Por qué sin framework

Para una aplicación de este tamaño, un framework habría añadido más conceptos de los que eliminó. PHP puro + PDO sobre SQLite significa: un archivo es toda la base de datos, las copias de seguridad son una copia, el despliegue es git pull, y no hay árbol de dependencias que mantener parcheado. La interfaz de usuario se basa en Bootstrap con un aspecto limpio estilo portal gubernamental (en el espíritu de "Diia" de Ucrania), por lo que resulta familiar y confiable para las personas que usan servicios electrónicos estatales.

La lección

Las partes más difíciles de una herramienta interna "simple" nunca son las elecciones del framework; son las humanas: contenido bilingüe, formularios accesibles, el paso OCR que elimina una tarea tediosa y reglas de acceso que una junta no técnica puede administrar realmente. Pequeño, robusto y legible supera a lo ingenioso aquí.

Transparencia: la mayoría de las entradas se redactan con ayuda de IA, y las versiones que no están en inglés se traducen automáticamente con un LLM local y luego se revisan. ¿Has visto un error? Avísame, por favor.