Introducción

Contigo Burrito es un proyecto que busca lograr el seguimiento en tiempo real del autobús (¡o autobuses!) de transporte interno de la UNMSM para facilitar la vida de los estudiantes. Además, incluye las siguientes características:

  • Notificaciones en la aplicación en forma de banners, ventanas emergentes y publicaciones.
  • Seguimiento en tiempo real de la ubicación del autobús, su estado y el nivel de batería del dispositivo.
  • Versionado de la aplicación y forzar actualizaciones en los clientes.
  • Información de paradas y rutas, incluyendo la distancia a la próxima parada.
  • Sesiones de usuario (para analíticas) y autenticación (para recursos protegidos).
  • Flags de características tanto para el servidor como para los clientes.
  • Integración para subir multimedia con Cloudinary.

El siguiente documento contiene toda la documentación técnica de alto nivel del proyecto, incluyendo la configuración de desarrollo, compilación, distribución, despliegue y otra información relevante.

Soporte y Contacto

No dudes en contactar al equipo si tienes preguntas o necesitas ayuda con el proyecto:

Resumen

A continuación, se presenta una descripción general del proyecto Contigo Burrito y cómo sus componentes interactúan entre sí. Para información más detallada, consulta la documentación específica de cada componente.

Componentes

El proyecto está dividido en cuatro componentes principales, cada uno con su propio repositorio:

Repositorio Descripción Tecnologías
burrito-app La app que los estudiantes usan para verificar el estado del autobús. Flutter, Riverpod, Google Maps
burrito-server Servidor REST API responsable. Rust, Rocket
burrito-driver Aplicación para el conductor del autobús que envía datos de ubicación. Flutter, Geolocator
burrito-dashboard Panel de administración para interactuar con el sistema. Vite, React

Ten en cuenta que estos son repositorios privados, por lo que es posible que necesites solicitar acceso a ellos.

Arquitectura

El proyecto sigue una arquitectura cliente-servidor, donde el servidor y la aplicación del conductor son responsables de gestionar los datos y los clientes se encargan de mostrarlos.

Arquitectura del proyecto

Burrito App

Status: production ready

La aplicación que los estudiantes usan para verificar el estado del autobús. Consume los registros de estado desde el burrito-server realizando consultas constantes al endpoint /status.

Está escrita en Flutter y se compila para las plataformas Android y web.

Consulta el directorio docs/ para más información.

Protocolo de actualización de la aplicación

El endpoint GET /pending_updates?version=1.0.0 devolverá una lista de versiones de la aplicación que son más recientes que la proporcionada en el parámetro de consulta.

// Ejemplo
{
  "must_update": true,
  "versions": [
    {
      "banner_url": "https://picsum.photos/id/866/400",
      "is_mandatory": false,
      "release_date": "2019-10-12T07:20:50.52Z",
      "release_notes": "Este es un resumen extenso de los cambios introducidos en la nueva versión, que puede incluir saltos de línea.\n\n- Característica 1\n- Característica 2",
      "semver": "1.1.0"
    }
  ]
}

El cliente NO DEBE permitir que el usuario continúe con la aplicación si alguna versión está marcada como is_mandatory. Si el cliente lo decide, puede mostrar un diálogo al usuario con el registro de cambios y la opción de actualizar, almacenando el reconocimiento en el almacenamiento local.

Un ejemplo del flujo de trabajo sería:

Acto 1: la primera vez

>el cliente solicita /pending_updates?version=1.0.0
>el servidor devuelve dos versiones pendientes, ninguna obligatoria
>se muestran dos opciones [Actualizar ahora] y [Más tarde] al usuario junto con los registros de cambios
>el usuario reconoce
>el cliente almacena la más alta como "latest_acknowledged_version" en el almacenamiento local
>el usuario decide no actualizar

Acto 2: al día siguiente, otra actualización

