Mhamdans17 commited on
Commit
fe79eec
·
1 Parent(s): 4e8a43c

fix: manual cascading deletes in company_controller and add public ip check endpoint

Browse files
Files changed (2) hide show
  1. controllers/company_controller.go +108 -3
  2. main.go +19 -0
controllers/company_controller.go CHANGED
@@ -380,7 +380,7 @@ func DeleteCompany(c *gin.Context) {
380
  }
381
  }()
382
 
383
- // Ambil semua user terkait company ini, lalu hapus record OTP mereka
384
  var users []models.User
385
  tx.Where("company_id = ?", companyID).Find(&users)
386
  for _, u := range users {
@@ -389,7 +389,56 @@ func DeleteCompany(c *gin.Context) {
389
  }
390
  }
391
 
392
- // Cascading deletes Company (users, branches, products, categories, dll)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
393
  if err := tx.Delete(&company).Error; err != nil {
394
  tx.Rollback()
395
  c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal menghapus data perusahaan"})
@@ -429,6 +478,7 @@ func RejectCompany(c *gin.Context) {
429
  }
430
  }()
431
 
 
432
  var users []models.User
433
  tx.Where("company_id = ?", companyID).Find(&users)
434
  for _, u := range users {
@@ -437,7 +487,62 @@ func RejectCompany(c *gin.Context) {
437
  }
438
  }
439
 
440
- tx.Delete(&company)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
441
  tx.Commit()
442
 
443
  c.JSON(http.StatusOK, gin.H{
 
380
  }
381
  }()
382
 
383
+ // 1. Ambil semua user terkait company ini, lalu hapus record OTP mereka
384
  var users []models.User
385
  tx.Where("company_id = ?", companyID).Find(&users)
386
  for _, u := range users {
 
389
  }
390
  }
391
 
392
+ // 2. Hapus order_items terlebih dahulu (menggunakan subquery) untuk menghindari FK violations
393
+ if err := tx.Exec("DELETE FROM order_items WHERE order_id IN (SELECT id FROM orders WHERE company_id = ?)", companyID).Error; err != nil {
394
+ tx.Rollback()
395
+ c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal menghapus data order items"})
396
+ return
397
+ }
398
+
399
+ // 3. Hapus orders
400
+ if err := tx.Where("company_id = ?", companyID).Delete(&models.Order{}).Error; err != nil {
401
+ tx.Rollback()
402
+ c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal menghapus data order"})
403
+ return
404
+ }
405
+
406
+ // 4. Hapus branch_products
407
+ if err := tx.Exec("DELETE FROM branch_products WHERE product_id IN (SELECT id FROM products WHERE company_id = ?)", companyID).Error; err != nil {
408
+ tx.Rollback()
409
+ c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal menghapus data branch products"})
410
+ return
411
+ }
412
+
413
+ // 5. Hapus products
414
+ if err := tx.Where("company_id = ?", companyID).Delete(&models.Product{}).Error; err != nil {
415
+ tx.Rollback()
416
+ c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal menghapus data produk"})
417
+ return
418
+ }
419
+
420
+ // 6. Hapus categories
421
+ if err := tx.Where("company_id = ?", companyID).Delete(&models.Category{}).Error; err != nil {
422
+ tx.Rollback()
423
+ c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal menghapus data kategori"})
424
+ return
425
+ }
426
+
427
+ // 7. Hapus users
428
+ if err := tx.Where("company_id = ?", companyID).Delete(&models.User{}).Error; err != nil {
429
+ tx.Rollback()
430
+ c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal menghapus data user"})
431
+ return
432
+ }
433
+
434
+ // 8. Hapus branches
435
+ if err := tx.Where("company_id = ?", companyID).Delete(&models.Branch{}).Error; err != nil {
436
+ tx.Rollback()
437
+ c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal menghapus data cabang"})
438
+ return
439
+ }
440
+
441
+ // 9. Terakhir hapus company utama
442
  if err := tx.Delete(&company).Error; err != nil {
443
  tx.Rollback()
444
  c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal menghapus data perusahaan"})
 
478
  }
479
  }()
480
 
481
+ // 1. Ambil semua user terkait company ini, lalu hapus record OTP mereka
482
  var users []models.User
