# Dokumen Teknis Talacare A1
## Cara Menjalankan talacare-mobile
`talacare-mobile` menggunakan framework Flutter.
> Flutter adalah kerangka kerja sumber terbuka yang dikembangkan dan didukung oleh Google. Developer frontend dan full-stack menggunakan Flutter untuk membangun antarmuka pengguna (UI) aplikasi untuk beberapa platform dengan codebase tunggal.
Karena aplikasi yang dibuat adalah sebuah *game*, digunakan module **Flutter Flame**, yakni sebuah Game Engine Framework khusus Flutter.
### Struktur Project Flutter
- Terdapat folder `android/`, `ios/` `windows/`, `macos/`, `linux/`, dan `web/`. Yang perlu diperhatikan adalah folder `android/` saja karena aplikasi ini hanya dirancang untuk android (Namun jika ada rencana mengembangkan untuk platform lain folder tiap platform dapat dikonfigurasikan). Pada folder ini dapat diatur nama package aplikasi, versi/tag nya, dan permission yang dipakai.
- Folder `lib/` adalah folder utama source code disimpan. Penjelasan detail tentang masing-masing subdirektori dibawahnya sebagai berikut
- `lib/screens/`: berisi source code untuk halaman/page class, terdapat 2 kategori yakni halaman yang menggunakan **Flutter Widget** dan ada yang menggunakan **Flame Component**. Perbedaannya hanyalah Flame Component digunakan untuk unsur mekanisme game sementara Flutter Widget digunakan untuk antarmuka aplikasi umum.
- `lib/components/`: berisi source code untuk berbagai class-class yang diutilisasi di `screens`, khususnya untuk yang menggunakan Flame Component
- `lib/widgets/`: berisi source code untuk berbagai class-class yang diutilisasi di `screens`, khususnya untuk yang menggunakan Flutter Widget
- `lib/helpers/`: berisi utilitary functions, enumerations, dan sebagainya
- Terdapat juga cide lain di dalam `lib/` yang berada di luar 4 folder di atas seperti `main.dart` yang merupakan class utama yang dijalankan, `talacare.dart` yang merupakan class utama pada Flame Game, serta file-file konfigurasi.
- Folder `test/` berisi testcase-testcase yang akan dijalankan pada automated testing. Pada saat ini testcase belum terkelompokkan berdasarkan jenis kode yang diujikan.
- Folder `assets/` berisi aset-aset yang digunakan, dikategorikan menjadi gambar, tiles (map pada game), audio, dan fonts. Jika ingin menambahkan aset baru, jangan lupa menambahkannya pada `pubspec.yaml`
```yaml
assets:
- assets/images/Interiors_free/16x16/
- assets/images/Characters_free/
- assets/tiles/
- assets/images/D_Pad/
- assets/images/Overlays/
- assets/images/Activity_Points/
- assets/images/Activity_Events/
- assets/images/Illustrations/
- assets/images/Hospital/
- assets/images/Serene_Village/16x16_original/
- assets/images/Dialog/
- assets/images/Game_2/
- assets/images/Button/
- assets/images/Food/
- assets/audio/
```
### File-File Konfigurasi Yang Perlu Diperhatikan
- Terdapat file `lib/config.dart` yang mana bisa diatur **urlBackend** yang akan digunakan ketika aplikasi mengirimkan request.
- Terdapat file `lib/firebase_options.dart` yang mana bisa diatur konfigurasi Firebase (untuk keperluan login dengan akun Google dan juga analytics). Sebaiknya tidak mengubah isi file ini secara manual melainkan mengubahnya dengan command `flutterfire configure`.
### Cara Build APK
Jika ingin membuat apk aplikasi di local
1. Persiapkan instalasi Flutter yang bisa dilihat pada https://jagoflutter.com/tutorial-install-flutter-di-windows/, **developer menggunakan Flutter 3.19.0**, dan pastikan dengan `flutter doctor`
2. Install dependency dengan `flutter pub get`
3. Buat apk dengan `flutter build apk --release`, jika tidak ingin membuat apk melainkan hanya menjalankan saja, bisa menggunakan `flutter run --release` kemudian pilih device nya
Atau jika ingin di release di GitHub Release, bisa menggunakan Github Workflow `ci.yml`, namun pada file tersebut ada tahapan scan Sonarqube sehingga jika hanya ingin build aplikasi bisa menggunakan workflow berikut:
```yaml
name: CI/CD
on: [push, pull_request]
jobs:
deploy:
name: Make GitHub Release
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/staging' || github.event_name == 'pull_request' && github.base_ref == 'refs/heads/staging'
steps:
- name: Checkout Repository
uses: actions/checkout@v2
- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.19.0'
- name: Install dependencies
run: flutter pub get
- name: Build APK
run: flutter build apk --release
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: v.0.0.${{ github.run_number }}
release_name: Release v.0.0.${{ github.run_number }}
draft: false
prerelease: false
- name: Upload APK to Release
id: upload-release-asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: build/app/outputs/flutter-apk/app-release.apk
asset_name: app-release-${{ github.run_number }}.apk
asset_content_type: application/vnd.android.package-archive
```
Kemudian akan muncul release pada repository

