File size: 36,146 Bytes
a3e77a9
 
 
 
 
1177d61
a3e77a9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
359ee61
 
9e52285
 
 
 
 
 
 
 
 
c2003d2
9e52285
359ee61
 
6b959b3
a3e77a9
 
 
cabfcc4
 
 
a3e77a9
cabfcc4
a3e77a9
cabfcc4
 
 
a3e77a9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1f7dd45
 
 
 
 
 
 
aa83ff3
1f7dd45
 
 
a3e77a9
1f7dd45
 
 
 
 
 
 
 
 
 
 
a3e77a9
1f7dd45
 
 
 
 
aa83ff3
 
1f7dd45
 
a020582
a3e77a9
a020582
 
 
 
a3e77a9
 
 
a020582
 
a3e77a9
 
a020582
a3e77a9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57e875f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0199ba6
57e875f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0199ba6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57e875f
 
 
 
 
 
 
 
 
 
0199ba6
57e875f
 
 
 
 
a3e77a9
9e52285
 
359ee61
 
 
9e52285
 
 
 
 
 
 
 
 
 
 
 
 
 
359ee61
 
6b959b3
9e52285
 
 
359ee61
 
 
9e52285
 
 
 
 
 
359ee61
 
6b959b3
9e52285
 
 
359ee61
 
 
1301478
 
 
 
 
 
 
 
359ee61
 
6b959b3
9e52285
 
 
57e875f
 
 
 
 
54de00c
 
 
 
 
 
57e875f
 
 
54de00c
57e875f
 
 
 
 
 
 
 
 
 
 
 
 
6b959b3
9e52285
60c9768
 
359ee61
 
 
 
 
 
 
 
 
 
60c9768
 
 
359ee61
 
 
 
 
 
 
 
 
 
60c9768
 
 
359ee61
 
 
 
 
 
60c9768
9e52285
9adc91d
6b959b3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57e875f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1301478
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54de00c
 
 
 
 
 
 
f3f5b2d
 
54de00c
 
 
 
 
 
 
 
f3f5b2d
 
 
 
 
 
54de00c
 
 
 
c2003d2
 
54de00c
 
 
 
 
 
a3e77a9
9e52285
 
 
 
 
 
 
 
 
 
 
 
57e875f
 
9e52285
 
 
 
 
 
 
 
 
9adc91d
60c9768
 
 
1301478
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
package models

import (
	"time"

	"github.com/lib/pq"
	uuid "github.com/satori/go.uuid"
)

type Account struct {
	Id                uint       `gorm:"primaryKey" json:"id"`
	UUID              uuid.UUID  `gorm:"type:uuid" json:"uuid" `
	Email             string     `gorm:"uniqueIndex" json:"email"`
	Password          string     `json:"password"`
	IsEmailVerified   bool       `json:"is_email_verified"`
	IsDetailCompleted bool       `json:"is_detail_completed"`
	CreatedAt         time.Time  `json:"created_at"`
	DeletedAt         *time.Time `json:"deleted_at" gorm:"default:null"`
}

type AccountDetails struct {
	ID            uint64     `gorm:"column:id;primaryKey;autoIncrement" json:"id" counter:"skip"`
	AccountID     uint       `gorm:"column:account_id;not null;unique" json:"account_id" counter:"skip"`
	InitialName   string     `gorm:"column:initial_name;not null" json:"initial_name"`
	FullName      *string    `gorm:"column:full_name" json:"full_name"`
	DateOfBirth   *time.Time `gorm:"column:date_of_birth" json:"date_of_birth"`
	PlaceOfBirth  *string    `gorm:"column:place_of_birth" json:"place_of_birth"`
	Domicile      *string    `gorm:"column:domicile" json:"domicile"`
	LastJob       *string    `gorm:"column:last_job" json:"last_job"`
	Gender        *string    `gorm:"column:gender" json:"gender"`
	LastEducation *string    `gorm:"column:last_education" json:"last_education"`
	MaritalStatus *string    `gorm:"column:marital_status" json:"marital_status"`
	Avatar        *string    `gorm:"column:avatar" json:"avatar" counter:"skip"`
	PhoneNumber   *string    `gorm:"column:phone_number" json:"phone_number"`
	CreatedAt     time.Time  `gorm:"column:created_at;autoCreateTime" json:"created_at" counter:"skip"`
	UpdatedAt     time.Time  `gorm:"column:updated_at;autoUpdateTime" json:"updated_at" counter:"skip"`
	FieldCounter
}

type EmailVerification struct {
	ID        int64     `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
	AccountID int64     `gorm:"column:account_id;not null" json:"account_id"`
	Account   *Account  `gorm:"foreignKey:AccountID;constraint:OnDelete:CASCADE" json:"account,omitempty"`
	UUID      uuid.UUID `gorm:"type:uuid" json:"uuid" `
	Token     int64     `json:"token"`
	ExpiredAt time.Time `json:"expired_at"`
	IsExpired bool      `json:"is_expired"`
	CreatedAt time.Time `gorm:"column:created_at;autoCreateTime" json:"created_at"`
	UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime" json:"updated_at"`
}