>el cliente solicita /pending_updates?version=1.0.0
>el servidor devuelve tres versiones, aún ninguna obligatoria
>como una de ellas es más reciente que "latest_acknowledged_version", el cliente muestra el diálogo
>el usuario reconoce
>el cliente almacena la más alta como "latest_acknowledged_version" en el almacenamiento local
>el usuario decide no actualizar

Acto 3: la actualización urgente

>el cliente solicita /pending_updates?version=1.0.0
>el servidor devuelve cuatro versiones, donde la última (2.0.0) es obligatoria
>el cliente combina los registros de cambios y los muestra al usuario junto con el botón [Actualizar ahora]
>el usuario reconoce y la única opción es actualizar
>el cliente almacena la más alta como "latest_acknowledged_version" en el almacenamiento local
>el usuario actualiza

Acto 4: la calma después de la tormenta

>el cliente solicita /pending_updates?version=2.0.0
>el servidor devuelve una lista vacía
>el cliente continúa con la aplicación

El ejemplo anterior describe nuestra implementación actual. Podríamos cambiarla en el futuro, pero la idea general seguirá siendo la misma.

Compliando el cliente móvil

Para obtener información más detallada, consulte Los documentos oficiales de flutter.

Tenga en cuenta que esta documentación es solo para Android. Aunque Flutter es compatible con iOS, aún no lo hemos probado para este proyecto.

Hay un action llamado "ios-compilation.yml" en el directorio .github/workflows que puedes consultar para más información.

Compliando el APK

Para crear APK para múltiples arquitecturas (ej., ARM, ARM64, x86), utilice el siguiente comando. Esto generará archivos APK separados para cada ABI (interfaz binaria de aplicación), lo que permitirá a los usuarios descargar el APK apropiado para la arquitectura de su dispositivo:

flutter build apk --split-per-abi

Los APK se guardarán en build/app/outputs/flutter-apk/ directorio. En esa carpeta se encuentran los APK generados, listos para probar o distribuir.

Crea un paquete de aplicaciones para su lanzamiento

Además de crear archivos APK, también es una buena práctica generar un paquete de aplicaciones (.aab) para lanzar la aplicación en Google Play Store. El paquete de aplicaciones contiene todo lo necesario para la distribución y Google Play optimizará la aplicación para diferentes configuraciones de dispositivos de manera automática.

Para crear una versión de lanzamiento de la App Bundle, utilice el siguiente comando:

flutter build appbundle --release

Una vez que se complete la compilación, el archivo .aab estará disponible en build/app/outputs/bundle/release/ Puedes cargar este archivo en Google Play Console o en cualquier otra tienda de aplicaciones que admita App Bundles.

Publicando tu aplicación en Google Play Store

Hay algunas cosas que debes verificar antes de enviar la aplicación a Google Play Store (o cualquier otra tienda).

  1. Asegúrate de que el servidor esté en funcionamiento

    Antes de enviar tu aplicación a una tienda, es importante verificar que el servidor del que depende esté activo, funcional y listo para manejar solicitudes. Muchas tiendas requieren que las aplicaciones proporcionen funcionalidad real y no solo marcadores de posición; por lo tanto, podrían revisar las respuestas de la aplicación para confirmar que funciona como se espera.

    Si aún no tienes un controlador enviando los datos, consulta la sección Usando rutas simuladas.

    • Verifica las respuestas esperadas: Prueba que la API proporcione correctamente la ubicación del burrito.
    • Monitorea el tiempo de actividad: Muchas tiendas pueden revisar periódicamente la funcionalidad de tu aplicación durante el proceso de revisión. Considera usar un servicio de monitoreo para recibir alertas si tu servidor deja de estar disponible inesperadamente.
  2. Asegúrate de que la aplicación esté usando la API correcta y no localhost

    Revisa el archivo lib/services/dio_client.dart para asegurarte de que la aplicación esté conectada al punto final correcto de la API. El baseUrl debe estar configurado en la URL de tu API en vivo, no en localhost:

    baseUrl: 'https://yourAPI.com',
    

    Ahora estás listo para publicar la aplicación en la tienda de tu elección.

Desplegando la aplicación en la web usando Cloudflare Pages