### Cara Publish ke Play Store
Secara sederhananya, yang perlu disiapkan adalah ikon aplikasi, beberapa screenshot aplikasi, privacy policy, dan hasil bundle (.aab) aplikasi yang telah di-sign dengan release keystore.
Mengikuti guide berikut https://orangesoft.co/blog/how-to-publish-an-android-app-on-google-play-store
> Untuk privacy-policy bisa gunakan yang telah developer buat yakni https://ppl-a1-genap-2023-2024.github.io/privacy-policy/
## Cara Menjalankan talacare-backend
`talacare-backend` menggunakan framework Django.
> Django adalah perangkat lunak yang dapat Anda gunakan untuk mengembangkan aplikasi web dengan cepat dan efisien. Django memudahkan pekerjaan mereka dengan mengelompokkan fungsi yang berbeda ke dalam kumpulan besar modul yang dapat digunakan kembali dan disebut kerangka kerja aplikasi web. Developer menggunakan kerangka kerja web Django untuk mengatur dan menulis kode mereka secara lebih efisien dan mengurangi waktu pengembangan web secara signifikan.
### Struktur Project Django
Django project terdiri dari 3 App:
1. `main`: Saat ini tidak digunakan.
2. `export`: Untuk keperluan export data pemain.
3. `authentication`: Untuk memeriksa role pemain.
Terkait endpoint-endpoint yang tersedia akan dibahas pada bagian-bagian berikutnya (atau dapat anda lihat sendiri pada file `urls.py` di masing-masing Django App).
### File-File Konfigurasi Yang Perlu Diperhatikan
`pplbackend/settings.py` : Untuk konfigurasi Project Django
`pplbackend/settings/config/(local/production/staging/testing).py`: Konfigurasi khusus pada environment tertentu.
`Dockerfile`: Konfigurasi Docker (untuk membuild Docker Container)
`.github/workflows/deploy.yml`: Script untuk Deployment
### Menjalankan Django di Local
1. Install Python terlebih dahulu. Python dapat diunduh melalui https://www.python.org/downloads/ . **Versi Python yang digunakan developer adalah 3.11.3**.
2. Jika perlu, gunakan virtual environment agar versi package/dependency yang digunakan untuk proyek terpisah dari versi package/dependency yang digunakan oleh environment local. Dokumentasi terkait hal ini dapat dilihat di URL berikut https://docs.python.org/3.11/library/venv.html
3. Clone repositori backend yang sudah ada. Setelah itu, jalankan perintah `pip install -r requirements.txt` untuk menginstall dependency yang diperlukan. **Semua informasi mengenai dependency yang digunakan (beserta versinya) berada dalam file requirements.txt**
4. Jalankan server dengan perintah `python manage.py runserver`
### Django Dengan Docker Container
Saat ini, developer sudah melakukan setup agar server Django dapat berjalan di dalam Docker Container. Jika ingin menggunakan Docker Container untuk deployment, konfigurasinya sudah ada di file `Dockerfile`. **Perhatikan Environment Variables yang perlu di-declare sebelum mem-build container**. Informasi mengenai environment variables yang diperlukan akan dicantumkan bagian-bagian berikutnya.
### Guideline Deployment
1. Hingga saat ini, **Deployment dilakukan pada VM yang dihosting di Google Cloud Platform. Apabila server ingin di-deploy di tempat yang berbeda, harap Anda sesuaikan sendiri dengan keperluan Anda**.
2. Konfigurasi CI/CD terdapat pada direktori `.github/workflows/deploy.yml`. Harap sesuaikan konfigurasi ini jika Anda ingin men-deploy server selain di Google Cloud Platform.
3. Pastikan Anda sudah memiliki:
- Akun **GitHub** yang dapat mengakses repositori talacare-backend
- Akun **Docker Hub**
- **VM Instance** pada Google Cloud Platform yang dapat diakses dengan menggunakan protokol SSH (sudah mendaftarkan SSH key nya di project). **Sangat disarankan** untuk memiliki public static IP address.
4. Pada repositori backend, tambahkan `Repository secrets` seperti berikut:

