España Decide es una aplicación móvil de participación ciudadana que ofrece a los ciudadanos la posibilidad de para crear, votar y discutir propuestas sobre temas de interés público. Construida con tecnología nativa multiplataforma, permite a los usuarios participar activamente en la democracia desde sus dispositivos Android e iOS.
La aplicación facilita el debate democrático organizado por categorías como Economía, **Sanidad **, Educación, Medio Ambiente, Justicia y más, permitiendo que las voces de los ciudadanos sean escuchadas en tiempo real.
- 🗳️ Sistema de Votación: Vota a favor o en contra de propuestas con un sistema intuitivo de upvote/downvote
- 📝 Creación de Propuestas: Cualquier usuario puede crear propuestas con título y descripción detallada
- 🏷️ Categorías Temáticas: Propuestas organizadas por áreas (economía, sanidad, educación, etc.)
- ⚡ Actualizaciones en Tiempo Real: Sincronización instantánea de votos y nuevas propuestas vía WebSockets
- 🔒 Autenticación Segura: Sistema de login con email/contraseña y Google OAuth
- 📊 Ranking por Popularidad: Las propuestas se ordenan por votos netos (upvotes - downvotes)
- 🎨 Diseño Material 3: Interfaz moderna con soporte para tema claro/oscuro
- 🌐 Multiplataforma: Misma experiencia en Android e iOS con código compartido
🚧 Próximamente: Capturas de las pantallas principales (Categorías, Lista de Propuestas, Detalle, Creación)
La aplicación estará disponible próximamente en:
- 📱 Google Play Store: Enlace próximamente
- 🍎 Apple App Store: Enlace próximamente
SpainDecides está construido con tecnologías de vanguardia:
| Componente | Tecnología |
|---|---|
| Lenguaje | Kotlin 2.2.20 |
| Framework UI | Compose Multiplatform 1.9.1 |
| Arquitectura | MVVM + Repository Pattern |
| Backend | Supabase (PostgreSQL + Auth + Realtime) |
| Networking | Ktor Client 3.0.3 |
| Inyección Dependencias | Koin 4.1.1 |
| Navegación | Jetpack Navigation Compose 2.8.0 |
| Gestión Estado | Kotlin Coroutines + StateFlow |
| Serialización | Kotlinx Serialization |
La aplicación sigue el patrón MVVM (Model-View-ViewModel) con arquitectura limpia en capas:
┌─────────────────────────────────────────────────────────┐
│ PRESENTATION LAYER │
│ ┌──────────────┐ ┌──────────────────────────┐ │
│ │ Compose UI │ ◄──────► │ ViewModels │ │
│ │ (Screens) │ │ (StateFlow + Coroutines)│ │
│ └──────────────┘ └──────────┬───────────────┘ │
└───────────────────────────────────────┼─────────────────┘
│
┌───────────────────────────────────────┼─────────────────┐
│ DOMAIN LAYER │ │
│ ┌────────────────────▼──────────────┐ │
│ │ Repository Interfaces │ │
│ │ (Abstraction Layer) │ │
│ └─────────────────────┬─────────────┘ │
└────────────────────────────────────────┼────────────────┘
│
┌────────────────────────────────────────┼─────────────────┐
│ DATA LAYER │ │
│ ┌───────────────────────────────────┐ │ │
│ │ Repository Implementations │ │ │
│ └────────┬──────────────────────────┘ │ │
│ │ │ │
│ ┌────────▼─────────┐ ┌─────────────▼──────────────┐ │
│ │ Ktor Client │ │ Supabase Client │ │
│ │ (HTTP/REST) │ │ (Auth + Realtime) │ │
│ └──────────────────┘ └────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────┐
│ Supabase Backend │
│ - PostgreSQL Database │
│ - Authentication │
│ - Realtime (WebSockets) │
│ - RLS Policies │
└──────────────────────────┘
Flujo de Datos:
- UI → El usuario interactúa con Composables
- ViewModel → Gestiona el estado y ejecuta lógica de negocio
- Repository → Abstrae el origen de datos
- API/Database → Ktor Client realiza peticiones HTTP a Supabase
- Realtime Updates → WebSockets notifican cambios en tiempo real
- State Update → StateFlow emite nuevos estados → UI se recompone
Spain Decides is a citizen participation mobile application that empowers citizens to create, vote, and discuss proposals on public interest topics. Built with native multiplatform technology, it enables users to actively participate in democracy from their Android and iOS devices.
The app facilitates democratic debate organized by categories such as Economy, Healthcare, * Education*, Environment, Justice, and more, allowing citizens' voices to be heard in real-time.
- 🗳️ Voting System: Vote for or against proposals with an intuitive upvote/downvote system
- 📝 Proposal Creation: Any user can create proposals with title and detailed description
- 🏷️ Thematic Categories: Proposals organized by areas (economy, healthcare, education, etc.)
- ⚡ Real-time Updates: Instant synchronization of votes and new proposals via WebSockets
- 🔒 Secure Authentication: Login system with email/password and Google OAuth
- 📊 Popularity Ranking: Proposals sorted by net votes (upvotes - downvotes)
- 🎨 Material Design 3: Modern interface with light/dark theme support
- 🌐 Multiplatform: Same experience on Android and iOS with shared codebase
🚧 Coming soon: Screenshots of main screens (Categories, Proposal List, Detail, Creation)
The application will be available soon on:
- 📱 Google Play Store: Link coming soon
- 🍎 Apple App Store: Link coming soon
SpainDecides is built with cutting-edge technologies:
| Component | Technology |
|---|---|
| Language | Kotlin 2.2.20 |
| UI Framework | Compose Multiplatform 1.9.1 |
| Architecture | MVVM + Repository Pattern |
| Backend | Supabase (PostgreSQL + Auth + Realtime) |
| Networking | Ktor Client 3.0.3 |
| Dependency Injection | Koin 4.1.1 |
| Navigation | Jetpack Navigation Compose 2.8.0 |
| State Management | Kotlin Coroutines + StateFlow |
| Serialization | Kotlinx Serialization |
The application follows the MVVM (Model-View-ViewModel) pattern with clean architecture layers:
┌─────────────────────────────────────────────────────────┐
│ PRESENTATION LAYER │
│ ┌──────────────┐ ┌──────────────────────────┐ │
│ │ Compose UI │ ◄──────► │ ViewModels │ │
│ │ (Screens) │ │ (StateFlow + Coroutines)│ │
│ └──────────────┘ └──────────┬───────────────┘ │
└───────────────────────────────────────┼─────────────────┘
│
┌───────────────────────────────────────┼──────────────────┐
│ DOMAIN LAYER │ │
│ ┌────────────────────▼────────────────┐ │
│ │ Repository Interfaces │ │
│ │ (Abstraction Layer) │ │
│ └─────────────────────┬───────────────┘ │
└────────────────────────────────────────┼─────────────────┘
│
┌────────────────────────────────────────┼─────────────────┐
│ DATA LAYER │ │
│ ┌───────────────────────────────────┐ │ │
│ │ Repository Implementations │ │ │
│ └────────┬──────────────────────────┘ │ │
│ │ │ │
│ ┌────────▼─────────┐ ┌─────────────▼──────────────┐ │
│ │ Ktor Client │ │ Supabase Client │ │
│ │ (HTTP/REST) │ │ (Auth + Realtime) │ │
│ └──────────────────┘ └────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────┐
│ Supabase Backend │
│ - PostgreSQL Database │
│ - Authentication │
│ - Realtime (WebSockets) │
│ - RLS Policies │
└──────────────────────────┘
Data Flow:
- UI → User interacts with Composables
- ViewModel → Manages state and executes business logic
- Repository → Abstracts data source
- API/Database → Ktor Client makes HTTP requests to Supabase
- Realtime Updates → WebSockets notify changes in real-time
- State Update → StateFlow emits new states → UI recomposes
- Android Studio Ladybug | 2024.2.1 or later
- Xcode 15.0+ (for iOS development on macOS)
- JDK 17 or later
- Kotlin 2.2.20 (included in project)
-
Clone the repository
git clone https://github.com/YourUsername/SpainDecides.git cd SpainDecides -
Open in Android Studio
- Open Android Studio
- Select "Open an Existing Project"
- Navigate to the cloned
SpainDecidesfolder
-
Sync Gradle
- Android Studio will automatically sync Gradle dependencies
- Wait for the sync to complete
Option 1: Using Android Studio
- Select the
composeApprun configuration - Click the "Run" button (or press
Shift + F10)
Option 2: Using Terminal
# Build debug APK
./gradlew :composeApp:assembleDebug
# Install on connected device/emulator
./gradlew :composeApp:installDebugRun on emulator:
# Start emulator (if not running)
emulator -avd Pixel_8_API_35
# Install and launch
./gradlew :composeApp:installDebug
adb shell am start -n com.apptolast.spaindecides/.MainActivityOption 1: Using Xcode
- Open the
/iosAppdirectory in Xcode - Select your target device or simulator
- Click the "Run" button (or press
Cmd + R)
Option 2: Build Kotlin Framework
# For iOS Simulator (ARM64)
./gradlew :composeApp:linkDebugFrameworkIosSimulatorArm64
# For iOS Device (ARM64)
./gradlew :composeApp:linkDebugFrameworkIosArm64# Run all common tests
./gradlew :composeApp:cleanTestDebugUnitTest :composeApp:testDebugUnitTest
# Run with coverage
./gradlew :composeApp:testDebugUnitTest --tests "*"SpainDecides/
├── composeApp/ # Multiplatform module
│ └── src/
│ ├── commonMain/ # Shared code (Android + iOS)
│ │ ├── kotlin/com/apptolast/spaindecides/
│ │ │ ├── presentation/ # UI Layer (MVVM)
│ │ │ │ ├── ui/
│ │ │ │ │ ├── screens/ # Composable screens
│ │ │ │ │ ├── components/ # Reusable UI components
│ │ │ │ │ └── theme/ # Material 3 theming
│ │ │ │ └── viewmodel/ # ViewModels
│ │ │ ├── domain/ # Domain Layer
│ │ │ │ └── repository/ # Repository interfaces
│ │ │ ├── data/ # Data Layer
│ │ │ │ ├── model/ # Data models
│ │ │ │ ├── remote/ # Ktor API services
│ │ │ │ └── repository/ # Repository implementations
│ │ │ └── di/ # Dependency Injection (Koin)
│ │ └── composeResources/ # Shared resources
│ ├── androidMain/ # Android-specific code
│ │ └── kotlin/
│ │ └── MainActivity.kt
│ ├── iosMain/ # iOS-specific code (Kotlin)
│ │ └── kotlin/
│ │ └── MainViewController.kt
│ └── commonTest/ # Shared tests
├── iosApp/ # iOS application entry point
│ └── iosApp/
│ └── iOSApp.swift
├── gradle/ # Gradle configuration
│ └── libs.versions.toml # Version catalog
└── build.gradle.kts # Root build script
Contributions are welcome! If you'd like to contribute to SpainDecides:
- Fork the repository
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Please ensure your code follows the existing code style and includes appropriate tests.
AppToLast
- GitHub: @apptolast
- Website: apptolast.com
- Built with Kotlin Multiplatform
- UI powered by Compose Multiplatform
- Backend by Supabase
- Icons from Material Design Icons
- CLAUDE.md - Comprehensive development guidelines and architecture documentation
- Kotlin Multiplatform Documentation
- Compose Multiplatform Documentation
- Ktor Client Documentation
- Koin Documentation
Made with ❤️ for democratic participation
⭐ If you find this project useful, please consider giving it a star!