type ExternalAuth struct {
	ID            uint      `gorm:"primaryKey" json:"id"`
	UUID          uuid.UUID `gorm:"type:uuid" json:"uuid" `
	OauthID       string    `json:"oauth_id"`
	AccountID     uint      `json:"account_id"`
	OauthProvider string    `json:"oauth_provider"`
}

type FCM struct {
	ID        uint   `gorm:"primaryKey" json:"id"`
	AccountID uint   `json:"account_id"`
	FCMToken  string `json:"fcm_token"`
}

type ForgotPassword struct {
	ID        uint      `gorm:"primaryKey" json:"id"`
	UUID      uuid.UUID `gorm:"type:uuid" json:"uuid" `
	Token     uint      `json:"token"`
	AccountID uint      `json:"account_id"`
	IsExpired bool      `json:"is_expired"`
	CreatedAt time.Time `json:"created_at"`
	ExpiredAt time.Time `json:"expired_at"`
}

type (
	Academy struct {
		ID          int64     `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
		Title       string    `gorm:"column:title" json:"title"`
		Slug        string    `gorm:"column:slug;uniqueIndex" json:"slug"`
		Description string    `gorm:"column:description" json:"description"`
		Order       uint      `gorm:"column:order" json:"order"`
		Image       *string   `gorm:"column:image" json:"image"`
		CreatedAt   time.Time `gorm:"column:created_at;autoCreateTime" json:"created_at"`
		UpdatedAt   time.Time `gorm:"column:updated_at;autoUpdateTime" json:"updated_at"`
	}

	AcademyMaterial struct {
		ID        int64     `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
		AcademyID int64     `gorm:"column:academy_id;not null" json:"academy_id"`
		Academy   *Academy  `gorm:"foreignKey:AcademyID;constraint:OnDelete:CASCADE" json:"academy,omitempty"`
		Title     string    `gorm:"column:title" json:"title"`
		Slug      string    `gorm:"column:slug;uniqueIndex" json:"slug"`
		Content   string    `gorm:"column:content" json:"content"`
		Order     uint      `gorm:"column:order" json:"order"`
		CreatedAt time.Time `gorm:"column:created_at;autoCreateTime" json:"created_at"`
		UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime" json:"updated_at"`
	}

	AcademyMaterialProgress struct {
		AccountID         int64            `gorm:"primaryKey;column:account_id" json:"account_id" counter:"skip"`
		Account           *Account         `gorm:"foreignKey:AccountID;constraint:OnDelete:CASCADE" json:"account,omitempty" counter:"skip"`
		AcademyMaterialID int64            `gorm:"primaryKey;column:academy_material_id" json:"academy_material_id"`
		AcademyMaterial   *AcademyMaterial `gorm:"foreignKey:AcademyMaterialID;constraint:OnDelete:CASCADE" json:"academy_material,omitempty"`
		CreatedAt         time.Time        `gorm:"column:created_at;autoCreateTime" json:"created_at"`
		UpdatedAt         time.Time        `gorm:"column:updated_at;autoUpdateTime" json:"updated_at"`
	}
)

type OptionCategory struct {
	ID           int64          `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
	OptionName   string         `json:"option_name"`
	OptionSlug   string         `json:"option_slug" gorm:"uniqueIndex"`
	OptionValues []OptionValues `gorm:"foreignKey:OptionCategoryID" json:"-"`
}

type OptionValues struct {
	ID               int64  `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
	OptionCategoryID int64  `json:"option_category_id"`
	OptionValue      string `json:"option_value"`
}

type RegionProvince struct {
	ID   uint   `json:"id"`
	Name string `json:"name"`
	Code string `json:"code"`
}

type RegionCity struct {
	ID         uint   `json:"id"`
	Type       string `json:"type"`
	Name       string `json:"name"`
	Code       string `json:"code"`
	FullCode   string `json:"full_code"`
	ProvinceID uint   `json:"province_id"`
}