Penjelasan:
- `CONTAINER_NAME_STAGING`: Nama Docker Container (misal: **pplbackend**)
- `CONTAINER_TAG_STAGING`: Tag Docker Container (misal: **latest**)
- `DB_HOST_STAGING`, `DB_NAME`, `DB_PASSWORD_STAGING`, `DB_PASSWORD_STAGING`, `DB_PORT_STAGING`, `DB_USER_STAGING`: Konfigurasi agar dapat terkoneksi ke database. Dapat dilihat di project Supabase (atau server database lainnya jika tidak menggunakan Supabase). Informasi ini juga dijelaskan pada bagian berikutnya mengenai Environment Variables.
- `DJANGO_ENV`: Gunakan **staging**.
- `DJANGO_SECRET`: Secret key Django untuk project ini.
- `DOCKER_PASSWORD`: Password akun Docker yang akan digunakan untuk menyimpan Docker Container.
- `DOCKER_USERNAME`: Username akun Docker yang akan digunakan untuk menyimpan Docker Container.
- `EMAIL_HOST_PASSWORD`: (merujuk ke bagian Environment Variables)
- `EMAIL_HOST_USER`: (merujuk ke bagian Environment Variables)
- `GCP_STATIC_IP_STAGING`: Public IP Address dari VM Instance. Variabel ini akan sering anda ubah apabila Public IP Address VM Instance anda tidak statis.
- `SENTRY_DSN`: (merujuk ke bagian Environment Variables)
- `SONAR_HOST_URL`, `SONAR_TOKEN`: Setup untuk analisis code quality dengan SonarQube. Isi jika ingin melakukan analisis code quality.
- `SSH_KEY_STAGING`: SSH key yang digunakan untuk mengakses VM. Isi sesuai dengan yang Anda miliki.
5. Setiap kali anda melakukan **push**, GitHub Actions akan **ter-trigger** dan menjalankan deployment script `deploy.yml`. Pantau alur GitHub Actions untuk mengantisipasi error yang mungkin terjadi. Jika GitHub Actions menunjukkan tanda centang hijau, artinya deployment sudah berhasil.
**CATATAN**:
- Apabila anda **tidak ingin melakukan analisis kode dengan SonarQube**, silakan **hapus step Test dan Sonarqube** di file `deploy.yml`.
- Saat ini, **script deployment akan selalu dijalankan** setiap ada push di branch manapun. Anda dapat mengkonfigurasi sendiri hal ini dengan mengubah `branches: '*'` pada file `deploy.yml` untuk menentukan pada branch mana saja script deployment perlu dijalankan.
### Environment Variables
- `SENTRY_DSN`: Anda bisa atur dsn_tag pada Sentry Anda sendiri jika ingin Dashboard Sentry Anda bisa mencatat/memonitor performance dan error yang terjadi di backend. Anda hanya perlu signup di sentry.io dan buat project baru dengan framework Django.
- `EMAIL_HOST_USER` & `EMAIL_HOST_PASSWORD`: Anda bisa atur alamat email yang mengirimkan data user pada variabel ini. **PENTING**: gunakan App Password, bukan password Akun Google Anda seperti pada tutorial berikut https://www.rumahweb.com/journal/cara-mengaktifkan-application-password-gmail/
- `DJANGO_ENV`: Nilai yang mungkin dari environment ini adalah `development`, `testing`, `staging`, `production`. Variabel ini menyatakan berada di environment mana server Django dijalankan. Variabel ini akan dijadikan acuan untuk mengimport salah satu di antara 4 file config (`local.py`, `production.py`, `staging.py`, atau `production.py`). File config tersebut berada pada direktori `pplbackend/config/`. Saat ini, environment `production` belum terpakai. File `local.py` harap dibuat sendiri untuk konfigurasi lokal (tidak ada di repositori).
- `DJANGO_SECRET`: Secret key Django yang harus dirahasiakan. Silakan buat secret yang baru apabila yang lama sudah tidak rahasia.
- `DB_NAME`, `DB_USER`, `DB_PASSWORD`, `DB_HOST`, `DB_PORT`: Konfigurasi untuk menghubungkan Django dengan database. Saat ini, developer menggunakan `PostgreSQL` sebagai DBMS dan di-host di `supabase.com`.
## Ringkasan Arsitektur
Secara umum arsitektur aplikasi bisa dilihat pada gambar berikut