El despliegue en Cloudflare Pages ya está configurado como un flujo de trabajo de GitHub que se activa con cada push a la rama main.

Para más detalles, consulta el archivo .github/workflows/deploy.yml.

Usando un dominio personalizado

Por defecto, las páginas de Cloudflare se despliegan en el dominio *.pages.dev. Para usar un dominio personalizado, sigue las instrucciones proporcionadas por Cloudflare en el panel de Pages.

Construyendo manualmente la aplicación web

Construye la aplicación para web con:

flutter build web -t lib/main.dart

Burrito server

Status: Production ready

La API de Burrito sirve todos los datos del servidor (versiones de la app, notificaciones, flags, sesiones) y actúa como puente de comunicación entre la aplicación del conductor del autobús y la aplicación del usuario.

El servidor está escrito en Rust y utiliza el framework web Rocket.

Documentación de la API

Para la documentación de la API seguimos un enfoque de código primero. La documentación se genera a partir del código fuente utilizando utoipa, que genera un archivo de especificación OpenAPI 3.1 en tiempo de compilación.

Esta especificación es luego consumida y renderizada por Scalar. El resultado final del documento es servido por la propia API y puede ser accedido públicamente en /docs.

Documentación de la API

Puedes consultar la documentación online en https://api.contigosanmarcos.com/docs.

Documentar los endpoints de la API

Para documentar una ruta se utiliza la macro path del atributo de utoipa. Esta macro toma varios argumentos para documentar el endpoint. Los más importantes se muestran en este ejemplo de PATCH /flag/id:

#[utoipa::path(
    tag = docs::tags::APP_VERSIONS_TAG,
    description = "Edits an existing app version. All columns are optional.",
    request_body(content = schemas::AppVersionPatchPayload),
    responses(
        (status = 200, body = schemas::AppVersion),
        (status = 400),
        (status = 401),
    ),
    security(("staff_user_auth" = [])),
)]
#[patch("/<id>", format = "json", data = "<payload>")]
async fn patch_app_version(
    id: i32,
    _user: StaffUser,
    payload: JsonResult<'_, schemas::AppVersionPatchPayload>,
    state: &State<AppState>,
) -> ApiResponse<Json<schemas::AppVersion>> {
    // ...
}

Consulta la documentación de utoipa::path para más detalles.

Gestión de la base de datos

Nuestro driver de base de datos, sqlx, resuelve la mayoría de los problemas relacionados con la gestión de bases de datos.

Si no estás familiarizado con sqlx, este video es un buen punto de partida.

Primero, asegúrate de tener instalado el cliente sqlx.

cargo install sqlx-cli

Creación de migraciones de base de datos

Las migraciones de base de datos se encuentran en el directorio migrations/. Crea una nueva migración para cada cambio que quieras hacer en el esquema de la base de datos.

Por ejemplo, si necesitas añadir una nueva columna profile_image a la tabla users, puedes crear una migración con el siguiente comando:

sqlx migrate add -rs add_users_profile_image

Esto generará dos archivos en el directorio migrations/:

  • migrations/000x_add_users_profile_image.up.sql
  • migrations/000x_add_users_profile_image.down.sql

Edita el archivo up.sql para añadir la nueva columna:

ALTER TABLE users
ADD COLUMN profile_image TEXT;

Luego, edita el archivo down.sql para revertir la migración:

ALTER TABLE users
DROP COLUMN profile_image;

La idea es que el archivo down.sql revierta los cambios realizados en up.sql, dejando la base de datos exactamente en el mismo estado que antes de aplicar la migración.

Después de eso, puedes ejecutar o revertir las migraciones con:

sqlx migrate run
sqlx migrate revert

O reiniciar completamente la base de datos con:

sqlx database reset --force

Una vez que hagas commit a tus migraciones, no necesitas hacer nada más para aplicarlas en producción, ya que siempre se verifican y ejecutan automáticamente al iniciar el servidor.

Compilación de consultas en "offline mode"