type (
	Quiz struct {
		ID           int64     `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
		AcademyID    int64     `gorm:"column:academy_id;not null" json:"academy_id"`
		Academy      *Academy  `gorm:"foreignKey:AcademyID;constraint:OnDelete:CASCADE" json:"academy,omitempty"`
		Slug         string    `gorm:"column:slug;uniqueIndex" json:"slug" `
		Title        string    `gorm:"column:title" json:"title"`
		Description  string    `gorm:"column:description" json:"description"`
		AttemptLimit int64     `gorm:"column:attempt_limit" json:"attempt_limit"`
		TimeLimit    int64     `gorm:"column:time_limit" json:"time_limit"`
		MinScore     int64     `gorm:"column:min_score" json:"min_score"`
		CreatedAt    time.Time `gorm:"column:created_at;autoCreateTime" json:"created_at"`
		UpdatedAt    time.Time `gorm:"column:updated_at;autoUpdateTime" json:"updated_at"`
	}

	Question struct {
		ID        int64     `gorm:"column:id;primaryKey;autoIncrement"  json:"id"`
		QuizID    int64     `gorm:"column:quiz_id;not null" json:"quiz_id"`
		Quiz      *Quiz     `gorm:"foreignKey:QuizID;constraint:OnDelete:CASCADE" json:"quiz,omitempty"`
		Content   string    `gorm:"column:content" json:"content"`
		Order     int       `gorm:"column:order" json:"order"`
		Review    string    `gorm:"column:review" json:"review"`
		CreatedAt time.Time `gorm:"column:created_at;autoCreateTime" json:"created_at"`
		UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime" json:"updated_at"`
	}

	Answer struct {
		ID         int64     `gorm:"column:id;primaryKey;autoIncrement"  json:"id"`
		QuestionID int64     `gorm:"column:question_id;not null" json:"question_id"`
		Question   *Question `gorm:"foreignKey:QuestionID;constraint:OnDelete:CASCADE" json:"question,omitempty"`
		Content    string    `gorm:"column:content" json:"content"`
		IsCorrect  bool      `gorm:"column:is_correct" json:"is_correct"`
		CreatedAt  time.Time `gorm:"column:created_at;autoCreateTime" json:"created_at"`
		UpdatedAt  time.Time `gorm:"column:updated_at;autoUpdateTime" json:"updated_at"`
	}

	QuizAttempt struct {
		ID                 int64      `gorm:"column:id;primaryKey;autoIncrement"  json:"id"`
		AccountID          int64      `gorm:"column:account_id;not null" json:"account_id"`
		Account            *Account   `gorm:"foreignKey:AccountID;constraint:OnDelete:CASCADE" json:"account,omitempty"`
		AcademyID          int64      `gorm:"column:academy_id;not null" json:"academy_id"`
		Academy            *Academy   `gorm:"foreignKey:AcademyID;constraint:OnDelete:CASCADE" json:"academy,omitempty"`
		QuizID             int64      `gorm:"column:quiz_id;not null" json:"quiz_id"`
		Quiz               *Quiz      `gorm:"foreignKey:QuizID;constraint:OnDelete:CASCADE" json:"-"`
		StartedAt          time.Time  `gorm:"column:started_at;autoCreateTime" json:"started_at"`
		DueAt              time.Time  `gorm:"column:due_at" json:"due_at"`
		FinishedAt         *time.Time `gorm:"column:finished_at" json:"finished_at"`
		TotalQuestions     int64      `gorm:"column:total_questions;not null" json:"total_questions"`
		TotalCorrectAnswer int64      `gorm:"column:total_correct_answer;not null" json:"total_correct_answer"`
		TotalWrongAnswer   int64      `gorm:"column:total_wrong_answer;not null" json:"total_wrong_answer"`
		Score              float64    `gorm:"column:score" json:"score"`
		IsPassed           bool       `gorm:"column:is_passed" json:"is_passed"`
		CreatedAt          time.Time  `gorm:"column:created_at;autoCreateTime" json:"created_at"`
		UpdatedAt          time.Time  `gorm:"column:updated_at;autoUpdateTime" json:"updated_at"`
	}

	UserAnswer struct {
		ID            int64        `gorm:"column:id;primaryKey;autoIncrement"  json:"id"`
		QuizAttemptID int64        `gorm:"column:quiz_attempt_id;not null" json:"quiz_attempt_id"`
		QuizAttempt   *QuizAttempt `gorm:"foreignKey:QuizAttemptID;constraint:OnDelete:CASCADE" json:"quiz_attempt,omitempty"`
		QuestionID    int64        `gorm:"column:question_id;not null" json:"question_id"`
		Question      *Question    `gorm:"foreignKey:QuestionID;constraint:OnDelete:CASCADE" json:"question,omitempty"`
		AnswerID      *int64       `gorm:"column:selected_answer_id" json:"selected_answer"`
		Answer        *Answer      `gorm:"foreignKey:AnswerID;constraint:OnDelete:CASCADE" json:"answer,omitempty"`
		IsDoubt       bool         `gorm:"column:is_doubt" json:"is_doubt"`
		IsCorrect     bool         `gorm:"column:is_correct" json:"is_correct"`
		CreatedAt     time.Time    `gorm:"column:created_at;autoCreateTime" json:"created_at"`
		UpdatedAt     time.Time    `gorm:"column:updated_at;autoUpdateTime" json:"updated_at"`
	}
)