### Dokumentasi API
Ada beberapa API yang bisa diakses pada backend.
Berikut di antaranya
- `/auth/check_role/`: Mengecek role dari pengguna yang sudah login dengan Flutter menggunakan Firebase. Ini dilakukan dengan mengecek apakah email pengguna sudah ada di database, karena tabel Users pada database hanya menyimpan informasi pengguna dengan role admin. Jika ingin menambah admin bisa dengan menambahkannya pada database secara langsung.
Request Body:
```json
{
"email": "youremail@gmail.com"
}
```
Response:
```json
{
"email": "youremail@gmail.com",
"role": "USER"
}
atau
{
"email": "youremail@gmail.com",
"role": "ADMIN"
}
```
- `/export/upload_data/`: Mengirim data durasi pemain bermain. Pada Flutter akan otomatis mengirim ke endpoint ini email dan durasi bermain.
Request Body:
```json
{
"email": "youremail@gmail.com",
"duration": "01:02:30"
}
```
Response:
```json
{
"message": "Berhasil mengunggah data pemain.",
"data": {
"email": "youremail@gmail.com",
"date": "2024-05-27",
"duration": "01:02:30"
}
}
```
- `/export/send_email/`: Mengirim isi data pemain dari database via email dalam bentuk file excel (xlsx). Alamat email penerima akan dicek apakah merupakan email admin atau bukan.
Request Body:
```json
{
"recipient_email": "youremail@gmail.com"
}
```
Response:
```json
{
"message": "Data berhasil diexport dan telah dikirim ke email youremail@gmail.com. Mohon cek inbox Anda."
}
atau
{
"message": "Anda tidak punya otorisasi untuk mengakses endpoint ini."
}
```
### Basis Data dan Penyimpanannya
Data pemain akan di-query berdasarkan data mentah yakni tiap row pada tabel `UserPlays` pada sheet pertama serta data yang telah dikelompokkan per bulan pada sheet kedua.
Berikut adalah diagram dari basis data untuk backend-nya.

### DANGER ZONE (RAHASIAKAN INFORMASI INI)
- Password DB Supabase (saat ini): ||HHYm9hUAqGIj7ios||<-klik untuk melihat
- Django Secret Key (saat ini): ||```django-insecure-8%ee%aes2!p^q^e)qko=bh4=ipj%vm9sn)2e4r-p5_!lvo-x1n```||<-klik untuk melihat
## Limitasi dan Known Bugs
- Penggunaan autorisasi pada API endpoint `/auth/check_role` dan `/export/send_email` sebenarnya bisa dengan menerapkan konfigurasi firebase authentication yang sama pada backend. Sehingga daripada mengirimkan email sebagai request body, bisa menggunakan token pada header.
- Karena konfigurasi CORS telah diatur agar endpoint bisa dipanggil lewat Flutter, pada halaman `/admin/` yang merupakan bawaan Django tidak akan bisa melakukan login. Jika ingin memanipulasi database perlu dilakukan secara langsung pada databasenya. Atau bisa juga dengan menambahkan `CSRF_TRUSTED_ORIGINS` pada `settings.py` agar isu ini hilang.
- Database server yang digunakan dihosting di `supabase.com`. Karena menggunakan versi gratis, database server akan mati sendiri jika digunakan dalam periode tertentu. Untuk menghindari hal ini, Anda dapat migrate sendiri database hosting ke tempat lain.