Repository navigation
feat(ssp-templates): run, created SSPs and forget routes - #526
Merged
gusfcarvalho merged 2 commits intoOct 22, 2026
Merged
Conversation
|
Important Review skippedBot user detected. To trigger a single review, invoke the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This was referenced Oct 19, 2026
POST /admin/ssp-templates/{id}/run queues a discovery run (409 when the
template is disabled). GET /admin/ssp-templates/{id}/ssps lists the SSPs the
template created with their key hash, stale flag, last error and skipped
entries. DELETE /admin/ssp-templates/{id}/ssps/{keyHash} forgets an instance
whose SSP was deleted, so discovery creates it again.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ccf-lisa
Bot
force-pushed
the
feat/ssp-templates-5-routes
branch
from
October 19, 2026 14:53
eccb082 to
04f2c92
Compare
gusfcarvalho
pushed a commit
that referenced
this pull request
Oct 22, 2026
## Place in the stack SSP templates (feature 2 of `ssp-templates.md`), PR **B1 of 5** (B1–B5: #522, #523, #524, #525, #526), stacked on the SSP scope stack (#516–#520, top `feat/ssp-scope-5-auto-filters`). ## What it adds - Models `SSPTemplate` and `SSPTemplateInstance` (`internal/service/relational/ssp_templates.go`), in both AutoMigrate lists and both drop lists. Their foreign keys (instance → template `ON DELETE CASCADE`, instance → SSP `ON DELETE SET NULL`) are added by `EnsureSSPConstraints`, which is `EnsureSSPScopeConstraints` renamed, with two keys appended. AutoMigrate here does not enforce gorm FK tags. - Package `internal/service/relational/ssptemplates`: - `Build`: validation and normalization. Keys are trimmed, lower-cased and sorted (1–5). Scope-label groups are normalized the same way (≤10 groups of 1–5 labels). Keys and labels follow `sspscope.Normalize`'s key rules, so anything a template accepts can be stored as a scope entry. `min-streams` must be ≥ 1. The title template is required, and the title, description and prop templates must parse. The labelfilter must be valid. - `Service`: list/get/create/update/delete. Profile ids must exist. Keys cannot change on update (400). - Admin routes `/api/admin/ssp-templates` (list, create, get, update, delete), behind `JWTMiddleware` + `pep.Authorize(authz.ResourceAdmin, authz.ActionManage)`, like `/admin/subject-templates`. JSON is kebab-case. Swagger is regenerated. - **Contract addition from review**: template responses also return `ssp-count` and `last-run-at`. - `ssp-count` is the number of instances whose SSP still exists. - `last-run-at` is a new nullable `last_run_at` column. It stays `null` until B4's discovery job sets it, and Update preserves it. Not in this PR: preview (B3), SSP creation (B2/B4), discovery, run, instances routes (B4). ## How it was tested - Unit: `ssptemplates/validate_test.go`. It covers normalization, defaults, and every rejection rule. - Integration (`internal/api/handler/templates/ssp_template_integration_test.go`) runs under the embedded Cedar PDP: - an admin creates, lists, gets, updates and deletes templates; - changing keys is rejected; - a contributor gets 403 on every route; - 400/404 cases; - the FK behaviour and `ssp-count`: deleting an SSP nulls its instance's `ssp_id` and drops it from `ssp-count`, and deleting a template drops its instances and keeps its SSPs. - Gate on this branch: - `make swag`, `make lint` (only the existing SA1019 in `internal/api/metrics.go`), `make test`, `go vet -tags integration ./...`; - integration suites of `internal/api/handler`, `internal/api/handler/templates`, `internal/service`, `internal/service/relational`, `internal/service/relational/sspscope`; - `make check-diff`. Changed lines excluding generated swagger: 1000. ## Deviations from design - The instance model has exactly the design's fields. The `skipped-entries` count and sample reported by the instances route are added in B4, with the code that writes them. - Duplicate scope-label groups (after normalization) are rejected with 400, not merged silently. Duplicate profile ids are de-duplicated. - An empty filter (`{}` / `{"scope":{}}`) matches everything, so it is stored as no filter. - The `enabled` column has no database default (the design has `default:true`). gorm writes a column default over a false `Enabled` on create, so a disabled template was stored as enabled. `Build` always sets `Enabled`, with nil meaning true. - The list route is paginated (`svc.ListResponse`, `page`/`limit`) like subject templates. - The response timestamps are kebab-case (`created-at`/`updated-at`), unlike subject templates' camelCase ones. ## Open questions for reviewers - Templates are only checked to parse. Should save also reject templates that reference a field that is not one of the keys (keys are lower-cased, so `{{ ._APP }}` would render empty)? The design asks only for parse errors. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: ccf-lisa[bot] <286799724+ccf-lisa[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Place in the stack
SSP templates (feature 2 of
ssp-templates.md), PR B5 of 5. It is the second half of the design's B4, split to keep each PR under 1000 lines. Base: B4 (#525,feat/ssp-templates-4-discovery). Below it: B3 (#524), B2 (#523), B1 (#522) and the SSP scope stack (#516–#520).What it adds
All three routes sit behind the existing
/api/admin/ssp-templatesgroup: JWT +admin:manage.POST /api/admin/ssp-templates/{id}/runqueues a discovery run of the template (ssp_template_discoverywith the template id as args) and answers 202.worker.Service.EnqueueSSPTemplateDiscoveryimplements the newtemplates.SSPTemplateRunEnqueuer, wired throughAPIServices.SSPTemplateRunEnqueuerincmd/run.go.GET /api/admin/ssp-templates/{id}/sspsis paginated and newest first. Each item has:key-valuesandkey-hash(a contract addition from review: the forget route's id);ssp-id(null once the SSP was deleted) and the SSP's currenttitle;created-atandlast-seen-at;stale: the SSP exists and was last seen more thanCCF_SSP_TEMPLATE_STALE_AFTERago (from B4's config);last-error,skipped-entriesandskipped-sample.DELETE /api/admin/ssp-templates/{id}/ssps/{keyHash}forgets an instance whose SSP was deleted, so the next run creates it again. It answers 409 while the SSP exists and 404 for an unknown instance.Swagger is regenerated.
How it was tested
ssp_template_instances_integration_test.go):make swag,make lint(only the existing SA1019),make test,go vet -tags integration ./...;internal/api/handler,internal/api/handler/templates,ssptemplates,internal/service/worker;make check-diff.Changed lines excluding generated swagger: 395.
Deviations from design
title,key-hash(contract addition) andskipped-sampleto the design's fields.Open questions for reviewers
🤖 Generated with Claude Code