type (
	PersonalityAndPreferenceCV struct {
		ID                    int64     `gorm:"column:id;primaryKey;autoIncrement" json:"id" counter:"skip"`
		AccountID             int64     `gorm:"column:account_id;not null;unique" json:"account_id" counter:"skip"`
		Account               *Account  `gorm:"foreignKey:AccountID;constraint:OnDelete:CASCADE" json:"account,omitempty" counter:"skip"`
		PositiveTraits        *string   `gorm:"column:positive_traits" json:"positive_traits"`                   // sifat positif
		NegativeTraits        *string   `gorm:"column:negative_traits" json:"negative_traits"`                   // sifat negatif
		Hobbies               *string   `gorm:"column:hobbies" json:"hobbies"`                                   // hobi
		LifeGoals             *string   `gorm:"column:life_goals" json:"life_goals"`                             // target hidup
		DailyActivities       *string   `gorm:"column:daily_activities" json:"daily_activities"`                 // kegiatan sehari-hari
		LeisureActivities     *string   `gorm:"column:leisure_activities" json:"leisure_activities"`             // kegiatan waktu luang
		Likes                 *string   `gorm:"column:likes" json:"likes"`                                       // hal yang disukai
		Dislikes              *string   `gorm:"column:dislikes" json:"dislikes"`                                 // hal yang tidak disukai
		StressHandling        *string   `gorm:"column:stress_handling" json:"stress_handling"`                   // cara mengatasi stres
		AngerTriggers         *string   `gorm:"column:anger_triggers" json:"anger_triggers"`                     // pemicu amarah
		FavoriteFoodAndDrinks *string   `gorm:"column:favorite_food_and_drinks" json:"favorite_food_and_drinks"` // makanan dan minuman favorit
		CanCook               *bool     `gorm:"column:can_cook" json:"can_cook"`                                 // bisa memasak
		TypesOfDishesCooked   *string   `gorm:"column:types_of_dishes_cooked" json:"types_of_dishes_cooked"`     // jenis masakan yang bisa dimasak
		MonthlyExpenses       *string   `gorm:"column:monthly_expenses" json:"monthly_expenses"`                 // pengeluaran per bulan
		CreatedAt             time.Time `gorm:"column:created_at;autoCreateTime" json:"created_at" counter:"skip"`
		UpdatedAt             time.Time `gorm:"column:updated_at;autoUpdateTime" json:"updated_at" counter:"skip"`
		FieldCounter
	}

	FamilyMemberCV struct {
		ID            int64     `gorm:"column:id;primaryKey;autoIncrement" json:"id" counter:"skip"`
		AccountID     int64     `gorm:"column:account_id;not null" json:"account_id" counter:"skip"`
		Account       *Account  `gorm:"foreignKey:AccountID;constraint:OnDelete:CASCADE" json:"account,omitempty" counter:"skip"`
		Role          *string   `gorm:"column:role" json:"role"`                     // Peran dalam keluarga
		Status        *string   `gorm:"column:status" json:"status"`                 // Status (Hidup, Wafat)
		Religion      *string   `gorm:"column:religion" json:"religion"`             // Agama
		Job           *string   `gorm:"column:job" json:"job"`                       // Pekerjaan
		LastEducation *string   `gorm:"column:last_education" json:"last_education"` // Pendidikan terakhir
		Age           *int      `gorm:"column:age" json:"age"`                       // Usia
		CreatedAt     time.Time `gorm:"column:created_at;autoCreateTime" json:"created_at" counter:"skip"`
		UpdatedAt     time.Time `gorm:"column:updated_at;autoUpdateTime" json:"updated_at" counter:"skip"`
		FieldCounter
	}

	PhysicalAndHealthCV struct {
		ID               int64           `gorm:"column:id;primaryKey;autoIncrement" json:"id" counter:"skip"`
		AccountID        int64           `gorm:"column:account_id;not null;unique" json:"account_id" counter:"skip"`
		Account          *Account        `gorm:"foreignKey:AccountID;constraint:OnDelete:CASCADE" json:"account,omitempty" counter:"skip"`
		HeightInCm       *int            `gorm:"column:height_cm" json:"height_cm"`                                 // Tinggi badan dalam satuan sentimeter
		WeightInKg       *int            `gorm:"column:weight_kg" json:"weight_kg"`                                 // Berat badan dalam satuan kilogram
		BodyShape        *string         `gorm:"column:body_shape" json:"body_shape"`                               // Bentuk tubuh
		SkinColor        *string         `gorm:"column:skin_color" json:"skin_color"`                               // Warna kulit
		HairType         *string         `gorm:"column:hair_type" json:"hair_type"`                                 // Tipe rambut
		MedicalHistory   *pq.StringArray `gorm:"column:medical_history;type:varchar(255)[]" json:"medical_history"` // Riwayat penyakit
		PhysicalDisorder *string         `gorm:"column:physical_disorder" json:"physical_disorder"`                 // Cacat fisik
		PhysicalTraits   *string         `gorm:"column:physical_traits" json:"physical_traits"`                     // Ciri khas fisik
		CreatedAt        time.Time       `gorm:"column:created_at;autoCreateTime" json:"created_at" counter:"skip"` // Waktu data dibuat
		UpdatedAt        time.Time       `gorm:"column:updated_at;autoUpdateTime" json:"updated_at" counter:"skip"` // Waktu data terakhir diperbarui
		FieldCounter
	}

	WorshipAndReligiousUnderstandingCV struct {
		ID        int64    `gorm:"column:id;primaryKey;autoIncrement" json:"id" counter:"skip"`
		AccountID int64    `gorm:"column:account_id;not null;unique" json:"account_id" counter:"skip"`
		Account   *Account `gorm:"foreignKey:AccountID;constraint:OnDelete:CASCADE" json:"account,omitempty" counter:"skip"`

		// Data ibadah
		ObligatoryPrayer              *string         `gorm:"column:obligatory_prayer" json:"obligatory_prayer"`                               // sholat_wajib_5_waktu
		CongregationalPrayer          *string         `gorm:"column:congregational_prayer" json:"congregational_prayer"`                       // sholat_berjamaah_di_masjid
		TahajjudPrayer                *string         `gorm:"column:tahajjud_prayer" json:"tahajjud_prayer"`                                   // sholat_tahajud
		DhuhaPrayer                   *string         `gorm:"column:dhuha_prayer" json:"dhuha_prayer"`                                         // sholat_dhuha
		DaudFasting                   *string         `gorm:"column:daud_fasting" json:"daud_fasting"`                                         // puasa_daud
		AyyamulBidhFasting            *string         `gorm:"column:ayyamul_bidh_fasting" json:"ayyamul_bidh_fasting"`                         // puasa_ayyamul_bidh
		QuranReadingAbility           *string         `gorm:"column:quran_reading_ability" json:"quran_reading_ability"`                       // kemampuan_baca_alquran
		QuranMemorization             *string         `gorm:"column:quran_memorization" json:"quran_memorization"`                             // hafalan_alquran
		WeeklyReligiousStudyFrequency *string         `gorm:"column:weekly_religious_study_frequency" json:"weekly_religious_study_frequency"` // jumlah kajian yang diikuti dalam seminggu
		HajjOrUmrah                   *pq.StringArray `gorm:"column:hajj_or_umrah;type:varchar(255)[]" json:"hajj_or_umrah"`                   // ibadah_haji_umroh

		// Data Pemahaman Agama
		ListeningToMusic           *bool   `gorm:"column:listening_to_music" json:"listening_to_music"`                         // mendengarkan_musik
		OpinionOnIkhtilat          *string `gorm:"column:opinion_on_ikhtilat" json:"opinion_on_ikhtilat"`                       // pendapat_ikhtilat
		OpinionOnTouchingNonMahram *string `gorm:"column:opinion_on_touching_non_mahram" json:"opinion_on_touching_non_mahram"` // pendapat_menyentuh_non_mahram
		OpinionOnVeil              *string `gorm:"column:opinion_on_veil" json:"opinion_on_veil"`                               // pendapat_tentang_cadar
		OpinionOnBeard             *string `gorm:"column:opinion_on_beard" json:"opinion_on_beard"`                             // pendapat_tentang_jenggot_pada_laki_laki
		OpinionOnPantsAboveAnkle   *string `gorm:"column:opinion_on_pants_above_ankle" json:"opinion_on_pants_above_ankle"`     // pendapat_tentang_celana_di_atas_mata_kaki
		WeeklyReligiousStudies     *string `gorm:"column:weekly_religious_studies" json:"weekly_religious_studies"`             // kajian_yang_diikuti_dalam_sepekan
		FollowedUstadz             *string `gorm:"column:followed_ustadz" json:"followed_ustadz"`                               // ustadz_yang_diikuti

		CreatedAt time.Time `gorm:"column:created_at;autoCreateTime" json:"created_at" counter:"skip"`
		UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime" json:"updated_at" counter:"skip"`
		FieldCounter
	}

	EducationCV struct {
		ID                 int64     `gorm:"column:id;primaryKey;autoIncrement" json:"id" counter:"skip"`                              // id
		AccountID          int64     `gorm:"column:account_id;not null" json:"account_id" counter:"skip"`                              // id akun
		Account            *Account  `gorm:"foreignKey:AccountID;constraint:OnDelete:CASCADE" json:"account,omitempty" counter:"skip"` // relasi ke akun
		LastEducation      *string   `gorm:"column:last_education" json:"last_education"`                                              // pendidikan terakhir
		EducationInstitute *string   `gorm:"column:education_institute" json:"education_institute"`                                    // institusi pendidikan
		EducationMajor     *string   `gorm:"column:education_major" json:"education_major"`                                            // jurusan pendidikan
		YearStart          *int      `gorm:"column:year_start" json:"year_start"`                                                      // tahun masuk
		YearGraduate       *int      `gorm:"column:year_graduate" json:"year_graduate"`                                                // tahun lulus
		CreatedAt          time.Time `gorm:"column:created_at;autoCreateTime" json:"created_at" counter:"skip"`                        // tanggal dibuat
		UpdatedAt          time.Time `gorm:"column:updated_at;autoUpdateTime" json:"updated_at" counter:"skip"`                        // tanggal diperbarui
	}

	JobCV struct {
		ID                 int64           `gorm:"column:id;primaryKey;autoIncrement" json:"id" counter:"skip"`                              // id
		AccountID          int64           `gorm:"column:account_id;not null" json:"account_id" counter:"skip"`                              // id akun
		Account            *Account        `gorm:"foreignKey:AccountID;constraint:OnDelete:CASCADE" json:"account,omitempty" counter:"skip"` // relasi ke akun
		InstitutionName    *string         `gorm:"column:institution_name" json:"institution_name"`                                          // nama instansi
		CurrentJob         *string         `gorm:"column:current_job" json:"current_job"`                                                    // pekerjaan saat ini
		YearStartedWorking *int            `gorm:"column:year_started_working" json:"year_started_working"`                                  // tahun mulai bekerja
		MonthlyIncome      *string         `gorm:"column:monthly_income" json:"monthly_income"`                                              // penghasilan per bulan
		IncomeSources      *pq.StringArray `gorm:"column:income_sources;type:varchar(255)[]" json:"income_sources"`                          // sumber penghasilan
		CreatedAt          time.Time       `gorm:"column:created_at;autoCreateTime" json:"created_at" counter:"skip"`                        // tanggal dibuat
		UpdatedAt          time.Time       `gorm:"column:updated_at;autoUpdateTime" json:"updated_at" counter:"skip"`                        // tanggal diperbarui
	}

	AchievementCV struct {
		ID                 int64     `gorm:"column:id;primaryKey;autoIncrement" json:"id" counter:"skip"`                              // id
		AccountID          int64     `gorm:"column:account_id;not null" json:"account_id" counter:"skip"`                              // id akun
		Account            *Account  `gorm:"foreignKey:AccountID;constraint:OnDelete:CASCADE" json:"account,omitempty" counter:"skip"` // relasi ke akun
		AchievementOrAward *string   `gorm:"column:achievement_or_award" json:"achievement_or_award"`                                  // prestasi atau penghargaan
		CreatedAt          time.Time `gorm:"column:created_at;autoCreateTime" json:"created_at" counter:"skip"`                        // tanggal dibuat
		UpdatedAt          time.Time `gorm:"column:updated_at;autoUpdateTime" json:"updated_at" counter:"skip"`                        // tanggal diperbarui
	}
)

