107 lines
4.8 KiB
Markdown
107 lines
4.8 KiB
Markdown
# Factura del Hogar
|
|
|
|
Flutter app for tracking home bills and recurring expenses. All data stored locally via SQLite — no internet, no accounts.
|
|
|
|
## Build & install
|
|
|
|
```bash
|
|
export JAVA_HOME=/root/.sdkman/candidates/java/21.0.11-amzn
|
|
/opt/flutter/bin/flutter pub get
|
|
/opt/flutter/bin/flutter build apk --debug
|
|
/opt/android-sdk/platform-tools/adb install build/app/outputs/flutter-apk/app-debug.apk
|
|
```
|
|
|
|
## Prerequisites
|
|
|
|
- **JDK 21** via SDKMAN: `sdk use java 21.0.11-amzn`
|
|
- **Android SDK** at `/opt/android-sdk`
|
|
- **Flutter 3.27.4** at `/opt/flutter/bin`
|
|
- **adb** at `/opt/android-sdk/platform-tools/adb` (not in PATH)
|
|
- NDK `27.0.12077973` in `android/app/build.gradle`
|
|
|
|
## Verify
|
|
|
|
```bash
|
|
/opt/flutter/bin/dart analyze
|
|
export JAVA_HOME=/root/.sdkman/candidates/java/21.0.11-amzn && /opt/flutter/bin/flutter build apk --debug
|
|
```
|
|
|
|
No test suite configured beyond the default boilerplate (`test/widget_test.dart`). Lint shows 3 pre-existing issues (unused import in test file, deprecated `value` on Color, async BuildContext) — safe to ignore.
|
|
|
|
## Stack
|
|
|
|
- **State**: Provider (`ChangeNotifierProvider` for `Servicio`, `Factura`, `Configuracion`)
|
|
- **DB**: sqflite (single `hogarcontrol.db`, tables: `servicios`, `facturas`, `configuracion`)
|
|
- **Notifications**: `flutter_local_notifications` with `zonedSchedule` + timezone
|
|
- **Charts**: fl_chart (bar chart) + table_calendar
|
|
- **UI**: Material 3, `ThemeMode.system` (light/dark via system), custom `SmoothPageTransitionBuilder` (fade+slide on all pushes)
|
|
- **Navigation**: manual `Navigator.push` with `MaterialPageRoute` — no router
|
|
|
|
## Project layout
|
|
|
|
| Path | Purpose |
|
|
|---|---|
|
|
| `lib/main.dart` | Entry, MultiProvider, `_buildLightTheme()` / `_buildDarkTheme()` |
|
|
| `lib/models/` | Data classes (`Servicio`, `Factura`, `Configuracion`) |
|
|
| `lib/database/database_helper.dart` | Singleton DB with CRUD helpers |
|
|
| `lib/providers/` | ChangeNotifier state classes |
|
|
| `lib/screens/` | 9 screens (Splash → Dashboard → ...) |
|
|
| `lib/services/notification_service.dart` | Local notification scheduling |
|
|
| `lib/widgets/` | `StatCard` (animated fade+slide on mount) |
|
|
| `lib/utils/currency_utils.dart` | 37 currencies with `formatPrice()`, `getSymbol()`, `getDisplayName()` |
|
|
| `lib/utils/transitions.dart` | `SmoothPageTransitionBuilder` for global page transitions |
|
|
|
|
## DB schema
|
|
|
|
- `servicios` — id, nombre, icono, color, dia_vencimiento, fecha_creacion
|
|
- `facturas` — id, servicio_id (FK), monto, fecha_emision, fecha_vencimiento, estado, nota, fecha_pago
|
|
- `configuracion` — id, dias_recordatorio (comma-separated), tema, moneda
|
|
|
|
## Key Android config
|
|
|
|
- `android/app/build.gradle` — compileSdk 35, minSdk 26, targetSdk 35, coreLibraryDesugaringEnabled, AGP 8.7.3
|
|
- `android/settings.gradle` — AGP 8.7.3, Kotlin 2.0.21
|
|
- Permissions (main manifest): `POST_NOTIFICATIONS`, `RECEIVE_BOOT_COMPLETED`, `SCHEDULE_EXACT_ALARM`
|
|
- `INTERNET` only in debug/profile manifests (Flutter dev requirement — not in release)
|
|
|
|
## Currency helper
|
|
|
|
Always use `CurrencyUtils` instead of hardcoding symbols:
|
|
- `CurrencyUtils.formatPrice(amount, code)` — returns e.g. `$1,234.56` or `€1.234,56`
|
|
- `CurrencyUtils.getSymbol(code)` — symbol only
|
|
- `CurrencyUtils.getDisplayName(code)` — e.g. `"USD - US Dollar"`
|
|
- Zero-decimal currencies (JPY, KRW, CLP, PYG, COP) are handled automatically
|
|
- List: `CurrencyUtils.allCurrencies` (37 currencies)
|
|
|
|
## Styling conventions
|
|
|
|
- All cards use `BorderRadius.circular(16)` via `CardTheme`
|
|
- Input fields use `filled: true` with `BorderRadius.circular(12)`
|
|
- Page transitions: fade + slight vertical slide (defined in `transitions.dart`)
|
|
- List items animate in with `TweenAnimationBuilder<double>` using staggered delays (`300 + i * 60` ms pattern)
|
|
- `StatCard` is a `StatefulWidget` with `SingleTickerProviderStateMixin` — delay via `delayMs` prop
|
|
|
|
## Warnings
|
|
|
|
- `dart analyze` flags unused imports/variables in screens — safe to ignore for widget-tree watchers
|
|
- Running as root causes flutter warnings but doesn't break builds
|
|
- Flutter 3.27.4 has known warnings about x86 target deprecation
|
|
|
|
## Release a Play Store update
|
|
|
|
1. **Version**: bump `version:` in `pubspec.yaml` (e.g. `1.0.0+1` → `1.0.0+2`)
|
|
2. **Build AAB**: `export JAVA_HOME=/root/.sdkman/candidates/java/21.0.11-amzn && /opt/flutter/bin/flutter build appbundle --release`
|
|
3. **Native debug symbols** (required by Play Console):
|
|
```bash
|
|
cd build/app/intermediates/merged_native_libs/release/mergeReleaseNativeLibs/out/lib
|
|
zip -r /var/www/android/hogarcontrol/build/app/outputs/bundle/release/native-debug-symbols.zip .
|
|
```
|
|
Structure: `<abi>/libapp.so`, `<abi>/libflutter.so` — no `lib/` wrapper dir.
|
|
4. Upload to Play Console:
|
|
- **App Bundle**: `build/app/outputs/bundle/release/app-release.aab`
|
|
- **Native debug symbols**: `build/app/outputs/bundle/release/native-debug-symbols.zip`
|
|
|
|
## Remote
|
|
|
|
- Origin: `https://git.devlab.lat/android/home-control.git`
|