Files
LWLT-AIBOT/.project-docs/30-worklog/tasks/20260901-account-system-impl-d4e7a2.md

15 KiB
Raw Blame History

Task: Implement account isolation, roles, and audit

Identity

  • Task ID: 20260901-account-system-impl-d4e7a2
  • Mode: Feature
  • Branch: codex/20260901-account-system-impl-d4e7a2-account-system-impl-d4e7a2
  • Worktree: /Users/inmanx/Documents/lwltAPI-account-system-impl-d4e7a2
  • Base commit: ffa3340899
  • Owner: codex
  • Status: Ready for integration

Scope

  • Implement fixed-single-organization admin, team_lead, and user roles without adding organization selection or tenant administration.
  • Add administrator account lifecycle APIs and UI, self-service password change, session revocation, and last-administrator safety.
  • Enforce administrator-or-owner authorization for manual tasks, messages, events, artifacts, SSE, and browser execution paths.
  • Preserve creator and encrypted initial/supplemental input attribution, expose authorized audit history, and replace routine task deletion with archive/restore.
  • Add role-aware operator UI and table-driven security/regression coverage.
  • Add a team-lead/administrator-only, read-only operations dashboard for cross-user manual instruction history, work-status summaries, multi-dimensional business drill-through, and “who/instruction/result” detail.
  • Add administrator-managed per-account task-type authorization for all 18 registered manual business routes, with server-side fail-closed enforcement and denial audit.
  • Do not deploy, restart the existing 8786 service, access the real database/ERP, mutate real runtime tasks, or send data externally. A separately isolated local preview on port 8876 and PostgreSQL port 55432 is permitted by the user's explicit preview request.

Intent And Constraints

  • Existing organization_id remains an internal fixed deployment scope and compatibility boundary; it is not exposed as a product concept.
  • Existing users migrate as administrators. Administrators always retain all 18 manual business routes. New ordinary users and team leads start with no manual task-type authorization and can operate only explicitly granted routes for tasks they create; AgentBus/system tasks remain administrator-only and keep their separate channel authorization boundary.
  • Team leads gain cross-user visibility only through dedicated read-only dashboard APIs. That capability does not extend normal task mutation, artifact download, SSE, ERP execution, account administration, global audit, automation, parser, or AgentBus permissions.
  • Authorization is enforced in server/service/database access paths, never only by navigation visibility.
  • Unauthorized resource identifiers fail without revealing cross-user existence.
  • Initial and supplemental input remain encrypted at rest; password material and raw business input never enter audit or operational logs.
  • Organization-wide ERP execution serialization, confirmation, idempotency, uncertain-write, and requery safety gates remain unchanged.
  • Routine deletion becomes reversible archive/restore. Physical purge remains unavailable until an explicit retention policy is authorized.
  • Task-type authorization is re-read from PostgreSQL at every creation/continuation and before confirmation, automatic confirmation, and browser claim, so revocation takes effect without waiting for session expiry. A non-administrator instruction that cannot resolve to exactly one registered route fails closed.
  • The semantics and ERP contracts of the 18 registered business routes remain unchanged; this feature changes only which signed-in accounts may invoke each route.

Permission Contract

Surface Administrator Team lead Ordinary user
Login, logout, current user, CSRF, own password Allowed Allowed Allowed
Account list/create/status/role/reset/session revocation Allowed Denied Denied
Manual task-type authorization All 18 routes, fixed Explicit administrator grants only; default none Explicit administrator grants only; default none
Automation, parser routing/review/reparse, AgentBus channels, global audit Allowed Denied Denied
Normal task list/search/detail/events/input history All fixed-scope tasks Own non-AgentBus tasks only Own non-AgentBus tasks only
Create task/message/confirm/claim/result/cancel/archive/restore Any authorized task Own task only Own task only
Artifact download and SSE All fixed-scope tasks Own task only Own task only
Operations dashboard summaries and user directory All manual account tasks Read-only, all manual account tasks Denied
Operations dashboard instruction/attachment-name/business-result detail Read-only, all manual account tasks Read-only, all manual account tasks Denied
Browser heartbeat/connection Own authenticated connection Own authenticated connection Own authenticated connection
AgentBus/system tasks Allowed Not visible Not visible
Physical task purge Not exposed Not exposed Not exposed

