From 04cfb9719b93942cfe52d4c535502fea1ab0d084 Mon Sep 17 00:00:00 2001 From: Habib Fatkhul Rohman Date: Tue, 21 Oct 2025 20:23:16 +0700 Subject: [PATCH] feat: Add many-to-many relationship between menus and clients with seeder support --- database/entities/m_client_entity.go | 2 + database/entities/m_menu_client_entity.go | 4 +- database/entities/m_menu_entity.go | 10 +- database/seeder.go | 1 + database/seeders/json/menu_clients.json | 102 +++++++++++++++++++++ database/seeders/seeds/menu_client_seed.go | 59 ++++++++++++ 6 files changed, 173 insertions(+), 5 deletions(-) create mode 100644 database/seeders/json/menu_clients.json create mode 100644 database/seeders/seeds/menu_client_seed.go diff --git a/database/entities/m_client_entity.go b/database/entities/m_client_entity.go index b0151e3..5eb3b49 100644 --- a/database/entities/m_client_entity.go +++ b/database/entities/m_client_entity.go @@ -14,6 +14,8 @@ type M_Client struct { Users []M_User `gorm:"foreignKey:ClientID;references:ID" json:"users"` MaintenanceGroups []M_MaintenanceGroup `gorm:"foreignKey:ClientID;references:ID" json:"maintenance_groups"` Roles []M_Role `gorm:"foreignKey:ClientID;references:ID" json:"roles"` + MenusClients []M_Menu_Client `gorm:"foreignKey:ClientID;references:ID" json:"menus_clients"` + Menus []M_Menu `gorm:"many2many:m_menu_clients;joinForeignKey:ClientID;JoinReferences:MenuID" json:"menus"` FullAuditTrail } diff --git a/database/entities/m_menu_client_entity.go b/database/entities/m_menu_client_entity.go index fff3e5a..7ce2e97 100644 --- a/database/entities/m_menu_client_entity.go +++ b/database/entities/m_menu_client_entity.go @@ -5,7 +5,9 @@ import ( ) type M_Menu_Client struct { - ID uuid.UUID `gorm:"type:uuid;primary_key;default:uuid_generate_v4()" json:"id"` MenuID uuid.UUID `gorm:"type:uuid;not null;index" json:"menu_id"` ClientID uuid.UUID `gorm:"type:uuid;not null;index" json:"client_id"` + + M_Menu M_Menu `gorm:"foreignKey:MenuID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"m_menu"` + Client M_Client `gorm:"foreignKey:ClientID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"client"` } diff --git a/database/entities/m_menu_entity.go b/database/entities/m_menu_entity.go index 86be3f0..a461162 100644 --- a/database/entities/m_menu_entity.go +++ b/database/entities/m_menu_entity.go @@ -15,9 +15,11 @@ type M_Menu struct { Status string `gorm:"type:varchar(50);not null" json:"status"` ParentID *uuid.UUID `gorm:"type:uuid" json:"parent_id"` - Children []M_Menu `gorm:"foreignKey:ParentID;references:ID" json:"children"` - RoleMenus []M_Role_Menu `gorm:"foreignKey:MenuID;references:ID" json:"role_menus"` - Permissions []M_Permissions `gorm:"foreignKey:MenuID;references:ID" json:"permissions"` - + Children []M_Menu `gorm:"foreignKey:ParentID;references:ID" json:"children"` + RoleMenus []M_Role_Menu `gorm:"foreignKey:MenuID;references:ID" json:"role_menus"` + Permissions []M_Permissions `gorm:"foreignKey:MenuID;references:ID" json:"permissions"` + MenusClients []M_Menu_Client `gorm:"foreignKey:MenuID;references:ID" json:"menus_clients"` + Clients []M_Client `gorm:"many2many:m_menu_clients;joinForeignKey:MenuID;JoinReferences:ClientID" json:"clients"` + FullAuditTrail } diff --git a/database/seeder.go b/database/seeder.go index b027517..fb0ce81 100644 --- a/database/seeder.go +++ b/database/seeder.go @@ -15,6 +15,7 @@ func Seeder(db *gorm.DB) error { seeds.ListPermissionSeeder, seeds.ListRolePermissionSeeder, seeds.ListRoleMenuSeeder, + seeds.ListMenuClientSeeder, } for _, seeder := range seeders { diff --git a/database/seeders/json/menu_clients.json b/database/seeders/json/menu_clients.json new file mode 100644 index 0000000..bdd5890 --- /dev/null +++ b/database/seeders/json/menu_clients.json @@ -0,0 +1,102 @@ +[ + { + "menu_name": "Dashboard", + "client_name": "PT Teknologi Maju Indonesia" + }, + { + "menu_name": "Users", + "client_name": "PT Teknologi Maju Indonesia" + }, + { + "menu_name": "Roles & Permissions", + "client_name": "PT Teknologi Maju Indonesia" + }, + { + "menu_name": "Products", + "client_name": "PT Teknologi Maju Indonesia" + }, + { + "menu_name": "Reports", + "client_name": "PT Teknologi Maju Indonesia" + }, + { + "menu_name": "Dashboard", + "client_name": "CV Sumber Rejeki Abadi" + }, + { + "menu_name": "Users", + "client_name": "CV Sumber Rejeki Abadi" + }, + { + "menu_name": "Roles & Permissions", + "client_name": "CV Sumber Rejeki Abadi" + }, + { + "menu_name": "Products", + "client_name": "CV Sumber Rejeki Abadi" + }, + { + "menu_name": "Reports", + "client_name": "CV Sumber Rejeki Abadi" + }, + { + "menu_name": "Dashboard", + "client_name": "PT Logistik Nusantara Prima" + }, + { + "menu_name": "Users", + "client_name": "PT Logistik Nusantara Prima" + }, + { + "menu_name": "Roles & Permissions", + "client_name": "PT Logistik Nusantara Prima" + }, + { + "menu_name": "Products", + "client_name": "PT Logistik Nusantara Prima" + }, + { + "menu_name": "Reports", + "client_name": "PT Logistik Nusantara Prima" + }, + { + "menu_name": "Dashboard", + "client_name": "UD Mandiri Sejahtera" + }, + { + "menu_name": "Users", + "client_name": "UD Mandiri Sejahtera" + }, + { + "menu_name": "Roles & Permissions", + "client_name": "UD Mandiri Sejahtera" + }, + { + "menu_name": "Products", + "client_name": "UD Mandiri Sejahtera" + }, + { + "menu_name": "Reports", + "client_name": "UD Mandiri Sejahtera" + }, + { + "menu_name": "Dashboard", + "client_name": "PT Global Supply Chain" + }, + { + "menu_name": "Users", + "client_name": "PT Global Supply Chain" + }, + { + "menu_name": "Roles & Permissions", + "client_name": "PT Global Supply Chain" + }, + { + "menu_name": "Products", + "client_name": "PT Global Supply Chain" + }, + { + "menu_name": "Reports", + "client_name": "PT Global Supply Chain" + } +] diff --git a/database/seeders/seeds/menu_client_seed.go b/database/seeders/seeds/menu_client_seed.go new file mode 100644 index 0000000..794145b --- /dev/null +++ b/database/seeders/seeds/menu_client_seed.go @@ -0,0 +1,59 @@ +package seeds + +import ( + "encoding/json" + "io" + "os" + + "github.com/Caknoooo/go-gin-clean-starter/database/entities" + "github.com/sirupsen/logrus" + "gorm.io/gorm" +) + +type MenuClientSeed struct { + MenuName string `json:"menu_name"` + ClientName string `json:"client_name"` +} + +func ListMenuClientSeeder(db *gorm.DB) error { + jsonFile, err := os.Open("./database/seeders/json/menu_clients.json") + if err != nil { + return err + } + + jsonData, err := io.ReadAll(jsonFile) + if err != nil { + return err + } + + var listMenuClient []MenuClientSeed + if err := json.Unmarshal(jsonData, &listMenuClient); err != nil { + return err + } + hasTable := db.Migrator().HasTable(&entities.M_Menu_Client{}) + if !hasTable { + if err := db.Migrator().CreateTable(&entities.M_Menu_Client{}); err != nil { + return err + } + } + for _, data := range listMenuClient { + var menu entities.M_Menu + var client entities.M_Client + if err := db.Where("name = ?", data.MenuName).First(&menu).Error; err != nil { + logrus.Error("Menu not found: ", err) + return err // menu tidak ditemukan + } + if err := db.Where("name = ?", data.ClientName).First(&client).Error; err != nil { + logrus.Error("Client not found: ", err) + return err // client tidak ditemukan + } + var menuClient entities.M_Menu_Client + if err := db.FirstOrCreate(&menuClient, entities.M_Menu_Client{ + MenuID: menu.ID, + ClientID: client.ID, + }).Error; err != nil { + return err + } + } + return nil +}