package biz import ( "context" "strings" "time" ) type API struct { ID uint CreatedAt time.Time UpdatedAt time.Time Path string Description string APIGroup string Method string OrderKey string Desc bool StrictAll bool } type APIRepo interface { CreateAPI(context.Context, *API) error UpdateAPI(context.Context, *API) error DeleteAPIs(context.Context, []uint) error FindAPI(context.Context, uint) (*API, error) ListAPIs(context.Context, int, int, *API) ([]*API, int64, error) APIRoleIDs(context.Context, string, string) ([]uint, error) SetAPIRoles(context.Context, string, string, []uint) error Authorize(context.Context, uint, string, string) (bool, error) PolicyPaths(context.Context, uint) ([]*API, error) SetPolicyPaths(context.Context, uint, []*API) error IgnoredAPIs(context.Context) ([]*API, error) SetAPIIgnored(context.Context, string, string, bool) error ApplyAPISync(context.Context, []*API, []*API) error } type APIUsecase struct{ APIRepo } func NewAPIUsecase(repo APIRepo) *APIUsecase { return &APIUsecase{APIRepo: repo} } type APISyncDiff struct { Added []*API Deleted []*API Ignored []*API } func (uc *APIUsecase) SyncAPIs(ctx context.Context, routes []*API) (*APISyncDiff, error) { stored, _, err := uc.ListAPIs(ctx, 0, 0, nil) if err != nil { return nil, err } ignored, err := uc.IgnoredAPIs(ctx) if err != nil { return nil, err } key := func(value *API) string { return strings.ToUpper(value.Method) + " " + value.Path } ignoreSet := make(map[string]bool, len(ignored)) for _, item := range ignored { ignoreSet[key(item)] = true } routeSet := make(map[string]*API, len(routes)) for _, item := range routes { if !ignoreSet[key(item)] { routeSet[key(item)] = item } } storedSet := make(map[string]*API, len(stored)) for _, item := range stored { storedSet[key(item)] = item } diff := &APISyncDiff{Ignored: ignored} for routeKey, item := range routeSet { if storedSet[routeKey] == nil { diff.Added = append(diff.Added, item) } } for storedKey, item := range storedSet { if routeSet[storedKey] == nil && !ignoreSet[storedKey] { diff.Deleted = append(diff.Deleted, item) } } return diff, nil }