Unauthorized task and artifact identifiers use the existing not-found response to avoid enumeration. Administrator-only settings and account endpoints use an explicit forbidden response.

Outcome

  • Added migration 015_account_roles_and_task_audit: existing accounts remain administrators; new admin/user roles, forced-password lifecycle fields, message/attachment actor attribution, reversible task archive fields, and account-scoped manual idempotency keys are persisted. No organization selector or tenant-management concept was added.
  • Added migration 016_team_lead_operations_dashboard: the fixed role constraint now accepts team_lead, and bounded manual-task indexes support time-, actor-, status-, and business-type-oriented dashboard reads.
  • Added migration 017_user_business_route_authorizations: durable fixed-scope per-user allowlists cover all 18 registered manual business routes, carry administrator attribution and optimistic authorization revisions, and enforce same-organization user/granter references. Schema readiness now requires migration 017.
  • Implemented administrator account management for list/create, enable/disable, role changes, password reset, and session revocation. Passwords remain Argon2id hashes, reset accounts can be forced to change password, role/status changes revoke sessions, and self-lockout plus removal of the last active administrator are blocked transactionally.
  • Enforced owner-restricted access for both ordinary users and team leads on task list/search/detail, messages, input history, artifacts, lifecycle mutations, browser claim/result, archive/restore, historical events, and live SSE. Both roles can access only their own manual tasks through normal business APIs; AgentBus/system tasks remain administrator-only. Browser connection IDs are user-bound and idempotency keys no longer collide across manual accounts.
  • Added authorized creator/original-input audit: task creator, every newly attributed user turn, attachment actor, lifecycle event actor, and account/task audit events are available to the authorized operator. Input contents and file names remain encrypted at rest; passwords and plaintext business input are not copied into the global audit log.
  • Replaced routine task deletion with archive/restore across the API, UI, retention job, and compatibility routes. Physical task/audit purge code is no longer exposed or retained in the task service.
  • Added role-aware platform pages for account management and global audit, mandatory/self-service password change, administrator-only settings navigation, creator/input history, per-user browser connection identity, and active/archived task views. Administrators can assign the new 组长 role.
  • Added an administrator-only task-permission panel in account management with all 18 business types, selected counts, select-all/clear, optimistic save protection, and effective authorization display. Administrators are permanently shown as fully authorized; new non-administrator accounts are clearly created with no task permissions until an administrator grants them.
  • Enforced the allowlist in the task service before initial parsing/plugin dispatch, on supplemental messages and passenger attachments, inside creation transactions, before manual and automatic confirmation, and before browser/ERP claim. Confirmation and claim evaluate the task creator rather than the acting administrator, so a revoked creator cannot be bypassed by an administrator. Non-administrators receive business_not_authorized for a known denied route or business_type_unresolved when the route is unknown/non-unique; both paths stop execution and return a business-readable Chinese prompt. Denial audit stores actor, route/revision, phase, and an input hash only—never the plaintext instruction—and explicitly records that parsing, plugin dispatch, and ERP writes did not run.
  • Added /operations-dashboard and leadership-gated GET APIs with a default 30-day window, a 366-day maximum, status/person/Shanghai-business-day/business-type drill-through, aggregate KPIs, per-user work summaries, bounded pagination, and on-demand business detail. Keyword query matches the creator, full initial and supplemental instructions, business type, readable business result, task record number, group number, and order number after structured filters; decrypted matching is bounded to 2,000 candidates. Dashboard queries include only manual tasks. Its dedicated list/detail contracts expose only who acted, what was instructed, what business outcome was recorded, business type, timestamps, and simplified input attachment attribution; lifecycle events, parser/executor JSON, technical stages/errors, and artifact access data are not returned. No dashboard mutation route exists.
  • Updated control-plane/README.md to describe the three-role account model, owner isolation, read-only operations dashboard, administrator-managed task-type allowlists, fail-closed enforcement, archive semantics, migrations 015/016/017, and the latest schema readiness gate.
  • Added table-driven three-role access-policy tests plus migration, authorization-path, dashboard, UI, audit, idempotency, and no-purge regression assertions. The 18 business routes and ERP serialization/write-safety contracts were not changed.
  • Upgraded only the isolated local preview on 127.0.0.1:8876: applied migration 017 to its dedicated PostgreSQL database, restarted only the preview process, assigned small demonstrative allowlists to the preview lead/Alice/Bob accounts, and verified a denied instruction did not create a task. The existing service on port 8786 remained on its original PID and was not touched.
  • No deployment, real-service restart, real database migration, ERP access, real runtime task mutation, secret read, or external message occurred.