La idea de sqlx es que las consultas SQL planas se verifican en tiempo de compilación y se traducen a tipos primitivos de Rust. Sin embargo, esto requiere una conexión a la base de datos para verificar las consultas.

Por esta razón existe la compilación en "offline mode". Lo único que necesitas tener en cuenta aquí es que cada vez que hagas un commit ejecutes lo siguiente:

cargo sqlx prepare

Las consultas compiladas se guardarán en el directorio .sqlx/ y deben incluirse en el repositorio. Para más detalles, consulta la documentación sobre el offline mode de sqlx.

Variables de entorno

El archivo .env.example muestra una lista actualizada de todas las variables de entorno que utiliza el servidor. Comienza copiando el archivo de ejemplo a .env:

cp .env.example .env

Todas las variables definidas aquí se corresponden directamente con una variable global estática de Rust definida en el archivo src/env.rs, por lo que puedes utilizarlas en tu código de esta forma:

fn main() {
  let port: u16 = *crate::env::PORT;
  println!("Server running on port {}", port);
}

Ejemplos

Un archivo .env listo para usar en desarrollo se vería así:

IS_MOCKED=false

ROOT_SECRET="root_secret"
AUTH_DRIVER_PASSPHRASE="driver_pass"
AUTH_WHATSAPP_ACCESS_TOKEN="none"

POSTGRES_PASSWORD="dontship"
DATABASE_URL="postgres://admin:${POSTGRES_PASSWORD}@localhost/burrito_app"

CLOUDINARY_API_KEY="438453545385499"
CLOUDINARY_CLOUD_NAME="sea1jk51z"
CLOUDINARY_API_SECRET="mJd3bbkWa5mPVKuNBgCLxjY5FSM"

Un archivo .env para producción se vería así:

IS_MOCKED=false

ROOT_SECRET="burrito_prod_6z3g5z2t5z2g5Z2t5g3X"
AUTH_DRIVER_PASSPHRASE="burrito_prod_K4ZVf3g1zS6x2TcjdyDztkbvh4CQHrF6"

# Leave it empty ("") if you don't plan to use the WhatsApp API
AUTH_WHATSAPP_ACCESS_TOKEN="EAAjnKUIiz4ABOzMXloXZCVvifdfFHJGHvlFFWENYE1zFyfg0Ikh0ExDWnkTO1q9CllVXQgKZBvrD3XUucr6Bxk9RIZAITIvzAxWZB2KbZApppIbSwsk2Ozu54emMqb6QlpBRrUM7WAvrRWa8ZApj5p4ZBY9ROIcHKI6CXujoAg1Q1jnv7pJCnVeLDUblAND97J7Q5LliGPZCdiZAHKI16boABdPHo6p2mm8lFCIYZD"

POSTGRES_PASSWORD="MM3ky4RhgpFSbfoXmUh42r0REZzCYXyu"
DATABASE_URL="postgres://admin:${POSTGRES_PASSWORD}@burrito_db/burrito_app"

CLOUDINARY_API_KEY="438453545385499"
CLOUDINARY_CLOUD_NAME="sea1jk51z"
CLOUDINARY_API_SECRET="mJd3bbkWa5mPVKuNBgCLxjY5FSM"
Los archivos anteriores no contienen credenciales válidas y solo demuestran cómo se vería un archivo .env real en ambos casos.

Subiendo las variables de producción a GitHub

Si estás utilizando el pipeline de GitHub CI, asegúrate de configurar las variables en la configuración del repositorio de GitHub. Puedes encontrarlas en la pestaña Settings, bajo Secrets and Variables > Actions.

Descripción de los secretos:

  • ENV_FILE: Una copia exacta del contenido del archivo .env de producción.
  • SSH_KEY: La clave SSH privada que se utilizará para conectarse al servidor. Esto asume que la clave pública ya está en el archivo authorized_keys del servidor.

Descripción de las variables:

  • SSH_HOST: El host donde se ejecuta el servidor.
  • SSH_USERNAME: El usuario que se utilizará para conectarse al servidor.
  • SSH_REPO_PATH: La ruta donde ya está clonado el repositorio en el servidor.

