Skip to content
lruedar edited this page Sep 19, 2026 · 21 revisions

Decisions for Desing and Repos

General Product Backlog

This is just a reference to guide the construction of the backlog in each repository's list of issues.

[BE] Backend
[FE] Frontend
[AN] Analytics

Feature Description Acceptance criteria Repository
[BE] Core & Auth Set up NestJS/Prisma, DB and migrations, JWT+Argon2 authentication and user profile. App and Docker start register/login/refresh return tokens; GET/PATCH/DELETE /usuarios/me with cascade delete. backend
[BE] Well-being Daily check-in, panic button, Respira, Support and Protocols. One check-in/day; contacts + panic events with response time; breathing sessions; emergency lines; protocols with steps. backend
[BE] Content & Activity Flashcards, Games, Audios and unified Activity tab. Public catalogs; sessions/views require auth; paginated GET /actividad feed for the user. backend
[BE] Analytics & Wrap-up Telemetry, institutions/analytics, privacy, Swagger and deploy. Events → 202; summary with k-anonymity ≥5; 403 without consent; Swagger at /api/docs; Docker OK. backend
[FE] Breathing exercises Breathing exercises screen with guided animation and sessions. The user sees breathing exercises; selecting one opens an animated guide that expands and contracts in sync with the inhalation, retention, and exhalation phases, featuring optional haptic feedback; a timer indicates the remaining time; the user can pause or end the exercise, and a confirmation message appears upon completion. Flutter and Kotlin
[FE] Daily Check-in Daily user mood check-in via an interactive survey. User picks a mood from a set of icons and can add an optional note; only one check-in is allowed per day (UI blocks a second and shows a message); current and longest streak are displayed; past check-ins shown in a calendar. Flutter and Kotlin
[FE] Flashcards Category-based cards with swipe navigation. The user views cards by category, selects the ones they want to see, and swipes left or right to navigate between them; each card displays its title and content, featuring smooth transitions and a clear indication when the deck is finished. Flutter and Kotlin
[FE] Registration, Login, and Profile Account creation, sign-in and profile management. Users can register and log in using validated forms with clear error messages; the session persists after restarting the application; the profile screen allows viewing and editing of the name, photo, and language; and users can log out and delete their account after confirmation. Flutter and Kotlin
[FE] Panic Button Panic button with quick contact to your support network via call or message. The user can add, edit, and delete the emergency contact; selecting this contact offers the option to call and/or send a message and displays the connection or confirmation status, while an appropriate message is shown if there is no connection. Flutter and Kotlin
[FE] Support network Support network screen with emergency lines and contacts. The user views a list of emergency lines—including names, phone numbers, and descriptions—and can filter by personal contacts or emergency lines; tapping a line initiates a call; personal assistance contacts are displayed alongside them; and loading and no-data states are managed. Flutter and Kotlin

Flutter's Product Backlog
Kotlin's Product Backlog
Backend's Product Backlog

Architectural Desing

Components diagram

flowchart TB
    subgraph CLIENTES["Clientes móviles"]
        subgraph KOTLIN["App Android - Kotlin (MVVM)"]
            K_VIEW["View<br/>Pantallas"]
            K_VM["ViewModel<br/>Estado de pantalla"]
            K_REPO["Repository<br/>Cliente HTTP"]
            K_LOCAL[("Almacenamiento local<br/>Datos sin consentimiento<br/>y audios propios")]
            K_VIEW --> K_VM
            K_VM --> K_REPO
            K_REPO --> K_LOCAL
        end

        subgraph FLUTTER["App Flutter (MVVM)"]
            F_VIEW["View<br/>Pantallas"]
            F_VM["ViewModel<br/>Estado de pantalla"]
            F_REPO["Repository<br/>Cliente HTTP"]
            F_LOCAL[("Almacenamiento local<br/>Datos sin consentimiento<br/>y audios propios")]
            F_VIEW --> F_VM
            F_VM --> F_REPO
            F_REPO --> F_LOCAL
        end
    end

    DIALER["Servicio de llamadas<br/>del dispositivo"]

    K_VM -->|"llama a contacto<br/>o línea de emergencia"| DIALER
    F_VM -->|"llama a contacto<br/>o línea de emergencia"| DIALER

    subgraph BACKEND["Backend - NestJS + TypeScript (Docker)"]
        API["API REST versionada<br/>Documentación Swagger"]

        subgraph MODULOS["Módulos funcionales"]
            M_USR["Usuarios, perfil<br/>y rachas"]
            M_BIEN["Check-in, Respira, Protocolos,<br/>Flashcards, Juegos y Audios"]
            M_APOYO["Botón de pánico, contactos<br/>y líneas de emergencia"]
            M_ACT["Actividad<br/>del usuario"]
            M_ANA["Analítica institucional<br/>y telemetría"]
        end

        PRISMA["Prisma ORM<br/>Migraciones y seed"]

        API --> M_USR
        API --> M_BIEN
        API --> M_APOYO
        API --> M_ACT
        API --> M_ANA

        M_USR --> PRISMA
        M_BIEN --> PRISMA
        M_APOYO --> PRISMA
        M_ACT --> PRISMA
        M_ANA --> PRISMA
    end

    subgraph PERSISTENCIA["Persistencia"]
        DB[("PostgreSQL<br/>Tablas de la aplicación")]
        VISTAS["Vistas de analítica<br/>vista_actividad_usuario<br/>resumen_actividad_departamento"]
        DB -.->|"alimenta"| VISTAS
    end

    K_REPO -->|"HTTPS / JSON"| API
    F_REPO -->|"HTTPS / JSON"| API
    PRISMA -->|"SQL"| DB
    M_ANA -.->|"lee agregados"| VISTAS
    M_ACT -.->|"lee"| VISTAS