483
  tx.Where("company_id = ?", companyID).Find(&users)
484
  for _, u := range users {
 
487
  }
488
  }
489
 
490
+ // 2. Hapus order_items terlebih dahulu (menggunakan subquery)
491
+ if err := tx.Exec("DELETE FROM order_items WHERE order_id IN (SELECT id FROM orders WHERE company_id = ?)", companyID).Error; err != nil {
492
+ tx.Rollback()
493
+ c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal menghapus data order items"})
494
+ return
495
+ }
496
+
497
+ // 3. Hapus orders
498
+ if err := tx.Where("company_id = ?", companyID).Delete(&models.Order{}).Error; err != nil {
499
+ tx.Rollback()
500
+ c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal menghapus data order"})
501
+ return
502
+ }
503
+
504
+ // 4. Hapus branch_products
505
+ if err := tx.Exec("DELETE FROM branch_products WHERE product_id IN (SELECT id FROM products WHERE company_id = ?)", companyID).Error; err != nil {
506
+ tx.Rollback()
507
+ c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal menghapus data branch products"})
508
+ return
509
+ }
510
+
511
+ // 5. Hapus products
512
+ if err := tx.Where("company_id = ?", companyID).Delete(&models.Product{}).Error; err != nil {
513
+ tx.Rollback()
514
+ c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal menghapus data produk"})
515
+ return
516
+ }
517
+
518
+ // 6. Hapus categories
519
+ if err := tx.Where("company_id = ?", companyID).Delete(&models.Category{}).Error; err != nil {
520
+ tx.Rollback()
521
+ c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal menghapus data kategori"})
522
+ return
523
+ }
524
+
525
+ // 7. Hapus users
526
+ if err := tx.Where("company_id = ?", companyID).Delete(&models.User{}).Error; err != nil {
527
+ tx.Rollback()
528
+ c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal menghapus data user"})
529
+ return
530
+ }
531
+
532
+ // 8. Hapus branches
533
+ if err := tx.Where("company_id = ?", companyID).Delete(&models.Branch{}).Error; err != nil {
534
+ tx.Rollback()
535
+ c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal menghapus data cabang"})
536
+ return
537
+ }
538
+
539
+ // 9. Terakhir hapus company utama
540
+ if err := tx.Delete(&company).Error; err != nil {
541
+ tx.Rollback()
542
+ c.JSON(http.StatusInternalServerError, gin.H{"detail": "Gagal menghapus data perusahaan"})
543
+ return
544
+ }
545
+
546
  tx.Commit()
547
 
548
  c.JSON(http.StatusOK, gin.H{
main.go CHANGED
@@ -1,6 +1,7 @@
1
  package main
2
 
3
  import (
 
4
  "log"
5
  "net/http"
6
 
@@ -68,6 +69,24 @@ func main() {
68
  c.JSON(http.StatusOK, gin.H{"status": "healthy"})
69
  })
70
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  // API Routing Group
72
  api := r.Group("/api")
73
  {
 
1
  package main
2
 
3
  import (
4
+ "io"
5
  "log"
6
  "net/http"
7
 
 
69
  c.JSON(http.StatusOK, gin.H{"status": "healthy"})
70
  })
71
 
72
+ r.GET("/api/ip", func(c *gin.Context) {
73
+ resp, err := http.Get("https://api.ipify.org")
74
+ if err != nil {
75
+ c.JSON(http.StatusInternalServerError, gin.H{"error": "Gagal mendapatkan IP outbound: " + err.Error()})
76
+ return
77
+ }
78
+ defer resp.Body.Close()
79
+ ipBytes, err := io.ReadAll(resp.Body)
80
+ if err != nil {
81
+ c.JSON(http.StatusInternalServerError, gin.H{"error": "Gagal membaca IP response: " + err.Error()})
82
+ return
83
+ }
84
+ c.JSON(http.StatusOK, gin.H{
85
+ "public_ip": string(ipBytes),
86
+ "info": "Gunakan IP ini untuk di-whitelist di Tripay",
87
+ })
88
+ })
89
+
90
  // API Routing Group
91
  api := r.Group("/api")
92
  {