# 🚧 Carrramba! Encore rrraté! 🚧 Resident of the Ile-de-France, - Tired of missing your bus/train/metro ? - Tired of having to walk to know where your bus/train/metro will stop ? - Are you looking to display its next passages in the same way as Ile De France Mobilité ? **Visit [carrramba.adrien.run](https://carrramba.adrien.run/)** [![Presentation](medias/presentation.png)](medias/presentation.mp4) # Technical stack The following figure list the building blocks (docker images) and their interactions to provide the service: ```plantuml @startuml !include !define ICONURL https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/v2.4.0 !includeurl ICONURL/common.puml !includeurl ICONURL/font-awesome-5/users.puml !includeurl ICONURL/devicons2/redis.puml !includeurl ICONURL/devicons2/sqlalchemy.puml !includeurl ICONURL/devicons2/postgresql.puml title Carrramba-encore-rate - Back-end LAYOUT_WITH_LEGEND() Person(user, "User", "The service user", $sprite="users") System_Boundary(cb1, "carrramba-encore-rate") { Container(app, "SPA", "SolidJS", "The graphical interface used by users to consume services provided") Container(api, "carrramba-encore-rate-api", "FastAPI / Pydantic 2 / SQLAlchemy 2", "Provides the functionalities serving API endpoints", $sprite="sqlalchemy") ContainerDb(db, "Postgres", "PostgreSQL database", "Stores stops/stop areas/lines/shapes and associations information.", $sprite="postgresql") ContainerDb(cache, "In-Memory cache", "Redis", "Store previously computed results (stop, line, destination, next passages, shapes).", $sprite="redis") Container(db_updater, "db-updater", "Sync the service static data with the IDFM ones") } System_Boundary(idfm, "IDFM") { Container_Ext(static_, "Static data") Container_Ext(dynamic_, "Dynamic data") } Rel(user, app, "Uses") Rel(app, api, "Uses", "JSON/HTTPS") Rel_R(api, db, "Reads from", "sync, PSQL") Rel_L(api, cache, "Reads from and writes to", "sync, REdis Serialization Protocol") Rel(api, dynamic_, "Get next passages", "JSON/HTTPS") Rel_L(db_updater, db, "Writes to", "sync, PSQL") Rel(db_updater, static_, "Get stops, lines andshapes") @enduml ``` ## Back-end Conventional but efficient: - [FastAPI](https://fastapi.tiangolo.com/): _FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.8+ based on standard Python type hints._ - [Pydantic 2](https://docs.pydantic.dev/latest/): _Pydantic is the most widely used data validation library for Python._ - [Sqlalchemy 2](https://www.sqlalchemy.org/): _SQLAlchemy is the Python SQL toolkit and Object Relational Mapper that gives application developers the full power and flexibility of SQL._ The [Msgspec](https://github.com/jcrist/msgspec) library is used to serialize JSON objects collected from IDFM API endpoints, this library being faster than Pydantic. ## Front-end The component is developed using the [SolidJS](https://www.solidjs.com/) library. It brings the following interesting specificities: - Share with React the same programmatic structures and support for component. - Fine-grained reactivity architecture: no virtual DOM used to update the components, the browser DOM is directly updated by SolidJS. The front-end tries to be as close as possible to the design defined by the IDFM for the displays deployed by the transport operators in Ile-de-France. These specifications are public and available here: [PRIM-IDFM](https://prim.iledefrance-mobilites.fr/en/chartes-et-prescriptions). # TODO ## Features - [ ] Integration with [Matrix.org](https://matrix.org/ecosystem/integrations/) ecosystem: make the app able to send message to a room when a bus/train/metro will arriving in X minutes. - [ ] Add the capability for the users to pin his/her favorite stops. - [ ] Add the address to the stop location. ## Front-end - [ ] Add unit tests. - [ ] Make the StopNameInput component liquid. - [ ] Liquid to responsive Design. ## Back-end - [ ] Add unit tests. - [ ] Use [alembic](https://alembic.sqlalchemy.org/en/latest/) to manage the future updates of the database schemas. - [ ] Add the capability to reload the application configuration on configuration file update (e.g.: credential update by the vault). - [ ] Rework how the database is updated with the IDFM data: For now the database is cleaned before refilling. It could be useful to avoid to empty the database and only apply deltas (update/add/remove rows). - [ ] Could be nice to compare FastAPI with [Litestar](https://litestar.dev/).