Creando un nuevo usuario de la aplicación

Actualmente no hay forma de crear un nuevo usuario desde la API, necesitarás acceso directo a la base de datos al esquema internal.

Todas las funciones y procedimientos mostrados en este capítulo fueron definidos en la migración "migrations/0006_users.up.sql"

Recordar que la aplicación no depende de usuarios para funcionar. Actualmente los usuarios son solo usados para propósitos administrativos.

Existe un procedure llamado internal.create_user específicamente para este propósito.

\df internal.create_user

Su definición (actual) es la siguiente:

CREATE OR REPLACE PROCEDURE internal.create_user(
    p_username citext,
    p_display_name varchar(255),
    p_password text,
    p_is_active boolean,
    p_is_staff boolean
)

Por ejemplo, en el contenedor de desarrollo local harías lo siguiente:

$ psql 'postgres://admin:dontship@localhost/burrito_app'

burrito_app=# CALL internal.create_user('username', 'Display Name', 'pass123', true, true);

Cambiando la contraseña del usuario

Existe un procedure llamado internal.change_password para cambiar la contraseña de un usuario.

\df internal.change_password

Por ejemplo, para cambiar la contraseña del usuario creado en el paso anterior:

$ psql 'postgres://admin:dontship@localhost/burrito_app'

burrito_app=# CALL internal.change_password('username', 'newpass123');

Verifying the user

De manera similar, existe una function llamada internal.get_auth_user para consultar un usuario por su nombre de usuario y contraseña.

\df internal.get_auth_user

Por ejemplo, para verificar el usuario creado en el paso anterior:

$ psql 'postgres://admin:dontship@localhost/burrito_app'

burrito_app=# SELECT * FROM internal.get_auth_user('username', 'pass123');

Esta función se utiliza internamente en las rutas de la aplicación que requieren autenticación.

¿Por qué hacerlo de esta forma?

De esta forma, Postgres es responsable de hashear la contraseña y almacenarla de forma segura. El servidor no es responsable de hashear ni verificar nada.

Si se desean exponer endpoints de registro/login de usuarios, se tendrían que llamar estas funciones desde el backend. Puedes ver un ejemplo de esto en src/features/auth/handlers/login.rs.

Usando una ruta de autobús simulada

¿No hay conductor del burrito? ¡No hay problema! Puedes iniciar la aplicación con una ruta simulada configurando IS_MOCKED=true en el archivo .env.

