Skip to content

Commit 1b06474

Browse files
committed
Allow DISABLED workflow action and add endpoint to list latest scenario rule versions.
1 parent a0970b0 commit 1b06474

File tree

9 files changed

+128
-0
lines changed

9 files changed

+128
-0
lines changed

api/handle_scenarios.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,20 @@ func validateScenarioAst(uc usecases.Usecases) func(c *gin.Context) {
157157
})
158158
}
159159
}
160+
161+
func listLatestScenarioRules(uc usecases.Usecases) gin.HandlerFunc {
162+
return func(c *gin.Context) {
163+
ctx := c.Request.Context()
164+
scenarioId := c.Param("scenario_id")
165+
166+
scenarioUsecase := usecasesWithCreds(ctx, uc).NewScenarioUsecase()
167+
168+
rules, err := scenarioUsecase.ListLatestRules(ctx, scenarioId)
169+
170+
if presentError(ctx, c, err) {
171+
return
172+
}
173+
174+
c.JSON(http.StatusOK, pure_utils.Map(rules, dto.AdaptScenarioRuleLatestVersion))
175+
}
176+
}

api/routes.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ func addRoutes(r *gin.Engine, conf Configuration, uc usecases.Usecases, auth uti
9898
router.GET("/scenarios/:scenario_id", tom, getScenario(uc))
9999
router.PATCH("/scenarios/:scenario_id", tom, updateScenario(uc))
100100
router.POST("/scenarios/:scenario_id/validate-ast", tom, validateScenarioAst(uc))
101+
router.GET("/scenarios/:scenario_id/rules/latest", tom, listLatestScenarioRules(uc))
101102

102103
router.GET("/scenario-iterations", tom, handleListScenarioIterations(uc))
103104
router.POST("/scenario-iterations", tom, handleCreateScenarioIteration(uc))

dto/scenarios.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,19 @@ func AdaptUpdateScenarioInput(scenarioId string, input UpdateScenarioBody) model
101101
}
102102
return parsedInput
103103
}
104+
105+
type ScenarioRuleLatestVersion struct {
106+
Type string `json:"type"`
107+
StableId string `json:"stable_id"`
108+
Name string `json:"name"`
109+
LatestVersion string `json:"latest_version"`
110+
}
111+
112+
func AdaptScenarioRuleLatestVersion(rule models.ScenarioRuleLatestVersion) ScenarioRuleLatestVersion {
113+
return ScenarioRuleLatestVersion{
114+
Type: rule.Type,
115+
StableId: rule.StableId,
116+
Name: rule.Name,
117+
LatestVersion: rule.LatestVersion,
118+
}
119+
}

mocks/scenario_repository_mock.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,13 @@ func (s *ScenarioRepository) UpdateScenario(ctx context.Context, exec repositori
4141
args := s.Called(exec, scenario)
4242
return args.Error(0)
4343
}
44+
45+
func (s *ScenarioRepository) ListScenarioLatestRuleVersions(ctx context.Context, exec repositories.Executor, scenarioId string) ([]models.ScenarioRuleLatestVersion, error) {
46+
args := s.Called(ctx, exec, scenarioId)
47+
48+
if args.Error(1) != nil {
49+
return nil, args.Error(1)
50+
}
51+
52+
return args.Get(0).([]models.ScenarioRuleLatestVersion), nil
53+
}

models/scenarios.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,10 @@ type ScenarioAndIteration struct {
7272
Scenario Scenario
7373
Iteration ScenarioIteration
7474
}
75+
76+
type ScenarioRuleLatestVersion struct {
77+
Type string
78+
StableId string
79+
Name string
80+
LatestVersion string
81+
}

repositories/dbmodels/db_scenario.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,10 @@ func AdaptScenario(dto DBScenario) (models.Scenario, error) {
5858

5959
return scenario, nil
6060
}
61+
62+
type DBScenarioRuleLatestVersion struct {
63+
Type string `db:"type"`
64+
StableRuleId string `db:"stable_rule_id"`
65+
Name string `db:"name"`
66+
Version string `db:"version"`
67+
}