func (a AccountDetails) TotalFields() int {
	return a.FieldCounter.TotalFields(a)
}

func (a AccountDetails) GetFilledFields() []string {
	return a.FieldCounter.GetFilledFields(a)
}

func (p PersonalityAndPreferenceCV) TotalFields() int {
	return p.FieldCounter.TotalFields(p)
}

func (p PersonalityAndPreferenceCV) GetFilledFields() []string {
	return p.FieldCounter.GetFilledFields(p)
}

func (p PhysicalAndHealthCV) TotalFields() int {
	return p.FieldCounter.TotalFields(p)
}

func (p PhysicalAndHealthCV) GetFilledFields() []string {
	return p.FieldCounter.GetFilledFields(p)
}

func (w WorshipAndReligiousUnderstandingCV) TotalFields() int {
	return w.FieldCounter.TotalFields(w)
}

func (w WorshipAndReligiousUnderstandingCV) GetFilledFields() []string {
	return w.FieldCounter.GetFilledFields(w)
}

var WorshipFields = []string{
	"ObligatoryPrayer",
	"CongregationalPrayer",
	"TahajjudPrayer",
	"DhuhaPrayer",
	"DaudFasting",
	"AyyamulBidhFasting",
	"QuranReadingAbility",
	"QuranMemorization",
	"WeeklyReligiousStudyFrequency",
	"HajjOrUmrah",
}

