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

105 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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: ffa33408997c3e822dd8293fbca0739c72ff3d01
- 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.