repositories/scenarios_read.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55

66
"github.com/checkmarble/marble-backend/models"
77
"github.com/checkmarble/marble-backend/repositories/dbmodels"
8+
"github.com/jackc/pgx/v5"
89

910
"github.com/Masterminds/squirrel"
1011
)
@@ -24,6 +25,7 @@ type ScenarioUsecaseRepository interface {
2425
exec Executor,
2526
scenario models.UpdateScenarioInput,
2627
) error
28+
ListScenarioLatestRuleVersions(ctx context.Context, exec Executor, scenarioId string) ([]models.ScenarioRuleLatestVersion, error)
2729
}
2830

2931
func selectScenarios() squirrel.SelectBuilder {
@@ -78,3 +80,56 @@ func (repo *MarbleDbRepository) ListAllScenarios(ctx context.Context, exec Execu
7880
dbmodels.AdaptScenario,
7981
)
8082
}
83+
84+
func (repo *MarbleDbRepository) ListScenarioLatestRuleVersions(ctx context.Context, exec Executor, scenarioId string) ([]models.ScenarioRuleLatestVersion, error) {
85+
sql := `
86+
select type, stable_rule_id, name, version
87+
from (
88+
select
89+
rank() over (partition by sir.stable_rule_id order by si.version desc) as rank,
90+
'rule' as type,
91+
sir.stable_rule_id,
92+
sir.name,
93+
si.version
94+
from scenario_iteration_rules sir
95+
inner join scenario_iterations si on si.id = sir.scenario_iteration_id
96+
where si.scenario_id = $1
97+
union all
98+
select
99+
rank() over (partition by scc.stable_id order by si.version desc) as rank,
100+
'screening' as type,
101+
scc.stable_id,
102+
scc.name,
103+
si.version
104+
from sanction_check_configs scc
105+
inner join scenario_iterations si on si.id = scc.scenario_iteration_id
106+
where si.scenario_id = $2
107+
) rules
108+
where rules.rank = 1
109+
order by rules.version desc, rules.name asc
110+
`
111+
112+
rows, err := exec.Query(ctx, sql, scenarioId, scenarioId)
113+
if err != nil {
114+
return nil, err
115+
}
116+
117+
rules := make([]models.ScenarioRuleLatestVersion, 0)
118+
119+
for rows.Next() {
120+
rule, err := pgx.RowToStructByName[dbmodels.DBScenarioRuleLatestVersion](rows)
121+
122+
if err != nil {
123+
return nil, err
124+
}
125+
126+
rules = append(rules, models.ScenarioRuleLatestVersion{
127+
Type: rule.Type,
128+
StableId: rule.StableRuleId,
129+
Name: rule.Name,
130+
LatestVersion: rule.Version,
131+
})
132+
}
133+
134+
return rules, nil
135+
}

usecases/scenario_usecase.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,3 +199,16 @@ func (usecase *ScenarioUsecase) CreateScenario(
199199
})
200200
return createdScenario, nil
201201
}
202+
203+
func (uc *ScenarioUsecase) ListLatestRules(ctx context.Context, scenarioId string) ([]models.ScenarioRuleLatestVersion, error) {
204+
scenario, err := uc.repository.GetScenarioById(ctx, uc.executorFactory.NewExecutor(), scenarioId)
205+
if err != nil {
206+
return nil, err
207+
}
208+
209+
if err := uc.enforceSecurity.ReadScenario(scenario); err != nil {
210+
return nil, err
211+
}
212+
213+
return uc.repository.ListScenarioLatestRuleVersions(ctx, uc.executorFactory.NewExecutor(), scenarioId)
214+
}

usecases/workflows_usecase.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,8 @@ func (uc *WorkflowUsecase) ValidateWorkflowAction(ctx context.Context, scenario
380380
"invalid AST in field 'title_template'")
381381
}
382382
}
383+
case models.WorkflowDisabled:
384+
return nil
383385
default:
384386
return errors.Wrapf(models.BadParameterError, "unknown workflow action type: %s", cond.Action)
385387
}

0 commit comments

Comments
 (0)