module Web.Controller.AiGovernancePolicies where -- IHF Phase 11 — Advanced AI Federation (IHUB-WP-0012 T08) import Web.Controller.Prelude import Web.View.AiGovernancePolicies.Index import Web.View.AiGovernancePolicies.New import Application.Helper.AgentBridge (jsonArrayTexts) import qualified Data.Aeson as A validAllowedActions :: [Text] validAllowedActions = ["read", "propose", "delegate", "auto_apply"] validateAllowedActions :: Value -> ValidatorResult validateAllowedActions val = let actions = jsonArrayTexts val invalid = filter (`notElem` validAllowedActions) actions in if null invalid then Success else Failure ("Invalid actions: " <> intercalate ", " invalid) instance Controller AiGovernancePoliciesController where action AiGovernancePoliciesAction = do policies <- query @AiGovernancePolicy |> orderByAsc #artifactType |> fetch hubs <- query @Hub |> orderByAsc #name |> fetch agents <- query @AgentRegistration |> orderByAsc #name |> fetch render IndexView { .. } action NewAiGovernancePolicyAction = do let policy = newRecord @AiGovernancePolicy |> set #allowedActions (A.toJSON ["read" :: Text]) hubs <- query @Hub |> orderByAsc #name |> fetch agents <- query @AgentRegistration |> filterWhere (#isActive, True) |> orderByAsc #name |> fetch render NewView { .. } action CreateAiGovernancePolicyAction = do -- Collect allowed_actions from checkbox params let selectedActions = paramList @Text "allowedActions" let actionsJson = A.toJSON selectedActions let policy = newRecord @AiGovernancePolicy |> set #allowedActions actionsJson policy |> fill @'["hubId","agentRegistrationId","artifactType"] |> validateField #artifactType nonEmpty |> ifValid \case Left policy -> do hubs <- query @Hub |> orderByAsc #name |> fetch agents <- query @AgentRegistration |> filterWhere (#isActive, True) |> fetch render NewView { .. } Right policy -> do createRecord policy setSuccessMessage "Governance policy created" redirectTo AiGovernancePoliciesAction action ToggleAiGovernancePolicyAction { aiGovernancePolicyId } = do policy <- fetch aiGovernancePolicyId policy |> set #isActive (not policy.isActive) |> updateRecord let msg = if policy.isActive then "Policy deactivated" else "Policy activated" setSuccessMessage msg redirectTo AiGovernancePoliciesAction