add operator review workflow
This commit is contained in:
@@ -99,6 +99,16 @@ Creation must use a tenant-scoped idempotency key and request fingerprint. A rep
|
||||
|
||||
There is no SSE handler, durable queue, scan worker/isolation boundary, or worker process in Compose; its in-process worker and SQLite job/event tables are pilot-only. Process loss can lose work, there is no durable lease/recovery or horizontal coordination, and it must not be presented as production execution. Redis and Celery are not implemented.
|
||||
|
||||
## Phase 11 dashboard and review workflow operations
|
||||
|
||||
Operate saved filters as tenant-scoped configuration. Before exposing save/load/update/delete, verify the filter schema, server-side bounds, owner/share permissions, stable ordering, page-size maximum, retention/deletion behavior, and audit event format. A filter is not a permission grant; never troubleshoot a missing record by removing tenant or eligibility predicates.
|
||||
|
||||
The review queue must display the exact filter/predicate snapshot, whether each count is for the current page or the full matching set, and pagination/cursor state. Re-check tenant scope and current suppression/merge state when a row is opened or acted on. Suppressed/do-not-contact records remain blocked; merged/non-active records are not merge-eligible. A clickable count is safe only when it reuses the same bounded, tenant-scoped predicate; do not interpret stale, loading, or failed counts as zero.
|
||||
|
||||
For each bulk operation, verify the server-reported selection size and maximum, inspect the preview, obtain explicit operator confirmation, and ensure an idempotency key/correlation ID is recorded. The server must re-check permissions, tenant ownership, suppression, and merge eligibility at execution. Read back the per-record outcomes and audit event; investigate skipped/failed records and partial completion rather than retrying blindly. Never run an unbounded “all results” action from a count, and never describe bulk review as outreach or automatic deduplication.
|
||||
|
||||
Monitor saved-filter errors, queue count freshness, pagination/cursor failures, cross-tenant denials, suppression/eligibility skips, batch-limit violations, idempotency conflicts, partial bulk failures, audit append/readback failures, and merge snapshot/reversal outcomes. Preserve filter/selection snapshots or safe hashes and bounded totals in operational records, but redact secrets and unnecessary contact data. The current Compose/MVP runtime includes saved-filter creation/listing, a bounded review queue, clickable dashboard metadata, and explicit verify/reject/assign bulk review actions. It remains pilot-only: the remaining Phase 11 limitations are that update/delete saved-filter routes are not wired, queue counts lack complete matching-set/predicate snapshots, bulk operations have no preview/idempotency/per-record result contract, and the audit trail records a batch aggregate. Treat these as release blockers until the API/UI slices are hardened and verified.
|
||||
|
||||
## Configuration and deployment
|
||||
|
||||
Copy `.env.example` for local development. Production values must be supplied by the deployment environment, never committed. `BOOTSTRAP_ADMIN_EMAIL` and `BOOTSTRAP_ADMIN_PASSWORD` are optional API environment variables for first-run admin provisioning only; set them together through a secret store or protected deployment environment, remove them immediately after successful bootstrap, and rotate the password. Do not put real values in Compose files, CI variables visible to logs, images, or committed `.env` files.
|
||||
|
||||
@@ -87,6 +87,16 @@ If a future approved adapter fetches URLs, apply the SSRF requirements below in
|
||||
|
||||
Phase 10 is not production-ready until rule-set lifecycle permissions/approval, immutable snapshots, audit tamper resistance, retention/deletion policy, concurrency/rollback behavior, and regression tests for suppression precedence, stale/uncertain handling, replay/reproducibility, and tenant isolation are complete.
|
||||
|
||||
## Phase 11 dashboard and review workflow security controls
|
||||
|
||||
- Saved filters are tenant-owned data, not authorization. Validate and bound every predicate server-side; scope list/read/write/delete by the authenticated organization, reject unknown fields and unbounded limits, and keep filter definitions free of secrets. Any shared filter must remain within the tenant with explicit read/write permissions.
|
||||
- Review-queue membership and counts must be derived under the caller's tenant and permission predicate. A count, filter ID, cursor, or selected business ID must never grant access. Suppression/do-not-contact always overrides score, review status, or bulk selection; merged/non-active records are not merge-eligible.
|
||||
- Bulk actions require a server-enforced batch maximum, explicit selection or immutable filter snapshot, preview plus confirmation, authorization and state re-checks at execution, and idempotent/safely retryable behavior. Return bounded per-record outcomes and fail closed on cross-tenant, suppressed, stale, or ineligible records. Bulk review actions must not become an outreach or automatic-merge path.
|
||||
- Clickable counts must preserve the exact tenant-scoped predicate used to calculate them and clearly distinguish page counts from full matching-set counts. Never use a client-side count as a security decision; loading/error/unavailable must not collapse to zero and leak scope or state.
|
||||
- Audit every saved-filter mutation, queue assignment/decision, bulk preview/confirmation/execution, skip/failure, suppression/eligibility decision, and merge/reversal. Record tenant, actor, action, timestamp, filter/selection snapshot or safe hash, bounded counts, per-item outcomes, policy/version, and correlation/idempotency ID. Protect audit reads with the same tenant predicate, redact secrets/full contact values where unnecessary, and define retention/deletion and tamper-evidence before production.
|
||||
|
||||
Phase 11 is present in the current Compose source with durable saved-filter storage, a bounded review queue, clickable dashboard metadata, and explicit bulk review actions. It is not production-ready: saved-filter update/delete routes are not wired, queue/count responses lack complete predicate and matching-set semantics, bulk actions lack preview/idempotency/per-item outcomes, and audit coverage is aggregate for a batch. Do not infer stronger guarantees from the UI. Before release, add cross-tenant, suppression-precedence, merge-eligibility, count-scope, replay/idempotency, partial-failure, and audit-completeness tests.
|
||||
|
||||
## Known limitations before production
|
||||
|
||||
1. **Password storage:** production passwords must be hashed with Argon2id using a reviewed cost/memory/parallelism policy. Never store plaintext or reversible passwords, and never log bootstrap credentials. Rehash on login when the policy changes.
|
||||
|
||||
Reference in New Issue
Block a user