La ruta simulada se leerá desde static/mocks/*.json. Consulta mock.rs para más detalles.

Una vez que configures IS_MOCKED=true, puedes iniciar el servidor como de costumbre. La simulación funciona enviando solicitudes POST /driver a nosotros mismos, iterando sobre los registros de la ruta simulada.

¿Para qué se podría utilizar esta simulación de ruta?

Esta función es útil para mostrar la aplicación sin tener que depender de un conductor de autobús real, o para fines de prueba y NO DEBE usarse en producción.

Despliegue del servidor

El repositorio del servidor contiene todos los componentes necesarios para configurar fácilmente la integración y el despliegue continuos utilizando solo un VPS y GitHub Actions.

Configuración del VPS

La configuración inicial del VPS debería ser sencilla. Asumiendo que estás en un servidor Debian bookworm con privilegios de root:

Dependencias

Autenticación SSH

  • Crea un nuevo usuario que utilizarás para desplegar el servidor. Nómbralo como desees.

    # adduser burrito
    # usermod -aG sudo burrito
    
  • Genera un par de claves SSH (o sube una existente) para el nuevo usuario

    # su burrito
    $ ssh-keygen -t ed25519 -C "admin@burrito" -f ~/.ssh/id_ed25519
    
  • Copia la clave pública en el archivo authorized_keys del servidor

    $ cat ~/.ssh/id_ed25519.pub >> ~/.ssh/authorized_keys
    
  • Prueba la conexión al servidor

    $ ssh burrito@localhost
    

Configuración del repositorio

  • Ahora clona el repositorio del servidor

    $ sudo mkdir -p /opt/burrito/repo
    $ git clone git@github.com:burrito/server.git /opt/burrito/repo
    
  • Si estás utilizando el pipeline de CI de GitHub, configura las variables en los ajustes del repositorio de GitHub y estarás listo. Consulta Subiendo las variables de producción a GitHub.

    De lo contrario, rellena manualmente un archivo .env.

Certificados TLS

  • Lee cuidadosamente el archivo docker/prod/nginx/nginx.conf, que contiene la configuración del servidor y las rutas a los certificados TLS.

  • Sigue las instrucciones de tu CA (por ejemplo, Let's Encrypt) para generar los certificados. Probablemente necesitarás crear un nuevo registro DNS apuntando a la dirección IP del servidor o un registro TXT de desafío.

  • Genera un par de certificados TLS usando Let's Encrypt u otra CA. Por ejemplo, utilizando Certbot:

    # certbot certonly --standalone -d api.contigosanmarcos.com
    
  • Cualquiera que sea el dominio que hayas utilizado, asegúrate de actualizar la variable DOMAIN_NAME en el archivo docker-compose.prod.yml.

  • Si deseas guardar los certificados en una ruta personalizada (como /opt/burrito/certs), asegúrate de actualizar el archivo docker/prod/nginx/nginx.conf.

  • Usa un verificador de propagación DNS para comprobar si tu dominio apunta correctamente a la dirección IP del servidor.

Iniciar el contenedor

Si estás utilizando GH Actions, no necesitas correr estos comandos. En su lugar, inicia el action de deploy.

  • Puedes levantar el servidor utilizando Docker Compose

    $ cd /opt/burrito/repo
    $ docker compose -f docker-compose.prod.yml up --build
    
  • Cada vez que desees actualizar el servidor, simplemente descarga los cambios y reinicia el servidor.

    $ cd /opt/burrito/repo
    $ git pull origin main
    $ docker compose -f docker-compose.prod.yml up --build
    

    Aunque se recomienda usar el pipeline de GitHub Actions en lugar de lanzar comandos manuales.

Production checks

Antes de desplegar en producción, asegúrate de cumplir con las siguientes verificaciones:

Bus Driver Application

Estado: Listo para producción

Una aplicación Flutter que envía la ubicación, el nivel de batería y el estado del transporte en autobús de la UNMSM a intervalos regulares para ser consumidos por los clientes de la aplicación.

La aplicación del conductor es responsable de recopilar información del dispositivo, la ubicación y el estado del servicio informado por el conductor, todo en intervalos regulares para ser consumido por las aplicaciones clientes.

La aplicación debe ser simple y consumir la menor cantidad de batería posible.

Escrita con React y Vite.

Compilación de la aplicación del conductor del burrito

Para información más detallada, consulta la documentación oficial de Flutter.

Ten en cuenta que esta documentación es solo para Android. Aunque Flutter soporta completamente iOS, aún no se ha probado con este proyecto.

Hay un flujo de trabajo funcional llamado ios-compilation.yml en el directorio .github/workflows que puedes consultar.

Compilación del APK

Para construir APKs para múltiples arquitecturas (por ejemplo, ARM, ARM64, x86), utiliza el siguiente comando. Esto generará archivos APK separados para cada ABI (Interfaz Binaria de Aplicación), permitiendo a los usuarios descargar el APK adecuado para la arquitectura de su dispositivo:

flutter build apk --split-per-abi

Los APKs se guardarán en el directorio build/app/outputs/flutter-apk/. Puedes encontrar los APKs generados en esa carpeta, listos para pruebas o distribución.

Construir un paquete de la aplicación para la liberación

Además de construir los APKs, también es una buena práctica generar un Paquete de la Aplicación (.aab) para liberar la aplicación en la Google Play Store. El Paquete de la Aplicación contiene todo lo necesario para la distribución, y Google Play optimizará automáticamente la aplicación para diferentes configuraciones de dispositivos.

Para construir una versión de liberación del Paquete de la Aplicación, utiliza el siguiente comando:

flutter build appbundle --release

Una vez que la construcción esté completa, el archivo .aab estará disponible en el directorio build/app/outputs/bundle/release/. Puedes subir este archivo a la Google Play Console o cualquier otra tienda de aplicaciones que soporte Paquetes de Aplicación.

Cómo funciona la aplicación del conductor

Servicio de ubicación en segundo plano

Esta aplicación utiliza un servicio de ubicación en segundo plano para realizar un seguimiento continuo de la posición del autobús, incluso cuando la aplicación está en segundo plano o cuando la pantalla está apagada. Este servicio se ejecuta de forma silenciosa, asegurando que la ubicación del autobús se envíe al servidor sin necesidad de que el usuario tenga la aplicación abierta.

Enviar la ubicación a la API

La aplicación envía periódicamente las coordenadas GPS del autobús a un servidor. Esto se hace a través de un endpoint de la API, que la aplicación consulta en segundo plano.

Enviar la batería del teléfono

Al mismo tiempo que la aplicación envía una coordenada al servidor, también envía el estado de la batería del teléfono.

Botón simple para iniciar o finalizar el servicio

La aplicación incluye un botón simple que permite a los usuarios iniciar o detener el servicio de ubicación en segundo plano. Cuando el servicio está iniciado, la aplicación comenzará a enviar actualizaciones de ubicación al servidor. Cuando se detiene, la aplicación dejará de hacer un seguimiento o enviar datos de ubicación, lo que finaliza el seguimiento de ubicación para el autobús.

Cambiar el estado del burrito

La aplicación permite cambiar el estado del autobús, denominado "burrito," entre diferentes estados operacionales. Estos estados representan la condición actual del autobús:

  • En ruta ("In route"): El autobús está en camino a su destino.
  • Fuera de servicio ("Out of service"): El autobús no está operativo o no está disponible.
  • En descanso ("At rest"): El autobús está temporalmente detenido o inactivo.
  • Accidente ("Accident"): El autobús ha estado involucrado en un accidente.
  • Error ("Error"): Hay un problema con el autobús o con los datos de su ubicación.
  • Cargando ("Loading"): El autobús está siendo cargado o está en preparación.
  • Desconocido ("Unknown"): El estado del autobús no es conocido.

Burrito Admin Dashboard

Estado: listo para producción, pero parcialmente terminado

Dashboard para usuarios del personal/admin para gestionar recursos protegidos.

Características

  • Notificaciones: Añadir y eliminar banners de la aplicación. Actualmente no se soportan popups ni publicaciones.
  • Batería: Vista rápida de la batería restante de la aplicación.

Escrito con React y Vite.

Despliegue del Dashboard

El dashboard es una simple aplicación de React Vite, por lo que debería ser fácil de desplegar.

Cloudflare Pages

Con la ayuda de GitHub Actions, el despliegue está mayormente automatizado. Asegúrate de tener lo siguiente configurado:

  1. Configurar GitHub Secrets: Añade tu CLOUDFLARE_API_TOKEN y CLOUDFLARE_ACCOUNT_ID en los secretos de tu repositorio de GitHub.

  2. Verificar el flujo de trabajo de GitHub Actions: Asegúrate de que el archivo de flujo de trabajo esté configurado correctamente para construir y desplegar la aplicación. La configuración está en .github/workflows/cloudflare-deploy.yml

Desplegado en https://burrito-dashboard.pages.dev/

Notas adicionales

Antes de desplegar el dashboard, asegúrate de:

  • Verificar que se haya creado una cuenta de usuario con los permisos adecuados en la base de datos. Esto permite el control de acceso y asegura que cada usuario pueda interactuar con el dashboard como se espera.

  • Verificar que el servidor backend esté funcionando y sea accesible. El dashboard depende del servidor para la recuperación de datos y actualizaciones, por lo que una conexión en vivo es esencial para su funcionalidad completa.