Onboarding
Setelah register, user wajib menyelesaikan onboarding sebelum bisa menggunakan fitur utama. Onboarding terdiri dari 3 step dengan beberapa sub-step.
Alur Onboarding
Step 1 β Profile Setup (9 sub-steps):
0: Community Rules β Accept rules
1: Welcome β Welcome screen (no data)
2: Name β Input nama
3: Gender β Pilih MALE / FEMALE
4: Birthday β Input tanggal lahir
5: Body Basics β Tinggi/berat badan (opsional)
6: Photos β Upload foto profil (min 2, maks 6)
7: Bio β Input bio singkat (opsional)
8: Location β Pilih negara, provinsi, kota
Step 2 β Preferences (5 sub-steps):
0: Transition β Screen transisi
1: Motivations β Pilih motivasi (dynamic dari DB)
2: Sports β Pilih olahraga favorit (dynamic dari DB)
3: Activity Style β Pilih gaya aktivitas (dynamic dari DB)
4: Availability β Pilih ketersediaan (dynamic dari DB)
Step 3 β Permissions (3 sub-steps):
0: Transition β Screen transisi
1: Location Permission β Aktifkan geolokasi
2: Notifications β Aktifkan push notification β SelesaiGET /onboarding/status
Cek status onboarding dan data yang sudah disimpan (untuk resume).
Memerlukan JWT authentication.
Contoh Request
curl -X GET https://fumai.app/api/mobile/v1/onboarding/status \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"const res = await fetch('https://fumai.app/api/mobile/v1/onboarding/status', {
headers: { Authorization: `Bearer ${accessToken}` },
})
const data = await res.json()Response 200
{
"success": true,
"data": {
"isCompleted": false,
"currentStep": 1,
"currentSubStep": 3,
"completedAt": null,
"skippedAt": null,
"profile": {
"name": "John Doe",
"gender": "MALE",
"birthDate": "1995-06-15",
"height": 175,
"heightUnit": "cm",
"weight": 70,
"weightUnit": "kg",
"photos": ["https://..."],
"bio": "Fitness enthusiast",
"communityRulesAccepted": true,
"countryId": "clx...",
"regionId": "clx...",
"cityId": "clx...",
"locale": "id",
"timezone": "Asia/Jakarta",
"avatarUrl": "https://...",
"motivations": [],
"favoriteSports": [],
"activityStyle": [],
"preferredAvailability": []
}
}
}Response Fields
| Field | Tipe | Keterangan |
|---|---|---|
isCompleted | boolean | true jika semua step selesai |
currentStep | number | Step terakhir selesai (0-3). 0=belum mulai, 1=profile done, 2=preferences done, 3=all done |
currentSubStep | number | Sub-step terakhir (0-8) |
completedAt | string? | ISO date jika completed |
profile | object? | Data profil yang sudah disimpan |
POST /onboarding/save-profile
Simpan data profil secara incremental (Step 1). Tidak semua field harus dikirim β hanya field yang berubah.
Memerlukan JWT authentication.
Request Body
| Field | Tipe | Wajib | Keterangan |
|---|---|---|---|
communityRulesAccepted | boolean | Tidak | Terima community rules |
name | string | Tidak | Min 2 karakter |
gender | string | Tidak | "MALE", "FEMALE", "OTHER" |
birthDate | string | Tidak | ISO date, usia 13-120 tahun |
height | number | Tidak | 50-300 cm (selalu disimpan dalam cm) |
heightUnit | string | Tidak | "cm" atau "feet" (preferensi display) |
weight | number | Tidak | 20-500 kg (selalu disimpan dalam kg) |
weightUnit | string | Tidak | "kg" atau "pound" (preferensi display) |
photos | string[] | Tidak | URL foto, maks 6 |
bio | string | Tidak | Maks 500 karakter |
countryId | string | Tidak | ID negara |
regionId | string | Tidak | ID region/provinsi |
cityId | string | Tidak | ID kota |
locale | string | Tidak | Contoh: "id", "en" |
timezone | string | Tidak | Contoh: "Asia/Jakarta" |
subStep | number | Tidak | 0-8, melacak progress |
completed | boolean | Tidak | true = tandai Step 1 selesai |
Contoh Request
curl -X POST https://fumai.app/api/mobile/v1/onboarding/save-profile \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "John Doe",
"gender": "MALE",
"subStep": 3
}'const res = await fetch('https://fumai.app/api/mobile/v1/onboarding/save-profile', {
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'John Doe',
gender: 'MALE',
subStep: 3,
}),
})
const data = await res.json()Response 200
{
"success": true,
"data": {
"message": "Progress saved"
}
}Behavior
- Field yang tidak dikirim = tidak diubah (incremental save)
subStepmelacak posisi terakhir user untuk resumecompleted: truemenandai Step 1 selesai- Timezone otomatis diset dari city > country >
"Asia/Jakarta" - Photo pertama otomatis jadi avatar user
Info: Tinggi selalu disimpan dalam cm, berat selalu dalam kg.
heightUnitdanweightUnithanya untuk preferensi display.
POST /onboarding/upload-photo
Upload foto profil untuk onboarding. Gunakan URL yang dikembalikan di photos array saat save-profile.
Memerlukan JWT authentication.
Request
Content-Type: multipart/form-data| Field | Tipe | Wajib | Keterangan |
|---|---|---|---|
file | File | Ya | Image file (JPG, PNG, WebP) |
Contoh Request
curl -X POST https://fumai.app/api/mobile/v1/onboarding/upload-photo \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-F "file=@photo.jpg"const formData = new FormData()
formData.append('file', imageFile)
const res = await fetch('https://fumai.app/api/mobile/v1/onboarding/upload-photo', {
method: 'POST',
headers: { Authorization: `Bearer ${accessToken}` },
body: formData,
})
const data = await res.json()Response 200
{
"success": true,
"data": {
"url": "https://cdn.fumai.app/profile/clx.../1709...-abc123.jpg",
"key": "profile/clx.../1709...-abc123.jpg"
}
}Batasan
| Setting | Nilai |
|---|---|
| Ukuran maks | 5MB |
| Tipe file | JPEG, PNG, WebP |
| Min foto | 2 (untuk lanjut onboarding) |
| Maks foto | 6 |
GET /onboarding/options
Mendapatkan opsi dinamis untuk onboarding Step 2. Opsi dikelola dari database (admin-managed).
Tidak memerlukan authentication.
Query Parameters
| Parameter | Tipe | Wajib | Keterangan |
|---|---|---|---|
type | string | Ya | Tipe opsi (lihat tabel di bawah) |
Tipe Opsi
| Type | Keterangan | Jumlah Opsi |
|---|---|---|
motivation | Alasan menggunakan Fumai | 4 |
activity_style | Preferensi grup aktivitas | 4 |
sport_category | Kategori induk olahraga | 10 |
sport | Olahraga/aktivitas individual | 127 |
availability | Ketersediaan waktu | 5 |
fitmatch_interest | Yang dicari di FitMatch | 8 |
Contoh Request
curl -X GET "https://fumai.app/api/mobile/v1/onboarding/options?type=motivation"const res = await fetch(
'https://fumai.app/api/mobile/v1/onboarding/options?type=motivation'
)
const data = await res.json()Response 200
{
"success": true,
"options": [
{
"optionId": "find_sport_buddy",
"label": "Find a sport buddy",
"icon": "π₯",
"category": null,
"sortOrder": 0
},
{
"optionId": "SOCCER",
"label": "Soccer / Football",
"icon": "https://cdn.fumai.app/...",
"category": "ball_court",
"sortOrder": 23
}
]
}Info: Icon bisa berupa emoji string atau URL gambar (SVG/PNG).
POST /onboarding/save-preferences
Simpan preferensi secara incremental (Step 2).
Memerlukan JWT authentication.
Request Body
| Field | Tipe | Wajib | Keterangan |
|---|---|---|---|
motivations | string[] | Tidak | Divalidasi terhadap OnboardingOption |
favoriteSports | string[] | Tidak | Maks 50, divalidasi terhadap DB |
activityStyle | string[] | Tidak | Divalidasi terhadap DB |
preferredAvailability | string[] | Tidak | Divalidasi terhadap DB |
preferredWorkoutTime | string[] | Tidak | early_morning, morning, afternoon, evening, night, flexible |
workoutFrequency | number | Tidak | Integer 1-7 (kali per minggu) |
subStep | number | Tidak | Melacak progress |
completed | boolean | Tidak | true = tandai Step 2 selesai |
Contoh Request
curl -X POST https://fumai.app/api/mobile/v1/onboarding/save-preferences \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"motivations": ["find_sport_buddy", "stay_active"],
"favoriteSports": ["SOCCER", "RUNNING"],
"activityStyle": ["partner"],
"preferredAvailability": ["weekdays", "morning"],
"completed": true
}'const res = await fetch('https://fumai.app/api/mobile/v1/onboarding/save-preferences', {
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
motivations: ['find_sport_buddy', 'stay_active'],
favoriteSports: ['SOCCER', 'RUNNING'],
activityStyle: ['partner'],
preferredAvailability: ['weekdays', 'morning'],
completed: true,
}),
})
const data = await res.json()Response 200
{
"success": true,
"message": "Progress saved"
}POST /onboarding/save-permissions
Simpan permissions dan selesaikan onboarding (Step 3).
Memerlukan JWT authentication.
Request Body
| Field | Tipe | Wajib | Keterangan |
|---|---|---|---|
locationEnabled | boolean | Ya | User memberikan izin lokasi |
latitude | number | Tidak | GPS latitude (jika lokasi diaktifkan) |
longitude | number | Tidak | GPS longitude (jika lokasi diaktifkan) |
pushNotifications | boolean | Ya | User memberikan izin push notification |
Contoh Request
curl -X POST https://fumai.app/api/mobile/v1/onboarding/save-permissions \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"locationEnabled": true,
"latitude": -8.6705,
"longitude": 115.2123,
"pushNotifications": true
}'const res = await fetch('https://fumai.app/api/mobile/v1/onboarding/save-permissions', {
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
locationEnabled: true,
latitude: -8.6705,
longitude: 115.2123,
pushNotifications: true,
}),
})
const data = await res.json()Response 200
{
"success": true,
"message": "Onboarding completed successfully",
"data": {
"onboardingCompleted": true,
"locationEnabled": true,
"pushNotifications": true
}
}Info: Endpoint ini menandai onboarding sebagai selesai. Setelah ini, navigasikan user ke halaman utama/dashboard.