424 lines
23 KiB
Go
424 lines
23 KiB
Go
package api
|
|
|
|
import (
|
|
"strings"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/clause"
|
|
|
|
"wucher/internal/domain/auth"
|
|
"wucher/internal/domain/base"
|
|
)
|
|
|
|
// SeedRoles inserts default roles if they don't exist.
|
|
func SeedRoles(db *gorm.DB) error {
|
|
roles := []auth.Role{
|
|
{Code: "admin", Name: "admin", Description: "Full access to all resources."},
|
|
{Code: auth.RoleCodeStaff, Name: auth.RoleCodeStaff, Description: "Operational access with limited admin rights."},
|
|
{Code: "user", Name: "user", Description: "Regular end-user access."},
|
|
{Code: auth.RoleCodePilot, Name: "pilot", Description: "HEMS pilot contact role."},
|
|
{Code: auth.RoleCodeDoctor, Name: "doctor", Description: "HEMS doctor contact role."},
|
|
{Code: auth.RoleCodeAirRescuer, Name: "air_rescuer", Description: "HEMS air rescuer contact role."},
|
|
{Code: auth.RoleCodeTechnician, Name: "technician", Description: "HEMS technician contact role."},
|
|
{Code: auth.RoleCodeFlightAssistant, Name: "flight_assistant", Description: "HEMS flight assistant contact role."},
|
|
}
|
|
|
|
return db.Clauses(clause.OnConflict{
|
|
Columns: []clause.Column{{Name: "name"}},
|
|
DoUpdates: clause.AssignmentColumns([]string{"code", "description"}),
|
|
}).Create(&roles).Error
|
|
}
|
|
|
|
// DefaultPermissions returns the canonical catalog of permissions seeded into the system.
|
|
func DefaultPermissions() []auth.Permission {
|
|
return []auth.Permission{
|
|
{Name: "Create User", Key: "user.create", Description: "Create users"},
|
|
{Name: "Read User", Key: "user.read", Description: "Read users"},
|
|
{Name: "Update User", Key: "user.update", Description: "Update users"},
|
|
{Name: "Delete User", Key: "user.delete", Description: "Delete users"},
|
|
{Name: "Create Role", Key: "role.create", Description: "Create roles"},
|
|
{Name: "Read Role", Key: "role.read", Description: "Read roles"},
|
|
{Name: "Update Role", Key: "role.update", Description: "Update roles"},
|
|
{Name: "Delete Role", Key: "role.delete", Description: "Delete roles"},
|
|
{Name: "Read Permission", Key: "role.permission.read", Description: "Read permissions"},
|
|
{Name: "Assign Permission", Key: "role.permission.assign", Description: "Assign permissions to role"},
|
|
{Name: "Remove Permission", Key: "role.permission.remove", Description: "Remove permissions from role"},
|
|
{Name: "Update Permission", Key: "role.permission.update", Description: "Update permission configuration"},
|
|
{Name: "Read Filesystem", Key: "filesystem.read", Description: "Read filesystem structure"},
|
|
{Name: "Read File Manager", Key: "file_manager.read", Description: "Read file manager"},
|
|
{Name: "Create File Manager", Key: "file_manager.create", Description: "Create in file manager"},
|
|
{Name: "Update File Manager", Key: "file_manager.update", Description: "Update in file manager"},
|
|
{Name: "Delete File Manager", Key: "file_manager.delete", Description: "Delete in file manager"},
|
|
{Name: "Read Folders", Key: "file_manager.folder.read", Description: "Read folders"},
|
|
{Name: "Create Folders", Key: "file_manager.folder.create", Description: "Create folders"},
|
|
{Name: "Update Folders", Key: "file_manager.folder.update", Description: "Update folders"},
|
|
{Name: "Delete Folders", Key: "file_manager.folder.delete", Description: "Delete folders"},
|
|
{Name: "Read Files", Key: "file_manager.file.read", Description: "Read files"},
|
|
{Name: "Create Files", Key: "file_manager.file.create", Description: "Create files"},
|
|
{Name: "Update Files", Key: "file_manager.file.update", Description: "Update files"},
|
|
{Name: "Delete Files", Key: "file_manager.file.delete", Description: "Delete files"},
|
|
{Name: "Create Helicopter", Key: "helicopter.create", Description: "Create helicopter"},
|
|
{Name: "Generate Helicopter Report Number", Key: "helicopter.report.generate", Description: "Generate next helicopter report number"},
|
|
{Name: "Read Helicopter", Key: "helicopter.read", Description: "Read helicopter"},
|
|
{Name: "Update Helicopter", Key: "helicopter.update", Description: "Update helicopter"},
|
|
{Name: "Delete Helicopter", Key: "helicopter.delete", Description: "Delete helicopter"},
|
|
{Name: "Create Helicopter Usage", Key: "helicopter_usage.create", Description: "Create helicopter usage"},
|
|
{Name: "Read Helicopter Usage", Key: "helicopter_usage.read", Description: "Read helicopter usage"},
|
|
{Name: "Update Helicopter Usage", Key: "helicopter_usage.update", Description: "Update helicopter usage"},
|
|
{Name: "Delete Helicopter Usage", Key: "helicopter_usage.delete", Description: "Delete helicopter usage"},
|
|
{Name: "Create Flight Inspection", Key: "flight_inspection.create", Description: "Create flight inspection"},
|
|
{Name: "Read Flight Inspection", Key: "flight_inspection.read", Description: "Read flight inspection"},
|
|
{Name: "Update Flight Inspection", Key: "flight_inspection.update", Description: "Update flight inspection"},
|
|
{Name: "Create After Flight Inspection", Key: "after_flight.create", Description: "Create after flight inspection"},
|
|
{Name: "Read After Flight Inspection", Key: "after_flight.read", Description: "Read after flight inspection"},
|
|
{Name: "Update After Flight Inspection", Key: "after_flight.update", Description: "Update after flight inspection"},
|
|
{Name: "Delete After Flight Inspection", Key: "after_flight.delete", Description: "Delete after flight inspection"},
|
|
{Name: "Create Flight", Key: "flight.create", Description: "Create flight"},
|
|
{Name: "Read Flight", Key: "flight.read", Description: "Read flight"},
|
|
{Name: "Update Flight", Key: "flight.update", Description: "Update flight"},
|
|
{Name: "Complete Flight Report", Key: "flight.complete", Description: "Complete (finalize) flight report"},
|
|
{Name: "Delete Flight", Key: "flight.delete", Description: "Delete flight"},
|
|
{Name: "Create Reserve AC", Key: "reserve_ac.create", Description: "Create reserve AC"},
|
|
{Name: "Read Reserve AC", Key: "reserve_ac.read", Description: "Read reserve AC"},
|
|
{Name: "Update Reserve AC", Key: "reserve_ac.update", Description: "Update reserve AC"},
|
|
{Name: "Delete Reserve AC", Key: "reserve_ac.delete", Description: "Delete reserve AC"},
|
|
{Name: "Create Facility", Key: "facility.create", Description: "Create facility"},
|
|
{Name: "Read Facility", Key: "facility.read", Description: "Read facility"},
|
|
{Name: "Update Facility", Key: "facility.update", Description: "Update facility"},
|
|
{Name: "Delete Facility", Key: "facility.delete", Description: "Delete facility"},
|
|
{Name: "Create Base", Key: "base.create", Description: "Create base"},
|
|
{Name: "Read Base", Key: "base.read", Description: "Read base"},
|
|
{Name: "Update Base", Key: "base.update", Description: "Update base"},
|
|
{Name: "Delete Base", Key: "base.delete", Description: "Delete base"},
|
|
{Name: "Create HEMS Base", Key: "hems_base.create", Description: "Create HEMS base"},
|
|
{Name: "Read HEMS Base", Key: "hems_base.read", Description: "Read HEMS base"},
|
|
{Name: "Update HEMS Base", Key: "hems_base.update", Description: "Update HEMS base"},
|
|
{Name: "Delete HEMS Base", Key: "hems_base.delete", Description: "Delete HEMS base"},
|
|
{Name: "Create Medicine", Key: "medicine.create", Description: "Create medicine"},
|
|
{Name: "Read Medicine", Key: "medicine.read", Description: "Read medicine"},
|
|
{Name: "Update Medicine", Key: "medicine.update", Description: "Update medicine"},
|
|
{Name: "Delete Medicine", Key: "medicine.delete", Description: "Delete medicine"},
|
|
{Name: "Create Vocation", Key: "vocation.create", Description: "Create vocation"},
|
|
{Name: "Read Vocation", Key: "vocation.read", Description: "Read vocation"},
|
|
{Name: "Update Vocation", Key: "vocation.update", Description: "Update vocation"},
|
|
{Name: "Delete Vocation", Key: "vocation.delete", Description: "Delete vocation"},
|
|
{Name: "Create OPC", Key: "opc.create", Description: "Create opc"},
|
|
{Name: "Read OPC", Key: "opc.read", Description: "Read opc"},
|
|
{Name: "Update OPC", Key: "opc.update", Description: "Update opc"},
|
|
{Name: "Delete OPC", Key: "opc.delete", Description: "Delete opc"},
|
|
{Name: "Create Forces Present", Key: "forces_present.create", Description: "Create forces present"},
|
|
{Name: "Read Forces Present", Key: "forces_present.read", Description: "Read forces present"},
|
|
{Name: "Update Forces Present", Key: "forces_present.update", Description: "Update forces present"},
|
|
{Name: "Delete Forces Present", Key: "forces_present.delete", Description: "Delete forces present"},
|
|
{Name: "Create No ICAO Code", Key: "no_icao_code.create", Description: "Create no icao code"},
|
|
{Name: "Read No ICAO Code", Key: "no_icao_code.read", Description: "Read no icao code"},
|
|
{Name: "Update No ICAO Code", Key: "no_icao_code.update", Description: "Update no icao code"},
|
|
{Name: "Delete No ICAO Code", Key: "no_icao_code.delete", Description: "Delete no icao code"},
|
|
{Name: "Create Health Insurance Companies", Key: "health_insurance_companies.create", Description: "Create health insurance companies"},
|
|
{Name: "Read Health Insurance Companies", Key: "health_insurance_companies.read", Description: "Read health insurance companies"},
|
|
{Name: "Update Health Insurance Companies", Key: "health_insurance_companies.update", Description: "Update health insurance companies"},
|
|
{Name: "Delete Health Insurance Companies", Key: "health_insurance_companies.delete", Description: "Delete health insurance companies"},
|
|
{Name: "Create Federal State", Key: "federal_state.create", Description: "Create federal state"},
|
|
{Name: "Read Federal State", Key: "federal_state.read", Description: "Read federal state"},
|
|
{Name: "Update Federal State", Key: "federal_state.update", Description: "Update federal state"},
|
|
{Name: "Delete Federal State", Key: "federal_state.delete", Description: "Delete federal state"},
|
|
{Name: "Create ICAO", Key: "icao.create", Description: "Create ICAO"},
|
|
{Name: "Read ICAO", Key: "icao.read", Description: "Read ICAO"},
|
|
{Name: "Update ICAO", Key: "icao.update", Description: "Update ICAO"},
|
|
{Name: "Delete ICAO", Key: "icao.delete", Description: "Delete ICAO"},
|
|
{Name: "Create Country", Key: "country.create", Description: "Create country"},
|
|
{Name: "Read Country", Key: "country.read", Description: "Read country"},
|
|
{Name: "Update Country", Key: "country.update", Description: "Update country"},
|
|
{Name: "Delete Country", Key: "country.delete", Description: "Delete country"},
|
|
{Name: "Create Master Settings", Key: "master_settings.create", Description: "Create master settings"},
|
|
{Name: "Read Master Settings", Key: "master_settings.read", Description: "Read master settings"},
|
|
{Name: "Update Master Settings", Key: "master_settings.update", Description: "Update master settings"},
|
|
{Name: "Delete Master Settings", Key: "master_settings.delete", Description: "Delete master settings"},
|
|
{Name: "Create Duty Roster", Key: "duty_roster.create", Description: "Create duty roster"},
|
|
{Name: "Read Duty Roster", Key: "duty_roster.read", Description: "Read duty roster"},
|
|
{Name: "Update Duty Roster", Key: "duty_roster.update", Description: "Update duty roster"},
|
|
{Name: "Delete Duty Roster", Key: "duty_roster.delete", Description: "Delete duty roster"},
|
|
{Name: "Create Air Rescuer Checklist", Key: "air_rescuer_checklist.create", Description: "Create air rescuer checklist"},
|
|
{Name: "Read Air Rescuer Checklist", Key: "air_rescuer_checklist.read", Description: "Read air rescuer checklist"},
|
|
{Name: "Update Air Rescuer Checklist", Key: "air_rescuer_checklist.update", Description: "Update air rescuer checklist"},
|
|
{Name: "Delete Air Rescuer Checklist", Key: "air_rescuer_checklist.delete", Description: "Delete air rescuer checklist"},
|
|
{Name: "Create Flight Prep Check", Key: "flight_prep_check.create", Description: "Create flight prep check"},
|
|
{Name: "Read Flight Prep Check", Key: "flight_prep_check.read", Description: "Read flight prep check"},
|
|
{Name: "Update Flight Prep Check", Key: "flight_prep_check.update", Description: "Update flight prep check"},
|
|
{Name: "Read Audit Log", Key: "audit.read", Description: "Read audit logs"},
|
|
{Name: "Create Insurance Patient Data", Key: "insurance_patient_data.create", Description: "Create insurance patient data"},
|
|
{Name: "Read Insurance Patient Data", Key: "insurance_patient_data.read", Description: "Read insurance patient data"},
|
|
{Name: "Update Insurance Patient Data", Key: "insurance_patient_data.update", Description: "Update insurance patient data"},
|
|
{Name: "Delete Insurance Patient Data", Key: "insurance_patient_data.delete", Description: "Delete insurance patient data"},
|
|
{Name: "Create Patient Data", Key: "patient_data.create", Description: "Create patient data"},
|
|
{Name: "Read Patient Data", Key: "patient_data.read", Description: "Read patient data"},
|
|
{Name: "Update Patient Data", Key: "patient_data.update", Description: "Update patient data"},
|
|
{Name: "Delete Patient Data", Key: "patient_data.delete", Description: "Delete patient data"},
|
|
{Name: "Create Operation", Key: "operation.create", Description: "Create HEMS operational data"},
|
|
{Name: "Read Operation", Key: "operation.read", Description: "Read HEMS operational data"},
|
|
{Name: "Update Operation", Key: "operation.update", Description: "Update HEMS operational data"},
|
|
{Name: "Delete Operation", Key: "operation.delete", Description: "Delete HEMS operational data"},
|
|
{Name: "Create Operation Category", Key: "operation_category.create", Description: "Create HEMS operation category"},
|
|
{Name: "Read Operation Category", Key: "operation_category.read", Description: "Read HEMS operation category"},
|
|
{Name: "Update Operation Category", Key: "operation_category.update", Description: "Update HEMS operation category"},
|
|
{Name: "Delete Operation Category", Key: "operation_category.delete", Description: "Delete HEMS operation category"},
|
|
{Name: "Create HEMS Operation", Key: "hems_operation.create", Description: "Create HEMS operation"},
|
|
{Name: "Read HEMS Operation", Key: "hems_operation.read", Description: "Read HEMS operation"},
|
|
{Name: "Update HEMS Operation", Key: "hems_operation.update", Description: "Update HEMS operation"},
|
|
{Name: "Delete HEMS Operation", Key: "hems_operation.delete", Description: "Delete HEMS operation"},
|
|
{Name: "Create DUL", Key: "dul.create", Description: "Create DUL"},
|
|
{Name: "Read DUL", Key: "dul.read", Description: "Read DUL"},
|
|
{Name: "Update DUL", Key: "dul.update", Description: "Update DUL"},
|
|
{Name: "Delete DUL", Key: "dul.delete", Description: "Delete DUL"},
|
|
{Name: "Create Complaint", Key: "complaint.create", Description: "Create complaint"},
|
|
{Name: "Read Complaint", Key: "complaint.read", Description: "Read complaint"},
|
|
{Name: "Update Complaint", Key: "complaint.update", Description: "Update complaint"},
|
|
{Name: "Delete Complaint", Key: "complaint.delete", Description: "Delete complaint"},
|
|
{Name: "Decide Complaint NSR", Key: "complaint.nsr", Description: "Set or cancel complaint NSR (non-safety release)"},
|
|
{Name: "Create EASA Release", Key: "easa_release.create", Description: "Create EASA maintenance release"},
|
|
{Name: "Read EASA Release", Key: "easa_release.read", Description: "Read EASA maintenance release"},
|
|
{Name: "Update EASA Release", Key: "easa_release.update", Description: "Update EASA maintenance release"},
|
|
{Name: "Delete EASA Release", Key: "easa_release.delete", Description: "Delete EASA maintenance release"},
|
|
{Name: "Sign EASA Release", Key: "easa_release.sign", Description: "Sign EASA maintenance release (return to service)"},
|
|
{Name: "Read Action Sign-off", Key: "action_signoff.read", Description: "Read corrective-action sign-off"},
|
|
{Name: "Sign Action Sign-off", Key: "action_signoff.sign", Description: "Toggle (sign/unsign) corrective-action sign-off, per complaint or fleet-wide"},
|
|
{Name: "Create MCF", Key: "mcf.create", Description: "Create maintenance check flight"},
|
|
{Name: "Read MCF", Key: "mcf.read", Description: "Read maintenance check flight"},
|
|
{Name: "Complete MCF", Key: "mcf.complete", Description: "Complete (release) a helicopter's open maintenance check flight"},
|
|
}
|
|
}
|
|
|
|
// SeedPermissions inserts default permissions and keeps existing rows in sync.
|
|
func SeedPermissions(db *gorm.DB) error {
|
|
perms := DefaultPermissions()
|
|
|
|
for i := range perms {
|
|
perms[i].Module = auth.ModuleForKey(perms[i].Key)
|
|
perms[i].RequiresPIN = auth.DefaultPermissionRequiresPIN(perms[i].Key)
|
|
}
|
|
|
|
return db.Clauses(clause.OnConflict{
|
|
Columns: []clause.Column{{Name: "key"}},
|
|
DoUpdates: clause.AssignmentColumns([]string{"name", "description", "module"}),
|
|
}).Create(&perms).Error
|
|
}
|
|
|
|
// SeedRolePermissions inserts default role-permission mappings and ensures admin has all permissions.
|
|
func SeedRolePermissions(db *gorm.DB) error {
|
|
type rolePerm struct {
|
|
RoleName string
|
|
PermKey string
|
|
}
|
|
|
|
mappings := []rolePerm{
|
|
// staff: read-only for users/roles/permissions
|
|
{RoleName: "staff", PermKey: "user.read"},
|
|
{RoleName: "staff", PermKey: "role.read"},
|
|
{RoleName: "staff", PermKey: "role.permission.read"},
|
|
{RoleName: "staff", PermKey: "helicopter.read"},
|
|
{RoleName: "staff", PermKey: "flight_inspection.read"},
|
|
{RoleName: "staff", PermKey: "flight.read"},
|
|
{RoleName: "staff", PermKey: "reserve_ac.read"},
|
|
{RoleName: "staff", PermKey: "facility.read"},
|
|
{RoleName: "staff", PermKey: "base.read"},
|
|
{RoleName: "staff", PermKey: "hems_base.read"},
|
|
{RoleName: "staff", PermKey: "medicine.read"},
|
|
{RoleName: "staff", PermKey: "vocation.read"},
|
|
{RoleName: "staff", PermKey: "opc.read"},
|
|
{RoleName: "staff", PermKey: "forces_present.read"},
|
|
{RoleName: "staff", PermKey: "no_icao_code.read"},
|
|
{RoleName: "staff", PermKey: "health_insurance_companies.read"},
|
|
{RoleName: "staff", PermKey: "federal_state.read"},
|
|
{RoleName: "staff", PermKey: "icao.read"},
|
|
{RoleName: "staff", PermKey: "country.read"},
|
|
{RoleName: "staff", PermKey: "master_settings.read"},
|
|
{RoleName: "staff", PermKey: "file_manager.read"},
|
|
{RoleName: "staff", PermKey: "duty_roster.read"},
|
|
{RoleName: "staff", PermKey: "air_rescuer_checklist.read"},
|
|
{RoleName: "staff", PermKey: "flight_prep_check.create"},
|
|
{RoleName: "staff", PermKey: "flight_prep_check.read"},
|
|
{RoleName: "staff", PermKey: "flight_prep_check.update"},
|
|
{RoleName: "staff", PermKey: "helicopter_usage.read"},
|
|
{RoleName: "staff", PermKey: "after_flight.read"},
|
|
{RoleName: "staff", PermKey: "audit.read"},
|
|
{RoleName: "staff", PermKey: "insurance_patient_data.read"},
|
|
{RoleName: "staff", PermKey: "patient_data.read"},
|
|
{RoleName: "staff", PermKey: "operation.read"},
|
|
{RoleName: "staff", PermKey: "operation_category.read"},
|
|
{RoleName: "staff", PermKey: "hems_operation.read"},
|
|
{RoleName: "pilot", PermKey: "flight.read"},
|
|
{RoleName: "pilot", PermKey: "duty_roster.read"},
|
|
}
|
|
|
|
if err := assignAllPermissionsToRole(db, "admin"); err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, m := range mappings {
|
|
if err := assignPermissionToRole(db, m.RoleName, m.PermKey); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func assignAllPermissionsToRole(db *gorm.DB, roleName string) error {
|
|
var role auth.Role
|
|
if err := db.Where("name = ?", roleName).First(&role).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
var perms []auth.Permission
|
|
if err := db.Find(&perms).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, perm := range perms {
|
|
rp := auth.RolePermission{RoleID: role.ID, PermissionID: perm.ID}
|
|
if err := db.Clauses(clause.OnConflict{
|
|
Columns: []clause.Column{{Name: "role_id"}, {Name: "permission_id"}},
|
|
DoNothing: true,
|
|
}).Create(&rp).Error; err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func assignPermissionToRole(db *gorm.DB, roleName, permKey string) error {
|
|
var role auth.Role
|
|
if err := db.Where("name = ?", roleName).First(&role).Error; err != nil {
|
|
return err
|
|
}
|
|
var perm auth.Permission
|
|
if err := db.Where("`key` = ?", permKey).First(&perm).Error; err != nil {
|
|
return err
|
|
}
|
|
rp := auth.RolePermission{RoleID: role.ID, PermissionID: perm.ID}
|
|
return db.Clauses(clause.OnConflict{
|
|
Columns: []clause.Column{{Name: "role_id"}, {Name: "permission_id"}},
|
|
DoNothing: true,
|
|
}).Create(&rp).Error
|
|
}
|
|
|
|
// SeedBaseCategories inserts default base categories if they don't exist.
|
|
func SeedBaseCategories(db *gorm.DB) error {
|
|
categories := []base.BaseCategory{
|
|
{Key: base.CategoryKeyRegular, Name: "Regular Base"},
|
|
{Key: base.CategoryKeyHEMS, Name: "HEMS Base"},
|
|
}
|
|
|
|
return db.Clauses(clause.OnConflict{
|
|
Columns: []clause.Column{{Name: "key"}},
|
|
DoUpdates: clause.AssignmentColumns([]string{"name"}),
|
|
}).Create(&categories).Error
|
|
}
|
|
|
|
// SeedRosterUsers inserts sample users for duty roster assignment in development.
|
|
// This seed is idempotent by email and keeps role assignment synced via user_roles.
|
|
func SeedRosterUsers(db *gorm.DB) error {
|
|
type rosterSeed struct {
|
|
Email string
|
|
FirstName string
|
|
LastName string
|
|
MobilePhone string
|
|
RoleCode string
|
|
}
|
|
|
|
seeds := []rosterSeed{
|
|
{Email: "pilot.main@wucher.local", FirstName: "Pilot", LastName: "Main", MobilePhone: "+620001", RoleCode: auth.RoleCodePilot},
|
|
{Email: "pilot.additional@wucher.local", FirstName: "Pilot", LastName: "Additional", MobilePhone: "+620002", RoleCode: auth.RoleCodePilot},
|
|
{Email: "doctor.main@wucher.local", FirstName: "Doctor", LastName: "Main", MobilePhone: "+620003", RoleCode: auth.RoleCodeDoctor},
|
|
{Email: "rescuer.main@wucher.local", FirstName: "Rescuer", LastName: "Main", MobilePhone: "+620004", RoleCode: auth.RoleCodeAirRescuer},
|
|
{Email: "helper.main@wucher.local", FirstName: "Helper", LastName: "Main", MobilePhone: "+620005", RoleCode: auth.RoleCodeFlightAssistant},
|
|
}
|
|
|
|
return db.Transaction(func(tx *gorm.DB) error {
|
|
roleKeys := make([]string, 0, len(seeds))
|
|
seenRole := make(map[string]struct{}, len(seeds))
|
|
for i := range seeds {
|
|
k := strings.ToLower(strings.TrimSpace(seeds[i].RoleCode))
|
|
if k == "" {
|
|
continue
|
|
}
|
|
if _, ok := seenRole[k]; ok {
|
|
continue
|
|
}
|
|
seenRole[k] = struct{}{}
|
|
roleKeys = append(roleKeys, k)
|
|
}
|
|
|
|
var roles []auth.Role
|
|
if err := tx.Where("LOWER(code) IN ? OR LOWER(name) IN ?", roleKeys, roleKeys).Find(&roles).Error; err != nil {
|
|
return err
|
|
}
|
|
roleIDByCode := make(map[string][]byte, len(roles))
|
|
for i := range roles {
|
|
code := strings.ToLower(strings.TrimSpace(roles[i].Code))
|
|
if code == "" {
|
|
code = strings.ToLower(strings.TrimSpace(roles[i].Name))
|
|
}
|
|
if code == "" {
|
|
continue
|
|
}
|
|
roleIDByCode[code] = append([]byte(nil), roles[i].ID...)
|
|
}
|
|
|
|
now := time.Now().UTC()
|
|
for i := range seeds {
|
|
roleCode := strings.ToLower(strings.TrimSpace(seeds[i].RoleCode))
|
|
roleID := roleIDByCode[roleCode]
|
|
if len(roleID) != 16 {
|
|
continue
|
|
}
|
|
|
|
row := auth.User{
|
|
Email: strings.ToLower(strings.TrimSpace(seeds[i].Email)),
|
|
Username: nil,
|
|
FirstName: strings.TrimSpace(seeds[i].FirstName),
|
|
LastName: strings.TrimSpace(seeds[i].LastName),
|
|
MobilePhone: strings.TrimSpace(seeds[i].MobilePhone),
|
|
Timezone: "UTC",
|
|
RoleID: roleID,
|
|
IsActive: true,
|
|
EmailVerifiedAt: &now,
|
|
}
|
|
|
|
if err := tx.Clauses(clause.OnConflict{
|
|
Columns: []clause.Column{{Name: "email"}},
|
|
DoUpdates: clause.Assignments(map[string]any{
|
|
"first_name": row.FirstName,
|
|
"last_name": row.LastName,
|
|
"mobile_phone": row.MobilePhone,
|
|
"timezone": row.Timezone,
|
|
"role_id": row.RoleID,
|
|
"is_active": row.IsActive,
|
|
"email_verified_at": row.EmailVerifiedAt,
|
|
"updated_at": now,
|
|
}),
|
|
}).Create(&row).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
var created auth.User
|
|
if err := tx.Where("email = ?", row.Email).Take(&created).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
link := auth.UserRole{
|
|
UserID: created.ID,
|
|
RoleID: roleID,
|
|
}
|
|
if err := tx.Clauses(clause.OnConflict{
|
|
Columns: []clause.Column{{Name: "user_id"}, {Name: "role_id"}},
|
|
DoNothing: true,
|
|
}).Create(&link).Error; err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
})
|
|
}
|