Mhamdans17 commited on
Commit ·
4a28cd8
1
Parent(s): 97344b4
perf: completely fix N+1 query problem and select * in ListCompanies, ListBranches, and GetCurrentUser middleware
Browse files- controllers/auth_controller.go +1 -1
- controllers/company_controller.go +46 -9
- middleware/auth.go +1 -1
controllers/auth_controller.go
CHANGED
|
@@ -493,7 +493,7 @@ func ListKasir(c *gin.Context) {
|
|
| 493 |
owner := userVal.(*models.User)
|
| 494 |
|
| 495 |
var kasir []models.User
|
| 496 |
-
if err := config.DB.Preload("Branch").Where("company_id = ? AND role = ?", *owner.CompanyID, "kasir").Find(&kasir).Error; err != nil {
|
| 497 |
c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal mengambil data kasir"})
|
| 498 |
return
|
| 499 |
}
|
|
|
|
| 493 |
owner := userVal.(*models.User)
|
| 494 |
|
| 495 |
var kasir []models.User
|
| 496 |
+
if err := config.DB.Select("id, name, email, phone, role, company_id, branch_id, is_active, created_at").Preload("Branch").Where("company_id = ? AND role = ?", *owner.CompanyID, "kasir").Find(&kasir).Error; err != nil {
|
| 497 |
c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal mengambil data kasir"})
|
| 498 |
return
|
| 499 |
}
|
controllers/company_controller.go
CHANGED
|
@@ -76,7 +76,8 @@ func ListCompanies(c *gin.Context) {
|
|
| 76 |
skipStr := c.Query("skip")
|
| 77 |
searchQuery := c.Query("search")
|
| 78 |
|
| 79 |
-
query := config.DB.Model(&models.Company{})
|
|
|
|
| 80 |
|
| 81 |
if searchQuery != "" {
|
| 82 |
query = query.Where("name ILIKE ? OR email ILIKE ? OR phone ILIKE ? OR address ILIKE ?",
|
|
@@ -103,23 +104,59 @@ func ListCompanies(c *gin.Context) {
|
|
| 103 |
return
|
| 104 |
}
|
| 105 |
|
| 106 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
for _, comp := range companies {
|
| 108 |
-
|
| 109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
|
|
|
|
|
|
|
|
|
|
| 111 |
var ownerVerified *bool
|
| 112 |
var ownerName, ownerEmail, ownerPhone string
|
| 113 |
|
| 114 |
-
if
|
| 115 |
ownerName = owner.Name
|
| 116 |
ownerEmail = owner.Email
|
| 117 |
ownerPhone = owner.Phone
|
| 118 |
|
| 119 |
if owner.Phone != "" {
|
| 120 |
-
|
| 121 |
-
otpErr := config.DB.Where("phone_number = ? AND is_verified = ?", owner.Phone, true).First(&otp).Error
|
| 122 |
-
isVerified := otpErr == nil
|
| 123 |
ownerVerified = &isVerified
|
| 124 |
}
|
| 125 |
}
|
|
@@ -454,7 +491,7 @@ func ListBranches(c *gin.Context) {
|
|
| 454 |
owner := userVal.(*models.User)
|
| 455 |
|
| 456 |
var branches []models.Branch
|
| 457 |
-
if err := config.DB.Where("company_id = ?", *owner.CompanyID).Find(&branches).Error; err != nil {
|
| 458 |
c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal mengambil data cabang"})
|
| 459 |
return
|
| 460 |
}
|
|
|
|
| 76 |
skipStr := c.Query("skip")
|
| 77 |
searchQuery := c.Query("search")
|
| 78 |
|
| 79 |
+
query := config.DB.Model(&models.Company{}).
|
| 80 |
+
Select("id, name, bank_account_number, bank_name, address, email, phone, logo_url, is_active, fee_percentage, approved_at, created_at")
|
| 81 |
|
| 82 |
if searchQuery != "" {
|
| 83 |
query = query.Where("name ILIKE ? OR email ILIKE ? OR phone ILIKE ? OR address ILIKE ?",
|
|
|
|
| 104 |
return
|
| 105 |
}
|
| 106 |
|
| 107 |
+
if len(companies) == 0 {
|
| 108 |
+
c.JSON(http.StatusOK, []CompanyResponse{})
|
| 109 |
+
return
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
var companyIDs []uint
|
| 113 |
for _, comp := range companies {
|
| 114 |
+
companyIDs = append(companyIDs, comp.ID)
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
// Ambil semua owner user dalam 1 query (hanya kolom yang diperlukan)
|
| 118 |
+
var owners []models.User
|
| 119 |
+
config.DB.Select("id, name, email, phone, company_id").
|
| 120 |
+
Where("company_id IN ? AND role = ?", companyIDs, "owner").
|
| 121 |
+
Find(&owners)
|
| 122 |
+
|
| 123 |
+
// Map company_id -> owner
|
| 124 |
+
ownerMap := make(map[uint]models.User)
|
| 125 |
+
var ownerPhones []string
|
| 126 |
+
for _, o := range owners {
|
| 127 |
+
if o.CompanyID != nil {
|
| 128 |
+
ownerMap[*o.CompanyID] = o
|
| 129 |
+
if o.Phone != "" {
|
| 130 |
+
ownerPhones = append(ownerPhones, o.Phone)
|
| 131 |
+
}
|
| 132 |
+
}
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
// Ambil status verifikasi OTP semua owner dalam 1 query
|
| 136 |
+
otpMap := make(map[string]bool)
|
| 137 |
+
if len(ownerPhones) > 0 {
|
| 138 |
+
var otps []models.OTP
|
| 139 |
+
config.DB.Select("phone_number").
|
| 140 |
+
Where("phone_number IN ? AND is_verified = ?", ownerPhones, true).
|
| 141 |
+
Find(&otps)
|
| 142 |
+
for _, otp := range otps {
|
| 143 |
+
otpMap[otp.PhoneNumber] = true
|
| 144 |
+
}
|
| 145 |
+
}
|
| 146 |
|
| 147 |
+
resp := []CompanyResponse{}
|
| 148 |
+
for _, comp := range companies {
|
| 149 |
+
owner, hasOwner := ownerMap[comp.ID]
|
| 150 |
var ownerVerified *bool
|
| 151 |
var ownerName, ownerEmail, ownerPhone string
|
| 152 |
|
| 153 |
+
if hasOwner {
|
| 154 |
ownerName = owner.Name
|
| 155 |
ownerEmail = owner.Email
|
| 156 |
ownerPhone = owner.Phone
|
| 157 |
|
| 158 |
if owner.Phone != "" {
|
| 159 |
+
isVerified := otpMap[owner.Phone]
|
|
|
|
|
|
|
| 160 |
ownerVerified = &isVerified
|
| 161 |
}
|
| 162 |
}
|
|
|
|
| 491 |
owner := userVal.(*models.User)
|
| 492 |
|
| 493 |
var branches []models.Branch
|
| 494 |
+
if err := config.DB.Select("id, company_id, name, address, phone, is_active, created_at").Where("company_id = ?", *owner.CompanyID).Find(&branches).Error; err != nil {
|
| 495 |
c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal mengambil data cabang"})
|
| 496 |
return
|
| 497 |
}
|
middleware/auth.go
CHANGED
|
@@ -98,7 +98,7 @@ func GetCurrentUser() gin.HandlerFunc {
|
|
| 98 |
}
|
| 99 |
|
| 100 |
var user models.User
|
| 101 |
-
if err := config.DB.
|
| 102 |
c.JSON(http.StatusUnauthorized, gin.H{"detail": "User tidak ditemukan"})
|
| 103 |
c.Abort()
|
| 104 |
return
|
|
|
|
| 98 |
}
|
| 99 |
|
| 100 |
var user models.User
|
| 101 |
+
if err := config.DB.Select("id, name, email, phone, role, company_id, branch_id, is_active, created_at").First(&user, claims.Sub).Error; err != nil {
|
| 102 |
c.JSON(http.StatusUnauthorized, gin.H{"detail": "User tidak ditemukan"})
|
| 103 |
c.Abort()
|
| 104 |
return
|