Verification

  • node --run check:repo: 10/10 passed.
  • node --run check: passed.
  • node --run test:control-plane: 153/153 passed.
  • node --run test:legacy: 256/256 passed.
  • node --run build: passed.
  • node --check LianSyn-platform/app.js: passed.
  • git diff --check: passed.
  • Focused authorization regression (node --test --import tsx control-plane/test/account-authorization.test.ts control-plane/test/control-plane.test.ts): 60/60 passed.
  • Disposable PostgreSQL API smoke: new non-administrator denied by default; one granted route accepted; another ungranted route denied; only the authorized task persisted; two denials were durably audited.
  • Fresh disposable PostgreSQL migration: migrations 001–017 applied successfully, schema head was 017_user_business_route_authorizations, and the disposable database was removed afterward.
  • Isolated preview readiness: /health/ready reported database/schema ready with required migration 017; the account catalog returned all 18 task types; Alice, Bob, and the team lead received 2, 1, and 3 demonstrative grants respectively; Bob's ungranted “安排导游” instruction returned HTTP 403 business_not_authorized with the expected Chinese prompt.
  • check_project_docs.py: passed.
  • check_doc_drift.py --task-id 20260901-account-system-impl-d4e7a2: passed.

Follow-ups

  • Integrate this feature worktree before deployment, then apply migrations 015_account_roles_and_task_audit, 016_team_lead_operations_dashboard, and 017_user_business_route_authorizations and restart the control plane only under separate authorization.
  • In an authorized staging/runtime window, create one team-lead and two ordinary test accounts. Verify forced password change, default-deny task permissions, per-route grant/revoke without re-login, known-route and unresolved-route denial prompts, no parsing/plugin/ERP side effects on denial, creator-based revocation at confirmation/claim, own-task visibility, cross-user 404 behavior on normal task/artifact/SSE paths, AgentBus invisibility, dashboard denial for ordinary users, and team-lead cross-user drill-through by status/person/date/business plus keyword hits in supplemental instructions and completed business results. Also verify the dashboard response contains no lifecycle/parser/executor/artifact-access data, then cover account session revocation, creator/input audit, and archive/restore against PostgreSQL and independent browser sessions.
  • Keep physical purge unavailable unless a separately approved retention design defines legal/audit retention periods and privileged irreversible-purge controls.

Promotion Candidates

  • Target canonical architecture/security/current-state memory during a later Integration task.
  • Proposal: record the fixed-scope account model as admin, team_lead, and user, with no product-visible organization concept. Team leads retain ordinary-user ownership boundaries for business operations but receive dedicated cross-user, manual-task-only, read-only operations-dashboard access; administrators retain global settings, AgentBus/system tasks, account lifecycle, and global audit.
  • Proposal: record the operations dashboard as a business-facing projection rather than a privileged task-debug surface: status/person/Shanghai-day/business drill-through and bounded plaintext matching are permitted, while lifecycle events, parser/executor payloads, technical stages/codes, and artifact access remain outside its response contract.
  • Proposal: record creator/input attribution, account-scoped idempotency, user-bound browser connections, forced password change/session revocation, last-administrator protection, and archive/restore as security invariants.
  • Proposal: record manual business eligibility as an administrator-managed allowlist over the 18 registered routes: administrators are always fully authorized, team leads/users default to none and require explicit grants, unknown/non-unique routes fail closed, revocation is checked at each state transition, and AgentBus keeps its independent channel boundary.
  • Evidence: control-plane/migrations/015_account_roles_and_task_audit.sql, control-plane/migrations/016_team_lead_operations_dashboard.sql, control-plane/migrations/017_user_business_route_authorizations.sql, control-plane/src/auth.ts, control-plane/src/task-service.ts, control-plane/src/server.ts, LianSyn-platform/index.html, LianSyn-platform/app.js, LianSyn-platform/styles.css, control-plane/README.md, and control-plane/test/account-authorization.test.ts plus the full verification above.
  • Human confirmation required: already received for the single-organization three-role ownership/audit/dashboard behavior; integration, database migration, deployment, restart, and live smoke testing remain separately authorized.