Loading

Deployment diagram

Deployment diagram

Class diagram

image

Rational behind Architectural Desing decisions

We chose NestJS due to the way it organizes everything into modules, which fits perfectly onto the five internal modules of the backend: Users, Well-being, Support/Panic, Activity, Analytics. Each member can work on their own module without affecting others. We also chose Prisma due to its typed autocomplete and easier migrations. PostgreSQL was chosen because the model is relational and because it let us gather analytics using database views.

We chose JWT because we wanted clients to keep functioning offline without depending on a "live" session.

The ViewModel calling the phone's calling service directly was chosen to avoid depending on internet working to call a contact during a crisis.

When a user doesn't want their data saved, that data just stays on the phone and never reaches the backend..

In the class diagram, User composes Check-in, Panic, SupportContact, and Activity log. We decided this because deleting the account wipes everything tied to that person instead of leaving orphaned data floating around.

Finally, we used MVVM with a Repository as the only thing that talks to the API, because this let us test the ViewModels without needing a real connection, and gave us a single place to decide whether a piece of data gets sent to the backend or just stays stored locally.

Implemented MVVM

The example structure for the mood_checkin feature is implemented using MVVM in Flutter, as follows:

lib/
├── main.dart
├── home/home_screen.dart
└── features/
    ├── mood_checkin/
    │   ├── model/       mood_state.dart, mood_checkin.dart
    │   ├── data/        mood_repository.dart (contrato), fake_mood_repository.dart
    │   ├── viewmodel/   mood_checkin_viewmodel.dart
    │   └── view/        mood_checkin_screen.dart
test/
└── mood_checkin_viewmodel_test.dart

The example structure for the mood_checkin feature was implemented using MVVM in Kotlin (Android), as follows:

app/src/
├── main/java/com/zenmind/
│   ├── MainActivity.kt
│   ├── home/HomeScreen.kt
│   └── features/
│       └── moodcheckin/
│           ├── model/       MoodState.kt, MoodCheckin.kt
│           ├── data/        MoodRepository.kt (contrato), FakeMoodRepository.kt
│           ├── viewmodel/   MoodCheckinViewModel.kt
│           └── view/        MoodCheckinScreen.kt
└── test/java/com/zenmind/
    └── MoodCheckinViewModelTest.kt

Complemented Value Proposition

  • How do the smart features help to generate value? The Daily Check-in creates the habit because it makes progress visible through a streak and a calendar with past check-ins, incentivizing users to maintain regularity in the process of bettering their well-being. Also, both Flashcards and the Activity feed configure according to what the student has looked at before, to feel unique and personalized to each individual. Finally, Analytics turns raw usage data into anonymized summaries that the Decanatura can use, like noticing which weeks are more stressful for which majors, without ever seeing one specific student's data.

  • How do the CAS features help to generate value? The panic button and support network go directly to the phone's call/message function instead of passing through the backend, to ensure that students in a crisis can contact someone regardless of internet. Also, breathing exercises use vibrations (haptic feedback) synchronized to the breathing phases to keep the student's focus without having them look at the screen.


Complete Native Prototype

Prototype with full views

Prototype in mobile

Clone this wiki locally