Outcome
Change whether a Consent project is eligible for scheduled cookie scanning and choose a daily or weekly cadence. Saving these settings does not run a scan.
Action: app_topolo_consent.cookie_scanner.settings.update.
PUT /api/projects/{projectKey}/cookie-scanner/settings
Before you start
-
Verify the original credential, production environment, organization and actual canonical Consent workspace. Discover the intended project key inside that workspace and bind the workspace separately; a project key is not a workspace id or access grant.
-
The PUT cookie-scanner/settings route requires a verified admin-level workspace grant plus app_topolo_consent.workspace:write. The verification read separately requires workspace:read. Organization membership or read_write alone does not establish the admin level. Preserve original API-key resource restrictions and stop after a refusal.
-
Review current settings and the intended change before approval. Enabling the policy can make the project eligible for future configured-domain HTTPS scans and completion callbacks when its scheduler actually runs. Approval for a settings change is not permission to launch an unrelated manual scan. Confirm with the existing service owner that scanner storage and the intended scheduled worker are configured before relying on automatic execution.
Request
{
"projectKey": "project_fixture_docs",
"enabled": true,
"cadence": "weekly"
}
The project key is fictional and the example is unrun. Discover actual scope and settings, validate/plan the exact intended input and obtain approval before a real mutation. enabled and cadence are optional; projectKey is required. nextRunAt, lastRunAt, organization and workspace fields are not accepted in the action input.
Scheduling and storage behavior
The worker authenticates, verifies the original caller’s workspace with route-derived minimumAccess:admin and applies workspace:write before this handler. requireAdminProject requires control storage, a scoped reachable project and a non-archived project; no permission or project identity comes from the body.
The handler reads current settings, replaces enabled only when supplied as a boolean and cadence only when daily/weekly, then calls nextCookieScannerSettings with completedRun:false. Omitted fields retain their normalized current values; an input containing only projectKey is still a write and can move an enabled schedule.
Disabling sets nextRunAt:null and keeps lastRunAt/cadence. When enabled, the next time is the existing valid nextRunAt plus one selected daily/weekly interval; if no valid stored time exists it uses the current clock plus the interval. It is not always now+interval, and re-saving an already enabled configuration can postpone it again. This operation does not set lastRunAt or perform a completed scan.
Normal output is {settings:{enabled,cadence,lastRunAt,nextRunAt}}. It does not add success:true, a scan result, delivery receipt or project object. Returned settings are computed by this request; they are not, by themselves, proof of storage persistence or scheduled execution.
writeCookieScannerSettings writes the project’s settings to KV, then separately reads/updates the shared scanner index. Enabled adds the project key; disabled removes it. The index is capped at500 keys. These are separate non-transactional operations with no accepted expected-version/CAS/idempotency field; a settings write can precede an index failure, and concurrent updates can lose index changes.
If CONSENT_CONFIG is unbound, the settings write returns without persisting anything and the handler can still return HTTP200 with its computed settings. The settings reader returns disabled/daily/null/null when KV is missing or a read fails. Do not mistake those defaults for stored state, or matching disabled defaults for persistence proof. Existing service ownership must qualify the binding and actual read-back before the operation is considered verified.
This settings handler does not fetch a domain, call a model/provider or send a notification. The separate scheduled runner reads only the first50 index entries per invocation before checking due times and active projects; no fairness or coverage of later entries is established. A later actual scan fetches at most25 configured normalized domains and can invoke a completion callback. Enabled, nextRunAt or HTTP200 does not prove that such a scan ran, completed or delivered a notification.
Complete worked responses
Disable scanning while retaining prior cadence and history time
Complete synthetic source-derived/unrun response. Assumes an active scoped fixture project, verified admin/write authority, bound scanner KV and current settings enabled:true/cadence:weekly/lastRunAt as shown. No settings write or scan occurred.
Input:
{
"projectKey": "project_fixture_docs",
"enabled": false
}
Response:
{
"settings": {
"enabled": false,
"cadence": "weekly",
"lastRunAt": "2026-10-19T08:00:00.000Z",
"nextRunAt": null
}
}
Verify actual persisted settings and index removal independently; the returned flag alone does not prove either.
Change an enabled schedule from daily to weekly
Complete synthetic source-derived/unrun response. Assumes prior nextRunAt2026-10-22T08:00:00.000Z, prior lastRunAt as shown, valid bound storage and the original caller’s approved admin-level mutation. The seven-day interval is added to the stored next time, not assumed to begin at the request clock.
Input:
{
"projectKey": "project_fixture_docs",
"enabled": true,
"cadence": "weekly"
}
Response:
{
"settings": {
"enabled": true,
"cadence": "weekly",
"lastRunAt": "2026-10-21T08:00:00.000Z",
"nextRunAt": "2026-10-29T08:00:00.000Z"
}
}
Confirm the schedule calculation and persisted state. Do not retry the same write merely to recheck it, or infer an actual scan from the next-run value.
Refuse an archived project
Synthetic source-derived/unrun HTTP409 refusal. Assumes caller verification, admin-level workspace and write permission passed, and the scoped stored project is archived. That state is an external fixture precondition, not an input field.
Input:
{
"projectKey": "project_fixture_docs",
"enabled": true,
"cadence": "daily"
}
Response:
{
"error": "project_archived"
}
Preserve the refusal; restoration or another project is a separate authorized decision.
Verify and recover
Discover app_topolo_consent.cookie_scanner.history.list with the original credential and same actual projectKey/workspace. Its current route returns settings plus history; workspace:read eligibility is required. Compare the intended enabled/cadence and schedule meaning, preserving actual returned state and request evidence.
Qualify that the service’s scanner KV storage is available before accepting read-back as persistence evidence. Missing/error fallback defaults are not stored settings. A returned enabled flag or matching timestamp is not scheduler admission, scan completion, history integrity or notification delivery proof.
For an uncertain or partial write, read settings/history and ask the existing owner to reconcile the scanner index as well as the per-project settings. Do not repeatedly save to force equality: saving can advance nextRunAt, and the public action does not expose index repair. Preserve concurrent-owner changes.
There is no transactional rollback across settings and index. After reconciling current state/concurrency and storage, a separately approved call can restore known prior enabled/cadence values. This action cannot directly restore the exact prior nextRunAt or lastRunAt because those are not accepted input fields; an enabled re-save recalculates the schedule. It cannot undo scans or notifications that may already have occurred. Preserve uncertain index state and route its repair to the existing service owner; never invent direct KV or timestamp writes.
Refusals
404 / project_not_found: Reconcile the actual key within the original verified organization/workspace; do not guess keys or broaden scope.
409 / project_archived: Do not configure an archived project. Any restoration requires separate current-contract review and authority.
503 / database_unavailable: The control-storage dependency is missing. Preserve actual request/error evidence and ask its existing service owner to restore it before an authorized retry.
An unsupported cadence such as hourly is a local schema-validation refusal, not a captured HTTP response. Original Auth/permission/workspace checks occur earlier and can return their actual shared carrier. The handler has no local catch for KV write failures; preserve the real outer error/request evidence instead of inventing a precise response body or assuming no write occurred.
Change log
- 2026-10-21: Added the exact admin access requirement, schedule arithmetic, persistence/index limits, complete illustrative unrun responses and compensation boundaries. Saving settings and observing a returned flag are distinguished from verified persistence and an actual scheduled scan.