fix: isolate ERP queues and force deletion by account
This commit is contained in:
1 parent
69ea6d2517
commit
d09b3032c0
9 files changed
+677
-97
No files matched your search
@@ -0,0 +1,69 @@
|
||||
# Task: Scope ERP queues per account and restore hard delete
|
||||
|
||||
## Identity
|
||||
|
||||
- Task ID: 20260902-per-account-queue-hard-delete-a6d9f2c1
|
||||
- Mode: Feature
|
||||
- Branch: codex/20260902-per-account-queue-hard-delete-a6d9f2c1-per-account-queue-hard-delete
|
||||
- Worktree: /Users/inmanx/Documents/lwltAPI-per-account-queue-hard-delete-a6d9f2c1
|
||||
- Base commit: 69ea6d25178d75abf8d7fd728bd31c61764caa7d
|
||||
- Owner: codex
|
||||
- Status: Ready for Integration
|
||||
|
||||
## Scope
|
||||
|
||||
- Replace organization-wide ERP claim serialization with an account-scoped claim lock and account-scoped active/confirmed FIFO checks.
|
||||
- Preserve FIFO ordering for tasks assigned to the same platform/ERP account while allowing tasks assigned to different accounts to be claimed and executed independently.
|
||||
- Keep reversible archive/restore as a separate operation, and restore `DELETE /api/tasks/:taskId` plus bulk-delete as permanent physical task deletion.
|
||||
- Allow permanent deletion regardless of parse, handoff, queue, or ERP execution state, while retaining organization/account access control.
|
||||
- Remove task-owned database rows through existing cascades, request post-commit OSS artifact cleanup, and invoke the existing local extension hard-delete bridge on a best-effort basis.
|
||||
- Update the operator UI and regressions so archive/restore and irreversible force-delete are visibly distinct.
|
||||
- Separate administrator-wide read visibility from executable routing: task SSE, automatic handoff, plugin result ingestion, and force-delete cleanup commands must be delivered only to the task's immutable `assigned_user_id`.
|
||||
|
||||
## Intent And Constraints
|
||||
|
||||
- The user explicitly superseded AUTH-001's organization-wide ERP FIFO and archive-only removal decisions for this task. Canonical decision and architecture updates remain Promotion Candidates for a later Integration task.
|
||||
- A single account still has at most one active ERP execution and a deterministic FIFO of confirmed tasks; one account's active or queued task must not affect another account's claim result or queue position.
|
||||
- Force delete is authoritative physical deletion and must not call the archive state gate. It is not an ERP rollback: already-written ERP data cannot be undone by deleting the platform record.
|
||||
- A minimal `task.hard_deleted` audit event may remain as evidence of the destructive action; task content, events, attempts, sessions, inputs, artifacts, and delivery rows must be removed with the task.
|
||||
- OSS cleanup is post-commit and best effort so storage unavailability cannot resurrect or block an already-authorized database deletion.
|
||||
- Do not change Chrome extension source/version: its existing `DELETE_TASK` / `LTJT_HARD_DELETE_TASK` path already performs local cancellation and cache removal.
|
||||
- An administrator may still view organization tasks, but viewing authority must never authorize confirmation, claim, result submission, plugin-result handling, or receipt of another account's execution event/command.
|
||||
- Do not deploy, restart services, mutate production tasks, operate ERP, or inspect secrets in this Feature task.
|
||||
|
||||
## Outcome
|
||||
|
||||
- `claimForBrowser` now uses an advisory transaction lock keyed by organization and executing user instead of locking the organization row. Both active-execution detection and confirmed FIFO selection are filtered by the locked task's account, so same-account work remains serialized while different accounts do not block or affect queue positions.
|
||||
- Added `hardDeleteTask` and atomic `hardDeleteTasks` service operations. They preserve organization/owner access checks, intentionally omit status/handoff gates, write a minimal `task.hard_deleted` audit marker, remove task outbox entries, physically delete task rows, rely on existing cascades for all task-owned database records, and request post-commit OSS cleanup.
|
||||
- `DELETE /api/tasks/:taskId` and `POST /api/tasks/bulk-delete` now use physical deletion; `/archive`, `/restore`, and `/bulk-archive` remain reversible and retain their active-task archive guard.
|
||||
- The task detail and history UI now expose archive/restore separately from red permanent force-delete controls. Force delete works for active, waiting, archived, and terminal tasks, presents an explicit irreversible/ERP-write warning, removes local caches, and uses the existing `DELETE_TASK` extension bridge as best-effort cancellation/cleanup after server deletion.
|
||||
- History selection and bulk force-delete are available for both active and archived views. Active tasks that cannot be archived can still be permanently deleted.
|
||||
- `/api/events` is now explicitly an executable wake-up feed. Historical and live task events are unconditionally filtered by the authenticated account's `assigned_user_id`, including for administrators; the administrator's organization-wide task-list visibility no longer enters SSE dispatch routing. The reconnect cursor is likewise derived only from the current account's tasks.
|
||||
- Plugin `TASK_RESULT_CHANGED` broadcasts, queued result persistence, and direct result polling now fail closed in the page unless the local task is assigned to the current authenticated account. This prevents an administrator page from attempting to persist another user's extension result and surfacing the resulting authorization rejection as a false task error.
|
||||
- Hard delete emits a post-commit `browser-command` addressed only to each deleted task's assigned account. An online owner page uses the existing `DELETE_TASK` bridge to stop/clean its own plugin state; an administrator deleting an employee task never sends that cleanup command to the administrator's local plugin. Direct best-effort cleanup is also filtered to locally assigned tasks.
|
||||
- Updated control-plane implementation documentation and regression coverage. No database migration or Chrome extension source/version change was required.
|
||||
|
||||
## Verification
|
||||
|
||||
- `node --check LianSyn-platform/app.js` — passed.
|
||||
- `node --run check` — passed.
|
||||
- `node --run test:control-plane` — passed, 162/162.
|
||||
- `node --run test:legacy` — passed, 268/268.
|
||||
- `node --run check:repo` — passed, 10/10.
|
||||
- `node --run build` — passed.
|
||||
- Focused account/routing/queue/delete regression — passed, 14/14.
|
||||
- Focused account plus core control-plane regression — passed after the added account-isolation coverage.
|
||||
- `git diff --check` — passed.
|
||||
|
||||
## Follow-ups
|
||||
|
||||
- Run an Integration Gate to resolve the intentional conflict with AUTH-001 and promote the accepted per-account FIFO plus explicit physical-delete behavior into canonical project memory.
|
||||
- Merge/integrate this Feature branch before any rollout. Production deployment, service restart, and live task mutation were not performed and still require explicit user authorization.
|
||||
- After an authorized rollout, smoke-test with an administrator plus two distinct assigned accounts: keep one employee account executing while confirming that the other employee account claims immediately; verify the administrator receives no employee executable SSE/result handoff; then force-delete a waiting and an active disposable employee task and verify database absence plus cleanup only in the owning employee plugin.
|
||||
|
||||
## Promotion Candidates
|
||||
|
||||
- Supersede AUTH-001's organization-wide ERP FIFO clause with account-scoped FIFO: each `assigned_user_id` owns one serialized ERP queue, while different assigned accounts execute independently.
|
||||
- Supersede AUTH-001's archive-only removal clause: archive/restore remains the routine reversible path, while explicitly confirmed force delete permanently removes a task regardless of state and cannot roll back prior ERP effects.
|
||||
- Record the invariant that administrator-wide read visibility is never execution authority: executable lists, SSE wake-ups, browser claims, plugin results, and browser cleanup commands are all scoped to immutable task assignment.
|
||||
- Update `.project-docs/20-architecture/system-overview.md`, `.project-docs/20-architecture/data-flow.md`, `.project-docs/40-domain/business-rules.md`, `.project-docs/40-domain/success-criteria.md`, and `.project-docs/30-worklog/current-state.md` after Integration acceptance.
|
||||
Reference in new issue
Block a user