Document the optional RulePrecheck rule interface

This commit is contained in:
nemunaire 2026-05-20 13:43:24 +08:00
commit d57b9c1d2a

View file

@ -20,11 +20,12 @@ Use this as a template when you create your own checker.
- [Step 6: Wire It Up (main.go)](#step-6-wire-it-up-maingo) - [Step 6: Wire It Up (main.go)](#step-6-wire-it-up-maingo)
- [Step 7: Create the Plugin Entrypoint](#step-7-create-the-plugin-entrypoint) - [Step 7: Create the Plugin Entrypoint](#step-7-create-the-plugin-entrypoint)
5. [Optional: Standalone Human UI (`CheckerInteractive`)](#optional-standalone-human-ui-checkerinteractive) 5. [Optional: Standalone Human UI (`CheckerInteractive`)](#optional-standalone-human-ui-checkerinteractive)
6. [Running the Checker](#running-the-checker) 6. [Optional: Declaring rule prerequisites (`RulePrecheck`)](#optional-declaring-rule-prerequisites-ruleprecheck)
7. [Testing with curl](#testing-with-curl) 7. [Running the Checker](#running-the-checker)
8. [Deploying to happyDomain](#deploying-to-happydomain) 8. [Testing with curl](#testing-with-curl)
9. [License & happyDomain compatibility](#license--happydomain-compatibility) 9. [Deploying to happyDomain](#deploying-to-happydomain)
10. [Going Further](#going-further) 10. [License & happyDomain compatibility](#license--happydomain-compatibility)
11. [Going Further](#going-further)
--- ---
@ -470,6 +471,59 @@ Returning an error from `ParseForm` re-renders the form with the error message d
--- ---
## Optional: Declaring rule prerequisites (`RulePrecheck`)
Some rules cannot run unless the operator has supplied a prerequisite, typically an API key or auth token in an admin option. Without a way to advertise that, the UI shows the rule as if it were ready and the user only discovers the problem after a check returns an error. The SDK exposes an optional per-rule hook so the host can tell ahead of time which rules are usable with the current options.
```go
type RulePrecheck interface {
CheckRule
Precheck(ctx context.Context, opts CheckerOptions) error
}
```
Return `nil` when the rule is ready to run; return an error describing the missing prerequisite otherwise. The error message is shown verbatim to the operator, so name the option they need to set (`"VirusTotal API key is not configured"` is much more useful than `"missing key"`).
### Minimal implementation
```go
func (r *vtRule) Precheck(ctx context.Context, opts sdk.CheckerOptions) error {
if v, _ := opts["virustotal_api_key"].(string); v == "" {
return fmt.Errorf("VirusTotal API key is not configured")
}
return nil
}
```
### How the host consumes it
`GET /definition` is unchanged: it returns the static checker definition with no per-rule availability information. Whenever the host has a concrete set of options at hand (rendering the rule list with the user's admin/user settings, validating an edit, …) it issues a `POST /definition` carrying those options:
```bash
curl -X POST http://localhost:8080/definition \
-H "Content-Type: application/json" \
-d '{"options": {}}'
```
Response:
```json
{
"precheck_failures": {
"virustotal": "VirusTotal API key is not configured"
}
}
```
Rules that pass precheck, or that do not implement `RulePrecheck`, are absent from the map. The UI uses this to grey out unconfigured rules and surface the message returned by `Precheck`.
### Important: Precheck is advisory only
The SDK never calls `Precheck` from `Collect` or `Evaluate`. If the user enables a rule whose precheck fails and the host runs `/collect` anyway, your `Collect` (or the rule itself) still has to short-circuit and surface its own error: precheck is purely a UI hint, not an admission gate.
---
## Running the Checker ## Running the Checker
### Build and run locally ### Build and run locally