var ReligiousUnderstandingFields = []string{
	"ListeningToMusic",
	"OpinionOnIkhtilat",
	"OpinionOnTouchingNonMahram",
	"OpinionOnVeil",
	"OpinionOnBeard",
	"OpinionOnPantsAboveAnkle",
	"WeeklyReligiousStudies",
	"FollowedUstadz",
}

func (w WorshipAndReligiousUnderstandingCV) GetTotalFieldsWorship() int {
	return w.FieldCounter.CountFieldsByNames(w, WorshipFields)
}

func (w WorshipAndReligiousUnderstandingCV) GetTotalFieldsReligiousUnderstanding() int {
	return w.FieldCounter.CountFieldsByNames(w, ReligiousUnderstandingFields)
}

func (w WorshipAndReligiousUnderstandingCV) GetFilledFieldsWorship() []string {
	return w.FieldCounter.GetFilledFieldsByNames(w, WorshipFields)
}

func (w WorshipAndReligiousUnderstandingCV) GetFilledFieldsReligiousUnderstanding() []string {
	return w.FieldCounter.GetFilledFieldsByNames(w, ReligiousUnderstandingFields)
}

type (
	MarriageReadinessProfile struct {
		ID        int64    `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
		AccountID int64    `gorm:"column:account_id;not null;unique" json:"account_id"`
		Account   *Account `gorm:"foreignKey:AccountID;constraint:OnDelete:CASCADE" json:"account,omitempty"`

		// Visi Misi Rumah Tangga
		MarriageVision     *string `gorm:"column:marriage_vision" json:"marriage_vision"`         // Apa visi dan tujuan utama kamu dalam membangun rumah tangga?
		LivingPlan         *string `gorm:"column:living_plan" json:"living_plan"`                 // Setelah menikah, kamu berencana tinggal di mana?
		SpouseRoles        *string `gorm:"column:spouse_roles" json:"spouse_roles"`               // Menurutmu, apa peran utama suami dan istri dalam rumah tangga?
		SpouseRights       *string `gorm:"column:spouse_rights" json:"spouse_rights"`             // Apa saja hak suami dan istri menurutmu?
		ConflictResolution *string `gorm:"column:conflict_resolution" json:"conflict_resolution"` // Jika terjadi konflik, bagaimana kamu menyikapinya?
		ParentingStyle     *string `gorm:"column:parenting_style" json:"parenting_style"`         // Setelah punya anak, pola pengasuhan seperti apa yang kamu inginkan?

		// Konsep Acara Pernikahan
		ReadyToMarryDuration *string `gorm:"column:ready_to_marry_duration" json:"ready_to_marry_duration"` // Setelah taaruf dimulai, berapa lama kamu butuh untuk siap menikah?
		WeddingConcept       *string `gorm:"column:wedding_concept" json:"wedding_concept"`                 // Seperti apa konsep pernikahan yang kamu harapkan?
		WeddingFunding       *string `gorm:"column:wedding_funding" json:"wedding_funding"`                 // Apakah kamu sudah mempersiapkan dana pernikahan? Dari mana sumbernya?

		// Karir Kedepannya
		CareerAfterMarriage *string `gorm:"column:career_after_marriage" json:"career_after_marriage"` // Apakah kamu ingin tetap bekerja setelah menikah?
		TimeManagement      *string `gorm:"column:time_management" json:"time_management"`             // Bagaimana kamu membagi waktu antara keluarga, ibadah, dan pekerjaan?
		CareerGoals         *string `gorm:"column:career_goals" json:"career_goals"`                   // Apa impian karier atau cita-cita kamu dalam 5 sampai 10 tahun ke depan?
		SelfDevelopment     *string `gorm:"column:self_development" json:"self_development"`           // Apa usaha kamu untuk terus mengembangkan diri dan skill?

		// Pendidikan Keluarga
		DelayChildren          *string `gorm:"column:delay_children" json:"delay_children"`                     // Apakah kamu berencana menunda memiliki anak?
		ChildEducationPlan     *string `gorm:"column:child_education_plan" json:"child_education_plan"`         // Apakah kamu sudah punya rencana pendidikan anak?
		ReligiousEmotionalBond *string `gorm:"column:religious_emotional_bond" json:"religious_emotional_bond"` // Bagaimana cara menjaga nilai agama & kedekatan emosional dengan anak?
		ParentingChallenges    *string `gorm:"column:parenting_challenges" json:"parenting_challenges"`         // Saat menghadapi tantangan pengasuhan, bagaimana kamu menyikapinya?

		// Finansial Keluarga
		MonthlyFinance       *string `gorm:"column:monthly_finance" json:"monthly_finance"`             // Bagaimana kamu mengelola keuangan bulanan?
		FamilyResponsibility *string `gorm:"column:family_responsibility" json:"family_responsibility"` // Apakah kamu masih punya tanggungan keluarga setelah menikah?
		DebtStatus           *string `gorm:"column:debt_status" json:"debt_status"`                     // Apakah kamu punya cicilan/utang setelah menikah?
		FinanceSharing       *string `gorm:"column:finance_sharing" json:"finance_sharing"`             // Setelah menikah, bagaimana pembagian tanggung jawab keuangan?
		IncomeGapView        *string `gorm:"column:income_gap_view" json:"income_gap_view"`             // Pandangan kamu jika istri berpenghasilan lebih besar dari suami?

		// Keputusan dan Komunikasi
		DecisionMaking     *string `gorm:"column:decision_making" json:"decision_making"`         // Dalam mengambil keputusan, kamu lebih mempertimbangkan pasangan atau sendiri?
		GrowthTogether     *string `gorm:"column:growth_together" json:"growth_together"`         // Apakah kamu siap berjuang bersama pasangan? Apa saja yang ingin diperjuangkan?
		ParentIntervention *string `gorm:"column:parent_intervention" json:"parent_intervention"` // Sejauh mana orang tua/mertua boleh ikut campur dalam rumah tangga?
		HabitResponse      *string `gorm:"column:habit_response" json:"habit_response"`           // Bagaimana kamu menyikapi kebiasaan pasangan yang kurang kamu sukai?

		CreatedAt time.Time `gorm:"column:created_at;autoCreateTime" json:"created_at"`
		UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime" json:"updated_at"`
	}
)

