Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
200 lines
22 KiB
Markdown
200 lines
22 KiB
Markdown
# Scratchpad — Workflow Time Actions
|
||
|
||
- Plan slug: `2026-04-27-workflow-time-actions`
|
||
- Created: `2026-04-27`
|
||
|
||
## What This Is
|
||
|
||
Rolling notes for adding workflow-safe time-entry, time-sheet, and billing-readiness actions to the workflow action registry.
|
||
|
||
## Decisions
|
||
|
||
- (2026-04-27) Scope option selected: core time entry actions, core time sheet actions, and readiness helpers. Timers and broad picker expansion can be deferred unless required by core flows.
|
||
- (2026-04-27) Implementation approach selected: create workflow-safe helpers/services that preserve canonical time module behavior, then build workflow actions on top of those helpers. Do not continue direct DB writes that bypass time-entry business logic.
|
||
- (2026-04-27) Existing `time.create_entry` should be treated as incomplete/prototype behavior and brought onto the canonical helper path rather than expanded as-is.
|
||
- (2026-04-27) Picker scope decision (`F028`): keep phase-1 fixed picker expansion minimal to currently supported infrastructure (user/ticket + textarea metadata). Service/contract/time-entry/time-sheet/time-period dedicated fixed pickers are explicitly deferred; schema descriptions and dynamic-reference support remain the fallback for those IDs.
|
||
|
||
## Discoveries / Constraints
|
||
|
||
- (2026-04-27) Current workflow action file: `shared/workflow/runtime/actions/businessOperations/time.ts`.
|
||
- (2026-04-27) Existing `time.create_entry` directly inserts into `time_entries`, uses `billing_plan_id`, computes `work_date` from UTC, and does not attach to a time sheet or resolve `service_id`/`contract_line_id` behavior.
|
||
- (2026-04-27) Canonical scheduling behavior lives primarily in `packages/scheduling/src/actions/timeEntryCrudActions.ts`, `timeSheetOperations.ts`, and `timeSheetActions.ts`.
|
||
- (2026-04-27) Important canonical side effects include `service_id` validation, user timezone work-date computation, time-sheet period validation, default contract line resolution, bucket usage updates, project-task actual-hours updates, ticket/task resource updates, invoiced-entry guards, and change-request handling.
|
||
- (2026-04-27) API time-entry service exists at `server/src/lib/api/services/TimeEntryService.ts`, but it has its own behavior and should not be blindly treated as the canonical source without reconciliation.
|
||
- (2026-04-27) Workflow fixed pickers currently support board, client, contact, user, user-or-team, ticket, ticket-status, ticket-priority, ticket-category, ticket-subcategory, and client-location. They do not currently support service catalog, contract line, time entry, time sheet, time period, project task, interaction, or non-billable category resources.
|
||
- (2026-04-27) Event schemas for `TIME_ENTRY_SUBMITTED` and `TIME_ENTRY_APPROVED` exist in `shared/workflow/runtime/schemas/timeEventSchemas.ts`, but current workflow-trigger publication appears limited; ticket time entry added publication is handled by `server/src/lib/api/services/timeEntryWorkflowEvents.ts`.
|
||
- (2026-04-27) `packages/scheduling/src/services/bucketUsageService.ts` requires tenant inference via `createTenantKnex()` when transaction config does not carry tenant metadata; workflow runtime already has explicit tenant context, so directly calling that service from workflow helper would be fragile in shared Vitest DB tests.
|
||
|
||
## Commands / Runbooks
|
||
|
||
- (2026-04-27) Initial investigation used `rg` across `server`, `shared`, `packages`, and `ee` for `time_entries`, `time_sheets`, `time.create_entry`, and workflow picker support.
|
||
- (2026-04-27) Validate plan JSON after edits: `python scripts/validate_plan.py ee/docs/plans/2026-04-27-workflow-time-actions` if the validator supports folder input; otherwise run project JSON validation or `python -m json.tool` on each JSON file.
|
||
|
||
## Links / References
|
||
|
||
- `shared/workflow/runtime/actions/businessOperations/time.ts`
|
||
- `shared/workflow/runtime/actions/registerBusinessOperationsActions.ts`
|
||
- `shared/workflow/runtime/designer/actionCatalog.ts`
|
||
- `shared/workflow/runtime/jsonSchemaMetadata.ts`
|
||
- `packages/scheduling/src/actions/timeEntryCrudActions.ts`
|
||
- `packages/scheduling/src/actions/timeSheetOperations.ts`
|
||
- `packages/scheduling/src/actions/timeSheetActions.ts`
|
||
- `packages/scheduling/src/actions/timeEntryServices.ts`
|
||
- `packages/scheduling/src/actions/timeEntryHelpers.ts`
|
||
- `server/src/lib/api/services/TimeEntryService.ts`
|
||
- `server/src/lib/api/schemas/timeEntry.ts`
|
||
- `server/src/lib/api/services/timeEntryWorkflowEvents.ts`
|
||
- `shared/workflow/runtime/schemas/timeEventSchemas.ts`
|
||
- `ee/server/src/components/workflow-designer/WorkflowActionInputFixedPicker.tsx`
|
||
|
||
## Open Questions
|
||
|
||
- Should time actions keep `time.create_entry` at version 1 with corrected semantics, add version 2, or add a new action id and deprecate the current action?
|
||
- Should phase 1 include new fixed pickers for service, contract line, time entry, time sheet, and time period, or should these fields remain reference/manual UUID inputs initially?
|
||
- Should this plan include publishing/trigger improvements for time-sheet submitted/approved and time-entry approval events, or remain action-only except for using existing events?
|
||
|
||
## Progress Log
|
||
|
||
- (2026-04-27) Implemented workflow-safe create-entry domain boundary in `shared/workflow/runtime/actions/businessOperations/timeDomain.ts`.
|
||
- New helper signature is explicit: `{ trx, tenantId, actorUserId, input }`.
|
||
- Helper performs service/work-item existence checks, computes user-timezone work-date fields, resolves/creates time sheets by work date, and applies ticket/task side effects.
|
||
- Output is normalized summary payload intended for workflow runtime consumers.
|
||
- (2026-04-27) Replaced direct-write `time.create_entry` handler logic in `shared/workflow/runtime/actions/businessOperations/time.ts` to call `createWorkflowTimeEntry(...)`.
|
||
- Decision: keep `time.create_entry@v1` and migrate semantics in place; retain `billing_plan_id` as a compatibility alias to `contract_line_id`.
|
||
- Added structured domain error mapping via `WorkflowTimeDomainError` -> runtime `throwActionError` categories.
|
||
- Added normalized output schema: `time_entry` object with ids, duration/billable minutes, work date/timezone, sheet/service/contract references, and status fields.
|
||
- (2026-04-27) Added DB-backed runtime action test: `shared/workflow/runtime/actions/__tests__/businessOperations.time.db.test.ts` covering T001 scenario.
|
||
- Test validates service requirement, user timezone work-date calculation (`America/Los_Angeles`), automatic time-sheet association, and normalized output/row persistence.
|
||
- (2026-04-27) Implemented `F006` bucket usage side effects in workflow create-entry path in `shared/workflow/runtime/actions/businessOperations/timeDomain.ts`.
|
||
- Added explicit-tenant bucket period resolution (`client_billing_cycles` first, then contract-line anchored frequency period).
|
||
- Added bucket usage record upsert for `(tenant, client, contract_line, service, period)` and minutes/overage delta updates gated by `Bucket` overlay configuration.
|
||
- Hooked create-entry to apply delta from `billable_duration` after entry insert.
|
||
- (2026-04-27) Added DB-backed runtime test case for `T002` in `shared/workflow/runtime/actions/__tests__/businessOperations.time.db.test.ts`.
|
||
- Uses billing fixtures (`createFixedPlanAssignment`, `createBucketOverlayForPlan`) to seed a bucket-backed contract line.
|
||
- Verifies default contract-line selection and `bucket_usage.minutes_used` increment from workflow `time.create_entry`.
|
||
- (2026-04-27) Implemented workflow `time.update_entry` and `time.delete_entry` actions in `shared/workflow/runtime/actions/businessOperations/time.ts` backed by new domain helpers.
|
||
- New domain helpers: `updateWorkflowTimeEntry(...)` and `deleteWorkflowTimeEntry(...)` in `shared/workflow/runtime/actions/businessOperations/timeDomain.ts`.
|
||
- Update behavior includes invoiced guard, recomputation of work-date/timezone + billable minutes, timesheet re-association, bucket usage rebalance (`-old +new`), project-task actual-hours recalc (old/new task), and ticket/project-task assignment side effects.
|
||
- Delete behavior includes invoiced guard, bucket usage decrement, and project-task actual-hours recalc.
|
||
- (2026-04-27) Added DB-backed runtime test case for `T003` in `shared/workflow/runtime/actions/__tests__/businessOperations.time.db.test.ts`.
|
||
- Creates a project-task-linked entry, updates duration via workflow action, and deletes via workflow action.
|
||
- Asserts `project_tasks.actual_hours` transitions `30 -> 90 -> 0`.
|
||
- (2026-04-27) Implemented `time.get_entry` (`F009`) and `time.find_entries` (`F010`) in workflow runtime.
|
||
- Added domain helpers `getWorkflowTimeEntry(...)` and `findWorkflowTimeEntries(...)`.
|
||
- `find_entries` supports bounded filters across user/work-item/client/service/contract/status/date/time/invoiced scopes and returns aggregate summary totals.
|
||
- Registered new actions in `shared/workflow/runtime/actions/businessOperations/time.ts` with read permissions and normalized output schemas.
|
||
- (2026-04-27) Added DB-backed runtime test case for `T005` in `shared/workflow/runtime/actions/__tests__/businessOperations.time.db.test.ts`.
|
||
- Verifies `time.get_entry` normalized response shape.
|
||
- Verifies `time.find_entries` filtered list + aggregate totals.
|
||
- Verifies tenant-scoped isolation by asserting cross-tenant entry lookup returns `NOT_FOUND`.
|
||
- (2026-04-27) Added DB-backed runtime test case for `T004` in `shared/workflow/runtime/actions/__tests__/businessOperations.time.db.test.ts`.
|
||
- Marks a project-task time entry as invoiced, then verifies `time.update_entry` and `time.delete_entry` reject with validation errors.
|
||
- Verifies project-task actual-hours and bucket-usage totals remain unchanged after rejected mutations.
|
||
- (2026-04-27) Implemented entry approval actions in workflow runtime:
|
||
- `time.set_entry_approval_status` for `DRAFT`/`SUBMITTED`/`APPROVED`/`CHANGES_REQUESTED` transitions.
|
||
- `time.request_entry_changes` convenience bulk action.
|
||
- Domain helpers added in `timeDomain.ts`: `setWorkflowTimeEntryApprovalStatus(...)` and `requestWorkflowTimeEntryChanges(...)`, including `time_entry_change_requests` creation when change-request comments are supplied.
|
||
- (2026-04-27) Added DB-backed runtime test case for `T006` in `shared/workflow/runtime/actions/__tests__/businessOperations.time.db.test.ts`.
|
||
- Verifies state transitions through submitted/approved/changes-requested and confirms change-request row creation (single + bulk convenience action).
|
||
- (2026-04-27) Implemented timesheet lookup actions (`F015`/`F016`/`F017`) with shared domain helpers:
|
||
- `findOrCreateWorkflowTimeSheet(...)`
|
||
- `getWorkflowTimeSheet(...)`
|
||
- `findWorkflowTimeSheets(...)`
|
||
- Helpers provide period metadata, entry/comment counts, and billable/total minute summaries.
|
||
- (2026-04-27) Added DB-backed runtime test case for `T007` in `shared/workflow/runtime/actions/__tests__/businessOperations.time.db.test.ts`.
|
||
- Verifies `find_or_create_timesheet`, `get_timesheet`, and `find_timesheets` for representative period/date/status filters.
|
||
- Verifies summary fields and comments payload shape.
|
||
- (2026-04-27) Implemented timesheet mutation actions (`F018`–`F022`) in workflow runtime:
|
||
- `time.submit_timesheet`
|
||
- `time.approve_timesheet`
|
||
- `time.request_timesheet_changes`
|
||
- `time.reverse_timesheet_approval`
|
||
- `time.add_timesheet_comment`
|
||
- Domain helpers enforce core state transitions and invoiced-entry guard on reverse.
|
||
- (2026-04-27) Added DB-backed runtime tests for `T008` and `T009` in `shared/workflow/runtime/actions/__tests__/businessOperations.time.db.test.ts`.
|
||
- `T008`: submit propagates `SUBMITTED` to sheet + entries.
|
||
- `T009`: approve/request-changes/add-comment/reverse flow behavior with invoiced-entry reopen guard.
|
||
- (2026-04-27) Implemented readiness helpers (`F023`/`F024`/`F025`) in workflow runtime:
|
||
- `time.summarize_entries`
|
||
- `time.find_billing_blockers`
|
||
- `time.validate_entries`
|
||
- Added grouping support, blocker categorization/explanations, and validation pass/fail summaries.
|
||
- (2026-04-27) Added DB-backed runtime tests for `T010` and `T011` in `shared/workflow/runtime/actions/__tests__/businessOperations.time.db.test.ts`.
|
||
- `T010`: blocker category detection and validation failure summary.
|
||
- `T011`: summary totals and grouped output verification.
|
||
- (2026-04-27) Added explicit time action registration/metadata test file: `shared/workflow/runtime/actions/__tests__/registerTimeActionsMetadata.test.ts`.
|
||
- `T013`: verifies time action registration completeness, stable ids/versions, idempotency metadata, and Time catalog grouping.
|
||
- `T014`: verifies user/ticket picker metadata and textarea editor metadata survive Zod->JSON schema conversion for representative time action inputs.
|
||
- (2026-04-27) Added workflow JSON-schema metadata annotations in `time.ts` for high-value user/ticket picker fields and long-text comment/note inputs.
|
||
- (2026-04-27) Added DB-backed runtime permission test case `T012` in `shared/workflow/runtime/actions/__tests__/businessOperations.time.db.test.ts`.
|
||
- Verifies structured `PERMISSION_DENIED` errors for denied `timeentry:create`, `timeentry:read`, and `timesheet:approve` paths.
|
||
- (2026-04-27) Implemented workflow audit writes for additional mutating time actions in `time.ts`:
|
||
- `time.find_or_create_timesheet`
|
||
- `time.submit_timesheet`
|
||
- `time.approve_timesheet`
|
||
- `time.request_timesheet_changes`
|
||
- `time.reverse_timesheet_approval`
|
||
- `time.add_timesheet_comment`
|
||
- (2026-04-27) Added DB-backed runtime tests:
|
||
- `T015`: verifies mutating time actions emit workflow run audit rows with action metadata and changed IDs.
|
||
- `T016`: verifies `time.create_entry` compatibility alias (`billing_plan_id`) still routes through canonical service/time-sheet/work-date behavior.
|
||
- (2026-04-27) Compatibility decision documentation status (`F032`):
|
||
- Keep `time.create_entry@v1` and preserve input compatibility via `billing_plan_id` alias while enforcing canonical semantics.
|
||
- Behavior now always runs through workflow-safe helper path with service validation, timezone work-date, timesheet association, and side effects.
|
||
|
||
## Commands / Verification (This Pass)
|
||
|
||
- Ran: `npx vitest run --config shared/vitest.config.ts workflow/runtime/__tests__/workflowDesignerActionCatalog.test.ts` (pass)
|
||
- Attempted: `npx vitest run --config shared/vitest.config.ts workflow/runtime/actions/__tests__/businessOperations.time.db.test.ts`
|
||
- Blocked locally due DB connection refusal at `127.0.0.1:57432` / `::1:57432`.
|
||
- Test file compiles/loads, but DB-backed execution requires local test Postgres availability.
|
||
- Attempted after F006/T002 changes: `npx vitest run --config shared/vitest.config.ts workflow/runtime/actions/__tests__/businessOperations.time.db.test.ts`
|
||
- Still blocked locally by the same test DB connection refusal (`127.0.0.1:57432`).
|
||
- Attempted after update/delete action + T003 changes: `npx vitest run --config shared/vitest.config.ts workflow/runtime/actions/__tests__/businessOperations.time.db.test.ts`
|
||
- Compile/import succeeds, but DB-backed execution remains blocked by local connection refusal (`127.0.0.1:57432`).
|
||
- Attempted after get/find actions + T005 changes: `npx vitest run --config shared/vitest.config.ts workflow/runtime/actions/__tests__/businessOperations.time.db.test.ts`
|
||
- Compile/import succeeds, but DB-backed execution remains blocked by the same local connection refusal (`127.0.0.1:57432`).
|
||
- Attempted after T004 additions: `npx vitest run --config shared/vitest.config.ts workflow/runtime/actions/__tests__/businessOperations.time.db.test.ts`
|
||
- Compile/import succeeds, but DB-backed execution remains blocked by the same local connection refusal (`127.0.0.1:57432`).
|
||
- Attempted after approval-action + T006 additions: `npx vitest run --config shared/vitest.config.ts workflow/runtime/actions/__tests__/businessOperations.time.db.test.ts`
|
||
- Compile/import succeeds, but DB-backed execution remains blocked by the same local connection refusal (`127.0.0.1:57432`).
|
||
- Attempted after timesheet lookup actions + T007 additions: `npx vitest run --config shared/vitest.config.ts workflow/runtime/actions/__tests__/businessOperations.time.db.test.ts`
|
||
- Compile/import succeeds, but DB-backed execution remains blocked by the same local connection refusal (`127.0.0.1:57432`).
|
||
- Attempted after timesheet mutation actions + T008/T009 additions: `npx vitest run --config shared/vitest.config.ts workflow/runtime/actions/__tests__/businessOperations.time.db.test.ts`
|
||
- Compile/import succeeds, but DB-backed execution remains blocked by the same local connection refusal (`127.0.0.1:57432`).
|
||
- Attempted after readiness helper + T010/T011 additions: `npx vitest run --config shared/vitest.config.ts workflow/runtime/actions/__tests__/businessOperations.time.db.test.ts`
|
||
- Compile/import succeeds, but DB-backed execution remains blocked by the same local connection refusal (`127.0.0.1:57432`).
|
||
- Attempted: `npx tsc -p shared/tsconfig.json --noEmit`
|
||
- Fails due pre-existing workspace TS config/module issues outside this feature area (`@alga-psa/sla/types`, alias `@/lib/*`, and existing `server/test-utils/dbReset.ts` declaration-order error).
|
||
- Ran: `npx vitest run --config shared/vitest.config.ts workflow/runtime/__tests__/workflowDesignerActionCatalog.test.ts` (pass after each action-registration expansion).
|
||
- Ran: `npx vitest run --config shared/vitest.config.ts workflow/runtime/actions/__tests__/registerTimeActionsMetadata.test.ts` (pass)
|
||
- Attempted after permission test additions: `npx vitest run --config shared/vitest.config.ts workflow/runtime/actions/__tests__/businessOperations.time.db.test.ts`
|
||
- Compile/import succeeds, but DB-backed execution remains blocked by the same local connection refusal (`127.0.0.1:57432`).
|
||
- Attempted after T015/T016 additions: `npx vitest run --config shared/vitest.config.ts workflow/runtime/actions/__tests__/businessOperations.time.db.test.ts`
|
||
- Compile/import succeeds, but DB-backed execution remains blocked by the same local connection refusal (`127.0.0.1:57432`).
|
||
- Ran: `npx vitest run --config shared/vitest.config.ts workflow/runtime/actions/__tests__/registerTimeActionsMetadata.test.ts workflow/runtime/__tests__/workflowDesignerActionCatalog.test.ts` (pass)
|
||
- Re-ran: `npx vitest run --config shared/vitest.config.ts workflow/runtime/actions/__tests__/registerTimeActionsMetadata.test.ts workflow/runtime/__tests__/workflowDesignerActionCatalog.test.ts` (pass, 2026-04-27 final verification before completion)
|
||
- Re-ran: `npx vitest run --config shared/vitest.config.ts workflow/runtime/actions/__tests__/businessOperations.time.db.test.ts` (still blocked by local DB connection refusal at `::1/127.0.0.1:57432`; tests skipped due suite setup failure)
|
||
- Verified remaining checklist state with `jq`: `features.json` false count = `0`, `tests.json` false count = `0`.
|
||
|
||
## Gotchas
|
||
|
||
- `@alga-psa/billing` subpath imports used in server packages are not exported for this shared Vite test runtime. To keep workflow-runtime tests executable, contract-line defaulting and bucket-usage linkage were intentionally deferred to subsequent features (`F005`/`F006`) rather than forcing brittle deep imports.
|
||
- (2026-04-27) Implemented default contract-line resolution in workflow helper (`F005`) without depending on non-exported billing package subpaths.
|
||
- Added tenant-scoped eligible-contract query with effective-date filtering and deterministic selection fallback (single eligible line, or single bucket-overlay candidate).
|
||
- `time.create_entry` now assigns `contract_line_id` automatically when omitted and client/service context can resolve a default.
|
||
- (2026-04-27) Bucket usage side-effect implementation in workflow helper intentionally keeps explicit tenant-scoped SQL in `timeDomain.ts` instead of importing `@alga-psa/billing`/`@alga-psa/scheduling` internals to avoid export-boundary and tenant-resolution brittleness in shared runtime tests.
|
||
|
||
## Review Follow-up Fixes
|
||
|
||
- (2026-04-27) Removed workflow time-sheet writes to non-existent `time_sheets.created_at` / `time_sheets.updated_at` columns; the current schema only has `submitted_at`, `approved_at`, and `approved_by` on `time_sheets`.
|
||
- (2026-04-27) Fixed TypeScript aggregate typing in `findWorkflowTimeEntries` so shared typecheck no longer reports `timeDomain.ts` aggregate property errors.
|
||
- (2026-04-27) Added workflow-time subject guards for acting on behalf of another user, self-approval denial, and scoped find/read helpers. The guard uses `timesheet:read_all` or manager/reporting relationship for cross-user access after the action-level permission check.
|
||
- (2026-04-27) Reworked `summarizeTimeSheet` to aggregate entries and comments separately to avoid entry-minute inflation when a sheet has multiple comments.
|
||
- (2026-04-27) Fixed `time.update_entry` detach semantics so `attach_to_timesheet: false` actually clears the sheet instead of retaining the existing sheet.
|
||
- (2026-04-27) Removed the misleading ticket picker from polymorphic `link.id`; ticket-specific filters still use the ticket picker.
|
||
- (2026-04-27) Validation run: `npx vitest run shared/workflow/runtime/actions/__tests__/registerTimeActionsMetadata.test.ts --config shared/vitest.config.ts` passed.
|
||
- (2026-04-27) Validation run: `npx eslint shared/workflow/runtime/actions/businessOperations/time.ts shared/workflow/runtime/actions/businessOperations/timeDomain.ts` passed.
|
||
- (2026-04-27) Validation run: `npx tsc --noEmit --project shared/tsconfig.json` still fails on pre-existing unrelated path/dbReset errors, but no longer reports `timeDomain.ts` errors.
|
||
- (2026-04-27) Updated DB-backed workflow time tests to grant the workflow actor real MSP time permissions so the new subject-scope helper checks can run under migrated schema instead of relying only on the mocked `requirePermission` path.
|