type (
	PartnerCriteria struct {
		ID        int64    `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
		AccountID int64    `gorm:"column:account_id;not null;unique" json:"account_id"`
		Account   *Account `gorm:"foreignKey:AccountID;constraint:OnDelete:CASCADE" json:"account,omitempty"`

		// Kriteria Umum
		ExpecteMinAgeLimit                   *int            `gorm:"column:expected_min_age_limit" json:"expected_min_age_limit"`                                     // batas usia pasangan yang diharapkan
		ExpecteMaxAgeLimit                   *int            `gorm:"column:expected_max_age_limit" json:"expected_max_age_limit"`                                     // batas usia pasangan yang diharapkan
		ExpectedDomicile                     *string         `gorm:"column:expected_domicile" json:"expected_domicile"`                                               // domisili pasangan yang diharapkan
		AcceptedMaritalStatus                *pq.StringArray `gorm:"column:accepted_marital_status;type:varchar(255)[]" json:"accepted_marital_status"`               // status pernikahan yang diterima
		PartnerFamilyReligion                *string         `gorm:"column:partner_family_religion" json:"partner_family_religion"`                                   // agama yang dianut keluarga pasangan
		PartnerWeeklyReligiousStudyFrequency *string         `gorm:"column:partner_weekly_religious_study_frequency" json:"partner_weekly_religious_study_frequency"` // rata-rata jumlah kajian yang diikuti pasangan per pekan
		PartnerMonthlySpendingEstimate       *string         `gorm:"column:partner_monthly_spending_estimate" json:"partner_monthly_spending_estimate"`               // estimasi pengeluaran pasangan per bulan
		PartnerCanCook                       *string         `gorm:"column:partner_can_cook" json:"partner_can_cook"`                                                 // apakah pasangan diharapkan bisa memasak

		// Kriteria Fisik
		ExpectedBodyShapes     *pq.StringArray `gorm:"column:expected_body_shapes;type:varchar(255)[]" json:"expected_body_shapes"`       // bentuk tubuh yang diharapkan
		ExpectedSkinColors     *pq.StringArray `gorm:"column:expected_skin_colors;type:varchar(255)[]" json:"expected_skin_colors"`       // warna kulit yang diharapkan
		ExpectedHairTypes      *pq.StringArray `gorm:"column:expected_hair_types;type:varchar(255)[]" json:"expected_hair_types"`         // tipe rambut yang diharapkan
		ExpectedHairThickness  *pq.StringArray `gorm:"column:expected_hair_thickness;type:varchar(255)[]" json:"expected_hair_thickness"` // jenis rambut yang diharapkan
		ExpectedMinHeightLimit *int            `gorm:"column:expected_min_height_limit" json:"expected_min_height_limit"`                 // tinggi badan yang diharapkan
		ExpectedMaxHeightLimit *int            `gorm:"column:expected_max_height_limit" json:"expected_max_height_limit"`                 // tinggi badan yang diharapkan

		// Pendidikan & Pekerjaan
		ExpectedPartnerIncome *string         `gorm:"column:expected_partner_income" json:"expected_partner_income"`                     // penghasilan pasangan per bulan yang diharapkan
		ExpectedLastEducation *pq.StringArray `gorm:"column:expected_last_education;type:varchar(255)[]" json:"expected_last_education"` // pendidikan terakhir yang diharapkan
		// ExpectedIncomeSources *pq.StringArray `gorm:"column:expected_income_sources;type:varchar(255)[]" json:"expected_income_sources"` // sumber penghasilan pasangan
		// ExpectedJobType       *string         `gorm:"column:expected_job_type" json:"expected_job_type"`                                 // jenis pekerjaan pasangan yang diharapkan

		CreatedAt time.Time `gorm:"column:created_at;autoCreateTime" json:"created_at"`
		UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime" json:"updated_at"`
	}
)

// Gorm table name settings
func (Account) TableName() string                    { return "account" }
func (AccountDetails) TableName() string             { return "account_details" }
func (EmailVerification) TableName() string          { return "email_verifications" }
func (ExternalAuth) TableName() string               { return "extern_auth" }
func (FCM) TableName() string                        { return "fcm" }
func (ForgotPassword) TableName() string             { return "forgot_password" }
func (Academy) TableName() string                    { return "academy" }
func (AcademyMaterial) TableName() string            { return "academy_materials" }
func (AcademyMaterialProgress) TableName() string    { return "academy_materials_progress" }
func (RegionProvince) TableName() string             { return "region_provinces" }
func (RegionCity) TableName() string                 { return "region_cities" }
func (Quiz) TableName() string                       { return "quizzes" }
func (Question) TableName() string                   { return "questions" }
func (Answer) TableName() string                     { return "answers" }
func (QuizAttempt) TableName() string                { return "quiz_attempts" }
func (UserAnswer) TableName() string                 { return "user_answers" }
func (OptionCategory) TableName() string             { return "option_categories" }
func (OptionValues) TableName() string               { return "option_values" }
func (PersonalityAndPreferenceCV) TableName() string { return "personality_and_preference_cv" }
func (FamilyMemberCV) TableName() string             { return "family_member_cv" }
func (PhysicalAndHealthCV) TableName() string        { return "physical_and_health_cv" }
func (WorshipAndReligiousUnderstandingCV) TableName() string {
	return "worship_and_religious_understanding_cv"
}
func (EducationCV) TableName() string   { return "education_cv" }
func (JobCV) TableName() string         { return "job_cv" }
func (AchievementCV) TableName() string { return "achievement_cv" }
func (MarriageReadinessProfile) TableName() string {
	return "marriage_readiness_profile"
}