# SCRATCHPAD — Invoice Template JSON AST Renderer Cutover ## Context - Plan folder: `ee/docs/plans/2026-02-12-invoice-template-json-ast-renderer-cutover/` - Date started: `2026-02-12` - Status: Draft - Supersedes architecture direction in: `ee/docs/plans/2026-02-09-invoice-template-designer-preview-workspace/` ## Key Decisions - Treat invoice templates as declarative data (AST), not executable code. - Keep future calculation/grouping flexibility via declarative transform specs. - Add optional `strategyId` hooks only through explicit allowlist resolution. - Use one shared React renderer for preview and backend PDF generation. - Keep migration effort minimal: no custom tenant templates exist that require backfill. ## Scope Boundaries In scope: - AST schema + evaluator + renderer cutover. - Preview + save/load + PDF pipeline updates. - Deletion of compiler and custom executor layers. Out of scope: - Arbitrary per-template code execution. - Complex migration tooling for existing tenant custom templates. ## Existing Code Paths Reviewed - Preview pipeline: - `packages/billing/src/actions/invoiceTemplatePreview.ts` - `packages/billing/src/actions/invoiceTemplatePreviewCache.ts` - Designer/editor coupling: - `packages/billing/src/components/billing-dashboard/InvoiceTemplateEditor.tsx` - `packages/billing/src/components/invoice-designer/DesignerVisualWorkspace.tsx` - `packages/billing/src/components/invoice-designer/compiler/guiIr.ts` - `packages/billing/src/components/invoice-designer/compiler/assemblyScriptGenerator.ts` - `packages/billing/src/components/invoice-designer/compiler/diagnostics.ts` - Runtime + rendering: - `packages/billing/src/lib/invoice-renderer/wasm-executor.ts` - `packages/billing/src/lib/invoice-renderer/quickjs-executor.ts` - `packages/billing/src/lib/invoice-renderer/host-functions.ts` - `packages/billing/src/lib/invoice-renderer/layout-renderer.ts` - Compile orchestration: - `packages/billing/src/lib/invoice-template-compiler/assemblyScriptCompile.ts` - PDF path: - `server/src/services/pdf-generation.service.ts` - Persistence/types: - `packages/billing/src/models/invoice.ts` - `packages/types/src/interfaces/invoice.interfaces.ts` - `server/src/interfaces/invoice.interfaces.ts` ## Risks To Watch - Parity drift while replacing compile/runtime pipeline. - AST transform model underpowered for future grouping/calc edge cases. - Strategy hook design becoming an unbounded execution escape hatch. ## Notes for Implementation Phase - Start with pure declarative transform operations. - Introduce strategy hooks only where declarative operations are insufficient. - Keep strategy registry narrow and explicit. - Preserve tenant-safe data access boundaries. ## Verification Commands - Plan lint/shape: - `python3 scripts/validate_plan.py ee/docs/plans/2026-02-12-invoice-template-json-ast-renderer-cutover` - Spot-check references: - `rg -n "guiIr|assemblyScriptGenerator|assemblyScriptCompile|wasm-executor|quickjs-executor|host-functions" packages/billing/src server/src` ## Open Questions Tracking 1. Final `Code` tab behavior for GUI templates (AST JSON read-only vs hidden). 2. Initial strategy hook set for MVP. 3. MVP expectation for layout verification under AST renderer path. ## Progress Log ### 2026-02-12 — F001 implemented - Implemented shared AST type system in `packages/types/src/lib/invoice-template-ast.ts`. - Added explicit versioning root model: - `INVOICE_TEMPLATE_AST_VERSION = 1` - `InvoiceTemplateAst` with `kind`, `version`, `metadata`, `styles`, `bindings`, `transforms`, `layout`. - Added discriminated node model for layout tree: - `document`, `section`, `stack`, `text`, `field`, `image`, `divider`, `table`, `totals`. - Added style model: - token catalog and class declarations via `InvoiceTemplateStyleCatalog`. - node style references via `InvoiceTemplateNodeStyleRef`. - Added binding model: - value and collection binding catalogs, binding refs, and value expression union. - Added transform model shape: - `filter`, `sort`, `group`, `aggregate`, `computed-field`, `totals-compose`. - transform base includes optional `strategyId` as schema surface for later allowlisted hook implementation. - Exported new AST type module from `packages/types/src/index.ts`. Rationale: - `@alga-psa/types` is the correct shared location for contracts consumed by both app and server paths. - Defining versioned AST and explicit discriminated unions up front reduces ambiguity before schema/runtime evaluator implementation. Commands run: - `npm -w @alga-psa/types run build` (fails with existing TS2209 rootDir/export-map ambiguity in this workspace). - `npx tsc -p packages/types/tsconfig.json --noEmit` (same existing TS2209 issue). - `npm -w @alga-psa/types test` (fails on existing unrelated `src/interfaces/barrel.test.ts` stray `tax.interfaces` export). Gotchas: - `@alga-psa/types` package currently has baseline build/test failures unrelated to AST changes; continue with targeted feature implementation and track failures in commit notes. ### 2026-02-12 — F002 implemented - Added runtime AST schema parser in `packages/billing/src/lib/invoice-template-ast/schema.ts`. - Implemented strict Zod schemas for: - AST root (`kind`, `version`, `metadata`, `styles`, `bindings`, `transforms`, `layout`), - recursive layout nodes, - expressions, predicates, and transform operation payloads. - Added structured validation model: - `InvoiceTemplateAstValidationError` (`code`, `path`, `message`), - `validateInvoiceTemplateAst(input)` returning success/error union, - `parseInvoiceTemplateAst(input)` throwing a consolidated message for invalid payloads. - Added targeted validator tests in `packages/billing/src/lib/invoice-template-ast/schema.test.ts`. Rationale: - Runtime schema validation is required before evaluator/renderer cutover so preview/PDF pipelines can fail fast with actionable diagnostics. - Strict object validation prevents accidental schema drift and catches unknown fields early. Commands run: - `npx vitest run packages/billing/src/lib/invoice-template-ast/schema.test.ts` (pass). ### 2026-02-12 — F003 implemented - Extended AST node model with explicit repeatable region support: - Added `dynamic-table` node type in `packages/types/src/lib/invoice-template-ast.ts`. - Added `InvoiceTemplateRepeatRegionBinding` with required `sourceBinding` and `itemBinding`. - Updated runtime validator in `packages/billing/src/lib/invoice-template-ast/schema.ts`: - Added `dynamic-table` schema variant. - Enforced required repeat metadata (`repeat.sourceBinding`, `repeat.itemBinding`). - Added/extended tests in `packages/billing/src/lib/invoice-template-ast/schema.test.ts` to ensure: - missing repeat binding metadata fails with structured path-aware errors, - valid dynamic table payload passes. Rationale: - Repeatable line-item regions should be first-class AST semantics, not implicit conventions on generic tables. - Explicit repeat metadata is required for deterministic evaluator behavior in upcoming features. Commands run: - `npx vitest run packages/billing/src/lib/invoice-template-ast/schema.test.ts` (pass). ### 2026-02-12 — F004 implemented - Completed declarative transform operation representation in AST: - Existing transform union now enforced as strict runtime schema in `packages/billing/src/lib/invoice-template-ast/schema.ts`. - Supported operations: `filter`, `sort`, `group`, `aggregate`, `computed-field`, `totals-compose`. - Strengthened runtime payload constraints: - `transforms.operations` must be non-empty. - `sort.keys`, `aggregate.aggregations`, `computed-field.fields`, `totals-compose.totals` must be non-empty. - logical predicates require at least one condition. - Added transform-shape tests in `packages/billing/src/lib/invoice-template-ast/schema.test.ts`: - invalid empty `sort.keys` rejected with structured path errors, - valid composed filter/sort/group/aggregate/computed payload accepted. Rationale: - This locks in declarative transform expressiveness before evaluator implementation and catches malformed transform configs early. Commands run: - `npx vitest run packages/billing/src/lib/invoice-template-ast/schema.test.ts` (pass). ### 2026-02-12 — F005 implemented - Confirmed/retained `strategyId?: string` on transform operation base model in: - `packages/types/src/lib/invoice-template-ast.ts` - `packages/billing/src/lib/invoice-template-ast/schema.ts` - Added runtime acceptance test in `packages/billing/src/lib/invoice-template-ast/schema.test.ts` ensuring `strategyId` is valid on grouped/aggregate transforms. Rationale: - Declares extension points in AST shape now, while deferring actual strategy resolution/execution to allowlisted registry implementation. Commands run: - `npx vitest run packages/billing/src/lib/invoice-template-ast/schema.test.ts` (pass). ### 2026-02-12 — F006 implemented - Added allowlisted strategy registry in `packages/billing/src/lib/invoice-template-ast/strategies.ts`. - Implemented explicit APIs: - `listAllowlistedInvoiceTemplateStrategyIds()` - `isAllowlistedInvoiceTemplateStrategy(strategyId)` - `resolveInvoiceTemplateStrategy(strategyId)` - `executeInvoiceTemplateStrategy(strategyId, input)` - Added strict unknown-strategy rejection with typed error: - `InvoiceTemplateStrategyResolutionError` - error code: `STRATEGY_NOT_ALLOWLISTED`. - Seeded initial allowlisted strategies for upcoming evaluator usage: - `custom-group-key` - `custom-aggregate` - Added unit tests in `packages/billing/src/lib/invoice-template-ast/strategies.test.ts` for known/unknown strategy behavior. Rationale: - Strategy execution must be explicit and allowlisted to preserve non-arbitrary-code security posture while enabling controlled extensibility. Commands run: - `npx vitest run packages/billing/src/lib/invoice-template-ast/schema.test.ts packages/billing/src/lib/invoice-template-ast/strategies.test.ts` (pass). ### 2026-02-12 — F007 implemented - Added shared AST evaluator in `packages/billing/src/lib/invoice-template-ast/evaluator.ts`. - Implemented declarative transform execution over invoice collections: - `filter` via predicate evaluation - `sort` via stable multi-key ordering - `group` with optional strategy hook support - `aggregate` for `sum/count/avg/min/max` (overall + per-group aggregates) - `computed-field` for derived numeric expressions - `totals-compose` for totals from aggregate refs/computation expressions - Evaluator exports: - `evaluateInvoiceTemplateAst(ast, invoiceData)` - `evaluateAstTransforms(ast, invoiceData)` alias - typed result with `output`, `groups`, `aggregates`, `totals`, and resolved `bindings`. - Added evaluator test suite in `packages/billing/src/lib/invoice-template-ast/evaluator.test.ts`. Rationale: - Central evaluator module is the core abstraction needed to unify preview and PDF behavior around AST data-shaping semantics. Commands run: - `npx vitest run packages/billing/src/lib/invoice-template-ast/evaluator.test.ts packages/billing/src/lib/invoice-template-ast/schema.test.ts packages/billing/src/lib/invoice-template-ast/strategies.test.ts` (pass). ### 2026-02-12 — F008 implemented - Added deterministic output normalization in evaluator (`packages/billing/src/lib/invoice-template-ast/evaluator.ts`): - recursive plain-object key sorting before returning `output`, `groups`, `aggregates`, `totals`, and `bindings`. - stable sort implementation already used index tie-break to preserve deterministic ordering. - Added explicit determinism test in `packages/billing/src/lib/invoice-template-ast/evaluator.test.ts`: - repeated evaluation of identical AST+input yields byte-for-byte identical JSON payload. Rationale: - Deterministic evaluation output is required for reproducible preview/PDF parity checks and reliable caching/verification logic. Commands run: - `npx vitest run packages/billing/src/lib/invoice-template-ast/evaluator.test.ts` (pass). ### 2026-02-12 — F009 implemented - Upgraded evaluator failure handling to structured error model in `packages/billing/src/lib/invoice-template-ast/evaluator.ts`. - Added `InvoiceTemplateEvaluationIssue` and enriched `InvoiceTemplateEvaluationError` with: - canonical error code, - operationId (where applicable), - issue list payload for multi-error contexts. - Covered required failure classes: - `SCHEMA_VALIDATION_FAILED` (integrated runtime schema validation before evaluation), - `MISSING_BINDING` (undefined source binding), - `UNKNOWN_STRATEGY` / `STRATEGY_EXECUTION_FAILED`, - `INVALID_TRANSFORM_INPUT`, - `INVALID_OPERAND` (e.g., unresolved aggregate references). - Added evaluator tests asserting explicit codes and structured issue payloads in `packages/billing/src/lib/invoice-template-ast/evaluator.test.ts`. Rationale: - Preview/PDF pipeline error surfacing needs explicit, machine-readable evaluator errors rather than ad hoc thrown strings. Commands run: - `npx vitest run packages/billing/src/lib/invoice-template-ast/evaluator.test.ts` (pass). ### 2026-02-12 — F010 implemented - Added shared React renderer module in `packages/billing/src/lib/invoice-template-ast/react-renderer.tsx`. - Implemented renderer component + server-safe static markup helper: - `InvoiceTemplateAstRenderer` - `renderEvaluatedInvoiceTemplateAst(ast, evaluation) -> { html, css }` - Supported node rendering for: - `document`, `section`, `stack`, `text`, `field`, `image`, `divider`, `table`, `dynamic-table`, `totals`. - Implemented expression/value resolution against evaluator bindings and row scope. - Implemented class/token CSS generation from AST style catalog. - Added renderer tests in `packages/billing/src/lib/invoice-template-ast/react-renderer.test.tsx` for: - static text/field/table/totals rendering, - style/class consistency, - unsafe content escaping in output HTML. Rationale: - This is the shared rendering surface required for both interactive preview and backend PDF paths. Commands run: - `npx vitest run packages/billing/src/lib/invoice-template-ast/react-renderer.test.tsx packages/billing/src/lib/invoice-template-ast/evaluator.test.ts packages/billing/src/lib/invoice-template-ast/schema.test.ts packages/billing/src/lib/invoice-template-ast/strategies.test.ts` (pass). ### 2026-02-12 — F011 implemented - Added server-side HTML document wrapper helper in `packages/billing/src/lib/invoice-template-ast/server-render.ts`. - Implemented `renderInvoiceTemplateAstHtmlDocument(ast, evaluation, options)` to: - call the shared React renderer (`renderEvaluatedInvoiceTemplateAst`), - wrap output in a complete `` document, - include generated CSS + optional additional CSS, - support configurable title/body class with HTML escaping. - Added unit test `packages/billing/src/lib/invoice-template-ast/server-render.test.ts` validating complete wrapper output for headless PDF use. Rationale: - PDF pipeline needs a full HTML document entrypoint, but should reuse the exact same AST React renderer output to maintain parity. Commands run: - `npx vitest run packages/billing/src/lib/invoice-template-ast/*.test.ts packages/billing/src/lib/invoice-template-ast/*.test.tsx` (pass). ### 2026-02-12 — F012 implemented - Added designer workspace -> AST exporter in: - `packages/billing/src/components/invoice-designer/ast/workspaceAst.ts` - with helper `exportWorkspaceToInvoiceTemplateAst(workspace)` and JSON helper. - Export mapping now emits versioned `InvoiceTemplateAst` directly from visual workspace (no IR step). - Updated `InvoiceTemplateEditor` visual save/export path (`packages/billing/src/components/billing-dashboard/InvoiceTemplateEditor.tsx`): - replaced IR/AssemblyScript generation in code-view projection with AST JSON projection, - on save with GUI designer enabled, persists canonical `templateAst` payload directly from workspace export, - keeps legacy `assemblyScriptSource` comment persistence only as temporary compatibility scaffolding. - Added exporter tests: - `packages/billing/src/components/invoice-designer/ast/workspaceAst.test.ts`. Rationale: - This establishes AST as the designer export artifact and removes compiler-IR coupling from the visual export path. Commands run: - `npx vitest run packages/billing/src/components/invoice-designer/ast/workspaceAst.test.ts` (pass). - `npx vitest run packages/billing/src/components/invoice-designer/ast/workspaceAst.test.ts packages/billing/src/components/billing-dashboard/InvoiceTemplateEditor.previewWorkspace.test.tsx packages/billing/src/components/billing-dashboard/InvoiceTemplateEditor.authoritativeFlow.test.tsx` (fails due existing React 19 test harness issue: `React.act is not a function` from `@testing-library/react`/`react-dom-test-utils` in this environment). ### 2026-02-12 — F013 implemented - Extended AST utility module (`packages/billing/src/components/invoice-designer/ast/workspaceAst.ts`) with import/hydration support: - `importInvoiceTemplateAstToWorkspace(ast)` builds designer workspace snapshot from persisted AST. - Updated `InvoiceTemplateEditor` hydration flow (`packages/billing/src/components/billing-dashboard/InvoiceTemplateEditor.tsx`): - prefers `templateAst` payload hydration when available, - falls back to legacy embedded-source/localStorage workspace hydration only if AST hydration is unavailable or fails. - Added AST import coverage in `packages/billing/src/components/invoice-designer/ast/workspaceAst.test.ts`. - Added editor integration expectation for `templateAst` hydration in `packages/billing/src/components/billing-dashboard/InvoiceTemplateEditor.previewWorkspace.test.tsx` (execution blocked by existing act-compat issue in current test harness). Rationale: - Save/reopen flow should hydrate editor state from canonical AST representation as cutover progresses. Commands run: - `npx vitest run packages/billing/src/components/invoice-designer/ast/workspaceAst.test.ts` (pass). - `npx vitest run packages/billing/src/components/invoice-designer/ast/workspaceAst.test.ts packages/billing/src/components/billing-dashboard/InvoiceTemplateEditor.previewWorkspace.test.tsx packages/billing/src/components/billing-dashboard/InvoiceTemplateEditor.authoritativeFlow.test.tsx` (editor test files fail due existing `React.act is not a function` harness issue). ### 2026-02-12 — F014 implemented - Confirmed `InvoiceTemplateEditor` no longer imports or calls: - `extractInvoiceDesignerIr` - `generateAssemblyScriptFromIr` - Save path now uses AST exporter (`exportWorkspaceToInvoiceTemplateAst`) instead of IR/compiler generation. Verification: - `rg -n "extractInvoiceDesignerIr|generateAssemblyScriptFromIr" packages/billing/src/components/billing-dashboard/InvoiceTemplateEditor.tsx` (no matches). ### 2026-02-12 — F015 implemented - Updated shared and server invoice template contracts to include canonical AST payload: - `packages/types/src/interfaces/invoice.interfaces.ts` - `server/src/interfaces/invoice.interfaces.ts` - Contract updates: - added `templateAst?: InvoiceTemplateAst | null` - relaxed `assemblyScriptSource` from required to optional (`assemblyScriptSource?: string`) for cutover compatibility. - Added type contract test: - `packages/types/src/interfaces/invoice-template-ast-contract.typecheck.test.ts` - verifies `IInvoiceTemplate` accepts AST payload without requiring legacy AssemblyScript source. Commands run: - `npx vitest run packages/types/src/interfaces/invoice-template-ast-contract.typecheck.test.ts` (pass). ### 2026-02-12 — F016 implemented - Added DB migration for tenant template AST persistence: - `server/migrations/20260212143000_add_template_ast_to_invoice_templates.cjs` - introduces nullable `templateAst` JSONB column on `invoice_templates`. - Updated template read/write repository/model paths: - `packages/billing/src/actions/invoiceTemplates.ts` - `getInvoiceTemplate` now selects `templateAst`, - `saveInvoiceTemplate` now treats `templateAst` payload as canonical and skips compile gating for AST templates. - `packages/billing/src/models/invoice.ts` - tenant template list path includes `templateAst`, - upsert merge list includes `templateAst`. - Updated API schema contract: - `server/src/lib/api/schemas/invoiceSchemas.ts` - `assemblyScriptSource` optional, `templateAst` optional nullable object payload. - Added wiring tests: - `packages/billing/src/actions/invoiceTemplateAstPersistenceWiring.test.ts`. Rationale: - Persistence/read paths now treat AST as first-class template payload while keeping legacy fields for transition compatibility. Commands run: - `npx vitest run packages/billing/src/actions/invoiceTemplateAstPersistenceWiring.test.ts` (pass). - `npx vitest run packages/billing/src/actions/invoiceTemplateCompileParity.test.ts packages/types/src/interfaces/invoice-template-ast-contract.typecheck.test.ts packages/billing/src/components/invoice-designer/ast/workspaceAst.test.ts` (pass). ### 2026-02-12 — F017 implemented - Added AST-based standard template definitions: - `packages/billing/src/lib/invoice-template-ast/standardTemplates.ts` - includes `standard-default` and `standard-detailed` canonical AST payloads. - Added DB migration for standard template AST persistence: - `server/migrations/20260212143500_add_template_ast_to_standard_invoice_templates.cjs` - Updated standard template read/update wiring: - `packages/billing/src/models/invoice.ts` now selects `templateAst` for standard templates and falls back to AST definitions by standard code. - `packages/billing/src/actions/invoiceTemplates.ts` now writes canonical `templateAst` during `compileStandardTemplate` updates. - Added tests: - `packages/billing/src/lib/invoice-template-ast/standardTemplates.test.ts` - extended `packages/billing/src/actions/invoiceTemplateAstPersistenceWiring.test.ts` for standard-template AST wiring assertions. Rationale: - Standard templates now have AST-native source representations, enabling unified renderer/evaluator behavior with tenant templates. Commands run: - `npx vitest run packages/billing/src/lib/invoice-template-ast/standardTemplates.test.ts packages/billing/src/actions/invoiceTemplateAstPersistenceWiring.test.ts` (pass). ### 2026-02-12 — F018 implemented - Rewrote authoritative preview execution path in `packages/billing/src/actions/invoiceTemplatePreview.ts`: - replaced GUI IR + AssemblyScript compile + Wasm execution path inside `runAuthoritativeInvoiceTemplatePreview`, - now exports workspace to AST (`exportWorkspaceToInvoiceTemplateAst`), validates schema (`validateInvoiceTemplateAst`), evaluates transforms (`evaluateInvoiceTemplateAst`), and renders HTML/CSS via shared React renderer (`renderEvaluatedInvoiceTemplateAst`). - Preview response semantics for this stage: - `sourceHash` now hashes canonical AST JSON, - `generatedSource` now carries AST JSON, - compile section is retained for compatibility but no longer performs compilation (`cacheHit=false`, diagnostics reflect AST/evaluator issues). - Updated integration coverage in `packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts`: - now asserts AST validation+evaluator+renderer execution and rendered output presence, - invocation adjusted to pass mocked auth/context args because `withAuth` is mocked as identity in this suite. Rationale: - This completes the preview runtime cutover for authoritative rendering while preserving response shape compatibility for downstream UI wiring. Commands run: - `pnpm vitest packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts` (pass). - `pnpm vitest packages/billing/src/lib/invoice-template-ast/schema.test.ts packages/billing/src/lib/invoice-template-ast/evaluator.test.ts packages/billing/src/lib/invoice-template-ast/react-renderer.test.tsx` (tests pass; run exits non-zero in this environment due pre-existing coverage temp dir `server/coverage/.tmp` ENOENT after reporting). ### 2026-02-12 — F019 implemented - Preserved Sample/Existing source-selection semantics for preview UX after AST backend cutover. - Added source-mode specific test coverage in pure preview state/status modules: - `packages/billing/src/components/invoice-designer/preview/previewStatus.test.ts` - sample source validity now explicitly verified to depend on preview sample payload. - `packages/billing/src/components/invoice-designer/preview/previewSessionState.test.ts` - source toggle flow verifies sample selection is preserved across Sample <-> Existing transitions. Rationale: - These tests guard the source-selection UX contract independently of the compile/runtime pipeline internals. Commands run: - `pnpm vitest packages/billing/src/components/invoice-designer/preview/previewStatus.test.ts packages/billing/src/components/invoice-designer/preview/previewSessionState.test.ts` (pass). - `pnpm vitest packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts` (test passes; command exits non-zero in this environment due existing coverage temp dir issue: `server/coverage/.tmp` ENOENT). - Attempted targeted `DesignerVisualWorkspace` component source-switch tests; blocked by pre-existing `React.act is not a function` compatibility issue in current React/testing-library stack. ### 2026-02-12 — F020 implemented - Remapped preview pipeline phase semantics from `compile/render/verify` to `shape/render/verify` in designer preview state and UI surface. - Updated preview state model and reducer: - `packages/billing/src/components/invoice-designer/preview/previewSessionState.ts` - renamed `compileStatus/compileError` -> `shapeStatus/shapeError` - phase enum now uses `'shape' | 'render' | 'verify'`. - Updated phase display derivation: - `packages/billing/src/components/invoice-designer/preview/previewStatus.ts` - status snapshot now tracks `shapeStatus`. - Updated `DesignerVisualWorkspace` status wiring and UX copy: - dispatches/reads `shape` phase state, - status label now reads `Shape`, - loading text updated to `Shaping and rendering preview...`, - automation IDs moved from `...preview-compile-*` to `...preview-shape-*` for status/error/diagnostics/cache markers. - Updated related tests: - `previewSessionState.test.ts` - `previewStatus.test.ts` - string/automation-id expectations in `DesignerVisualWorkspace.test.tsx` aligned to `shape` terminology. Rationale: - Preview UX now reflects the AST pipeline's shaping step instead of a compiler phase. Commands run: - `pnpm vitest packages/billing/src/components/invoice-designer/preview/previewSessionState.test.ts packages/billing/src/components/invoice-designer/preview/previewStatus.test.ts` (pass). ### 2026-02-12 — F021 implemented - Retained and strengthened structured preview diagnostics with AST/evaluator context in `runAuthoritativeInvoiceTemplatePreview`: - `packages/billing/src/actions/invoiceTemplatePreview.ts` - expanded diagnostic payload with `kind`, `code`, `path`, and `operationId` metadata. - schema validation failures now emit `kind: 'schema'` diagnostics with path/code context. - evaluator failures now emit `kind: 'evaluation'` diagnostics with operation/path/code context. - non-evaluator runtime failures now emit `kind: 'runtime'` diagnostics. - Updated preview diagnostics rendering surface: - `packages/billing/src/components/invoice-designer/DesignerVisualWorkspace.tsx` - diagnostics list now renders contextual `code/path/op` metadata alongside message severity. - Added integration coverage for structured diagnostics: - `packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts` - validates schema diagnostic context mapping and evaluator diagnostic context mapping. Rationale: - Preview diagnostics now preserve machine-meaningful context needed for targeted AST/evaluator debugging without reverting to compiler-era error formats. Commands run: - `pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts` (pass). - `pnpm vitest --coverage.enabled=false packages/billing/src/components/invoice-designer/preview/previewSessionState.test.ts packages/billing/src/components/invoice-designer/preview/previewStatus.test.ts` (pass). ### 2026-02-12 — F022 implemented - Updated server PDF generation invoice path to use AST evaluator + shared renderer output instead of Wasm execution in: - `server/src/services/pdf-generation.service.ts` - Changes made: - removed `getCompiledWasm`, `executeWasmTemplate`, and `renderLayout` usage/imports from invoice PDF rendering flow, - now requires canonical `templateAst` on selected template, - evaluates AST with `evaluateInvoiceTemplateAst`, - produces complete HTML document via `renderInvoiceTemplateAstHtmlDocument` for Puppeteer PDF generation. - Added wiring coverage: - `packages/billing/src/actions/invoicePdfGenerationAstWiring.test.ts` - asserts PDF service uses AST helper path and no longer references Wasm execution helpers. Rationale: - Backend invoice PDF generation now consumes the declarative AST rendering path and removes runtime dependence on Wasm executor in the PDF service. Commands run: - `pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoicePdfGenerationAstWiring.test.ts` (pass). - `pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts` (pass). ### 2026-02-12 — F023 implemented - Aligned preview and PDF/server render paths onto shared AST evaluator/renderer modules. - Updated template server-render action in: - `packages/billing/src/actions/invoiceTemplates.ts` - `renderTemplateOnServer` no longer executes Wasm; it now: - resolves template from tenant+standard template set, - requires canonical `templateAst`, - evaluates via `evaluateInvoiceTemplateAst`, - renders via `renderEvaluatedInvoiceTemplateAst`. - Extended parity wiring assertions in: - `packages/billing/src/actions/invoicePdfGenerationAstWiring.test.ts` - verifies preview action, PDF service, and `renderTemplateOnServer` all use AST evaluator/renderer stack. Rationale: - This ensures preview and both server-side rendering entry points share the same rendering core and reduces parity drift risk. Commands run: - `pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoicePdfGenerationAstWiring.test.ts` (pass). - `pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoiceTemplateAstPersistenceWiring.test.ts packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts` (pass). ### 2026-02-12 — F024 implemented - Removed preview compile-cache/Wasm artifact cache logic from preview pipeline. - Deleted cache module and its unit tests: - `packages/billing/src/actions/invoiceTemplatePreviewCache.ts` (deleted) - `packages/billing/src/actions/invoiceTemplatePreview.cache.test.ts` (deleted) - Updated preview action contract and implementation: - `packages/billing/src/actions/invoiceTemplatePreview.ts` - removed cache imports and cache key resolution, - removed cached artifact lookup/set operations, - removed `cacheHit` fields from preview compile status payload, - removed preview input cache-bypass flag from authoritative preview path. - Updated preview UI status behavior: - `packages/billing/src/components/invoice-designer/DesignerVisualWorkspace.tsx` - removed cache-hit badge and cache-bypass request plumbing while preserving manual rerun behavior. - Updated related tests and added explicit cache-removal wiring coverage: - `packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts` - `packages/billing/src/components/invoice-designer/DesignerVisualWorkspace.test.tsx` - `packages/billing/src/actions/invoiceTemplatePreviewCacheRemoval.test.ts` (new). Rationale: - Preview execution no longer compiles or executes Wasm, so compile-artifact cache lifecycle is obsolete and removed. Commands run: - `pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts packages/billing/src/actions/invoiceTemplatePreviewCacheRemoval.test.ts` (pass). - `pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoicePdfGenerationAstWiring.test.ts` (pass). ### 2026-02-12 — F025 implemented - Deleted PRD-listed legacy compiler/executor modules from billing package: - `packages/billing/src/components/invoice-designer/compiler/guiIr.ts` - `packages/billing/src/components/invoice-designer/compiler/assemblyScriptGenerator.ts` - `packages/billing/src/components/invoice-designer/compiler/diagnostics.ts` - `packages/billing/src/lib/invoice-template-compiler/assemblyScriptCompile.ts` - `packages/billing/src/lib/invoice-renderer/wasm-executor.ts` - `packages/billing/src/lib/invoice-renderer/quickjs-executor.ts` - `packages/billing/src/lib/invoice-renderer/host-functions.ts` - Removed associated dead test/snapshot scaffolding tied to deleted modules. - Reworked affected action paths to remove imports of deleted modules: - `packages/billing/src/actions/invoiceTemplatePreview.ts` now only contains AST preview runtime path, - `packages/billing/src/actions/invoiceTemplates.ts` no longer imports compiler helper module. - Added explicit removal wiring test: - `packages/billing/src/actions/invoiceLegacyCompilerRemoval.test.ts`. Rationale: - This removes the custom compiler/executor layer from billing runtime code and enforces absence via tests. Commands run: - `pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoiceLegacyCompilerRemoval.test.ts packages/billing/src/actions/invoiceTemplateCompileParity.test.ts packages/billing/src/actions/invoiceTemplateAstPersistenceWiring.test.ts` (pass). - `pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts packages/billing/src/actions/invoiceTemplatePreview.inv005.sanity.test.ts packages/billing/src/actions/invoicePdfGenerationAstWiring.test.ts packages/billing/src/actions/invoiceTemplatePreviewCacheRemoval.test.ts` (pass). ### 2026-02-12 — F026 implemented - Removed save-time AssemblyScript compile and Wasm persistence behavior from invoice template actions: - `packages/billing/src/actions/invoiceTemplates.ts` - `saveInvoiceTemplate` now persists template metadata directly (AST canonical) without compile gating. - `compileAndSaveTemplate` retained as compatibility API shape but now performs direct metadata save (no compile command, no Wasm generation). - `compileStandardTemplate` now updates `assemblyScriptSource`/`templateAst`/`sha` only and no longer writes compiled `wasmBinary` artifacts. - Updated startup sync behavior accordingly: - `server/src/lib/startupTasks.ts` no longer treats missing `wasmBinary` as a recompilation trigger. - Updated wiring tests to enforce no save-time compile path: - `packages/billing/src/actions/invoiceTemplateAstPersistenceWiring.test.ts` - `packages/billing/src/actions/invoiceTemplateCompileParity.test.ts` Rationale: - Template save/update behavior now reflects AST-as-data architecture and avoids compiler lifecycle during persistence. Commands run: - `pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoiceTemplateAstPersistenceWiring.test.ts packages/billing/src/actions/invoiceTemplateCompileParity.test.ts packages/billing/src/actions/invoicePdfGenerationAstWiring.test.ts` (pass). - `pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts packages/billing/src/actions/invoiceTemplatePreview.inv005.sanity.test.ts packages/billing/src/actions/invoiceLegacyCompilerRemoval.test.ts` (pass). ### 2026-02-12 — F027 implemented - Removed runtime dependency on `getCompiledWasm` for invoice rendering paths. - Active render entry points now use AST evaluator/renderer stack and do not fetch compiled Wasm: - `packages/billing/src/actions/invoiceTemplates.ts` (`renderTemplateOnServer`) - `server/src/services/pdf-generation.service.ts` - `packages/billing/src/actions/invoiceTemplatePreview.ts` - `getCompiledWasm` action remains only as an explicit unsupported guard path and is not used by rendering flows. - Added/updated wiring assertions to prevent regressions: - `packages/billing/src/actions/invoicePdfGenerationAstWiring.test.ts` - `packages/billing/src/actions/invoiceLegacyCompilerRemoval.test.ts` Rationale: - Invoice runtime rendering no longer depends on Wasm artifact retrieval lifecycle. Commands run: - `pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoiceTemplateAstPersistenceWiring.test.ts packages/billing/src/actions/invoiceTemplateCompileParity.test.ts packages/billing/src/actions/invoicePdfGenerationAstWiring.test.ts` (pass). - `pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts packages/billing/src/actions/invoiceTemplatePreview.inv005.sanity.test.ts packages/billing/src/actions/invoiceLegacyCompilerRemoval.test.ts` (pass). ### 2026-02-12 — F028 implemented - Defined and verified compatibility behavior where legacy template columns may coexist with canonical AST payloads. - Runtime rendering paths now explicitly treat `templateAst` as canonical and do not consume legacy `assemblyScriptSource`/`wasmBinary` columns: - `server/src/services/pdf-generation.service.ts` - `packages/billing/src/actions/invoiceTemplates.ts` (`renderTemplateOnServer`) - Extended wiring coverage: - `packages/billing/src/actions/invoicePdfGenerationAstWiring.test.ts` - new assertion checks render-action block uses `template.templateAst` and does not depend on legacy runtime columns. Rationale: - Legacy columns remain available as temporary scaffolding, but runtime cutover behavior is AST-first and deterministic. Commands run: - `pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoicePdfGenerationAstWiring.test.ts` (pass). ### 2026-02-12 — F029 implemented - Reinforced no-arbitrary-code security posture at runtime by exercising strategy allowlist enforcement through preview action integration. - Added preview integration coverage for non-allowlisted strategy rejection: - `packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts` - mocks AST export with an invalid `strategyId` and asserts structured `UNKNOWN_STRATEGY` evaluator diagnostics are returned. - Existing strategy registry/evaluator guardrails remain in place: - allowlist checks in `packages/billing/src/lib/invoice-template-ast/strategies.ts` - evaluator rejection path in `packages/billing/src/lib/invoice-template-ast/evaluator.ts`. Rationale: - Strategy execution remains constrained to explicit allowlisted functions and rejects arbitrary IDs in runtime paths. Commands run: - `pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts` (pass). ### 2026-02-12 — F030 implemented - Expanded evaluator unit coverage for transform semantics and edge behavior in: - `packages/billing/src/lib/invoice-template-ast/evaluator.test.ts` - Added coverage for: - explicit composition order behavior (`filter -> sort -> group -> aggregate`), - empty-item edge case behavior for grouping/aggregate/totals composition outputs. - Existing AST schema + strategy + evaluator unit suites now cover core transform semantics comprehensively. Rationale: - These tests harden deterministic transform semantics and prevent regressions in composition/edge-case handling. Commands run: - `pnpm vitest --coverage.enabled=false packages/billing/src/lib/invoice-template-ast/evaluator.test.ts packages/billing/src/lib/invoice-template-ast/schema.test.ts packages/billing/src/lib/invoice-template-ast/strategies.test.ts` (pass). ### 2026-02-12 — F031 implemented - Established integration coverage for AST-based preview pipeline in: - `packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts` - `packages/billing/src/actions/invoiceTemplatePreview.inv005.sanity.test.ts` - Covered integration behaviors include: - end-to-end preview action success over AST validation -> evaluator -> renderer, - schema diagnostic surfacing, - evaluator diagnostic surfacing, - strategy allowlist rejection surfaced through preview diagnostics, - realistic invoice fixture rendering sanity via mapped invoice payload. Rationale: - Preview integration tests now exercise the AST pipeline directly without compiler/Wasm execution dependencies. Commands run: - `pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts` (pass). - `pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoiceTemplatePreview.inv005.sanity.test.ts` (pass). ### 2026-02-12 — F032 implemented - Added integration-style coverage for shared AST renderer in server-side invoice render action: - `packages/billing/src/actions/renderTemplateOnServer.ast.integration.test.ts` - Coverage verifies: - canonical `templateAst` payload renders HTML/CSS through `renderTemplateOnServer`, - missing AST payloads fail explicitly, preventing silent legacy runtime fallback. Rationale: - PDF/server rendering path now has executable tests validating AST renderer behavior beyond static wiring assertions. Commands run: - `pnpm vitest --coverage.enabled=false packages/billing/src/actions/renderTemplateOnServer.ast.integration.test.ts` (pass). ### 2026-02-12 — F033 implemented - Added preview/PDF parity integration test: - `packages/billing/src/actions/invoicePreviewPdfParity.integration.test.ts` - Test exercises both render entry points with identical AST + invoice fixture: - preview action: `runAuthoritativeInvoiceTemplatePreview` - server render action: `renderTemplateOnServer` - Parity assertions include: - exact HTML/CSS equality, - totals value parity (`Grand Total`), - grouped section ordering parity (`Products` before `Services`). Rationale: - This provides direct automated guardrails against semantic drift between preview and PDF/server render pipelines. Commands run: - `pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoicePreviewPdfParity.integration.test.ts` (pass). ### 2026-02-12 — F034 implemented - Replaced outdated invoice template architecture documentation with AST cutover documentation: - `docs/billing/invoice_templates.md` - Documentation now describes: - canonical `InvoiceTemplateAst` model and runtime modules, - shared preview/PDF evaluator+renderer pipeline, - allowlisted `strategyId` extension mechanism, - compatibility behavior for legacy columns, - explicit deletion/removal notes for compiler/Wasm stack. Rationale: - Prior docs still described AssemblyScript/Wasm execution path and removed modules. Updated docs now align with runtime reality and PRD cutover architecture. Verification: - Manual doc review of `docs/billing/invoice_templates.md` for AST pipeline and removal notes coverage. ### 2026-02-12 — T001 implemented - Marked minimal valid AST schema acceptance as implemented via schema unit coverage. - Evidence: packages/billing/src/lib/invoice-template-ast/schema.test.ts::validates a minimal AST document Verification: - \ WARN  Unsupported engine: wanted: {"node":">=20 <25"} (current: {"node":"v25.5.0","pnpm":"9.15.9"}) RUN v3.2.4 /Users/roberisaacs/alga-psa.worktrees/codex/feature-invoice-designer Running tests with seed "1770925966224" Environment file path: /Users/roberisaacs/alga-psa.worktrees/codex/feature-invoice-designer/.env.localtest stdout | ee/server/src/lib/extensions/__tests__/assets/url.shared.test.ts > buildExtUiSrc > honors public base override [ext-ui][buildExtUiSrc] { extensionId: 'ext-1', mode: 'rust', clientPath: '/', tenantId: 'tenant-123', overrideBase: 'http://localhost:8085', runnerBase: undefined, publicBase: 'http://localhost:8085' } stdout | ee/server/src/lib/extensions/__tests__/assets/url.shared.test.ts > buildExtUiSrc > supports relative public base for gateway proxy [ext-ui][buildExtUiSrc] { extensionId: 'ext-1', mode: 'rust', clientPath: '/', tenantId: undefined, overrideBase: null, runnerBase: '/runner', publicBase: '/runner' } stdout | ee/server/src/lib/extensions/__tests__/assets/url.shared.test.ts > buildExtUiSrc > uses absolute public base when provided [ext-ui][buildExtUiSrc] { extensionId: 'ext-1', mode: 'rust', clientPath: '/settings', tenantId: undefined, overrideBase: null, runnerBase: 'https://runner.dev/alga', publicBase: 'https://runner.dev/alga' } stdout | ee/server/src/lib/extensions/__tests__/assets/url.shared.test.ts > buildExtUiSrc > appends tenant when provided [ext-ui][buildExtUiSrc] { extensionId: 'ext-1', mode: 'rust', clientPath: '/', tenantId: 'tenant-123', overrideBase: null, runnerBase: undefined, publicBase: '/runner' } stdout | ee/server/src/lib/extensions/__tests__/assets/url.shared.test.ts > buildExtUiSrc > falls back to /runner when no public base is set [ext-ui][buildExtUiSrc] { extensionId: 'ext-1', mode: 'rust', clientPath: '/', tenantId: undefined, overrideBase: null, runnerBase: undefined, publicBase: '/runner' } ✓ ee/server/src/lib/extensions/__tests__/assets/url.shared.test.ts (5 tests) 3ms 36 MB heap used ✓ packages/billing/src/lib/invoice-template-ast/react-renderer.test.tsx (3 tests) 8ms 41 MB heap used ✓ packages/billing/src/lib/invoice-template-ast/strategies.test.ts (2 tests) 1ms 42 MB heap used ✓ ee/server/src/__tests__/unit/tenant-creation.test.ts (4 tests) 1ms 43 MB heap used ✓ packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts (4 tests) 6ms 68 MB heap used ✓ ee/server/src/__tests__/unit/routeParams.resolveInstallId.test.ts (3 tests) 0ms 52 MB heap used ❯ ee/temporal-workflows/src/activities/__tests__/email-activities-simple.test.ts (24 tests | 17 failed) 914ms 79 MB heap used × Email Activities - Simple Tests > generateTemporaryPassword > should generate password with default length of 12 0ms → expected Promise{…} to have property 'length' × Email Activities - Simple Tests > generateTemporaryPassword > should generate password with custom length 0ms → expected Promise{…} to have property 'length' ✓ Email Activities - Simple Tests > generateTemporaryPassword > should generate different passwords each time 0ms × Email Activities - Simple Tests > generateTemporaryPassword > should contain at least one character from each category 0ms → .toMatch() expects to receive a string, but got object × Email Activities - Simple Tests > generateTemporaryPassword > should not contain ambiguous characters 0ms → .toMatch() expects to receive a string, but got object × Email Activities - Simple Tests > generateTemporaryPassword > should handle minimum length of 4 0ms → expected Promise{…} to have property 'length' ✓ Email Activities - Simple Tests > generateTemporaryPassword > should generate secure passwords with high entropy 0ms × Email Activities - Simple Tests > MockEmailService > should send emails successfully 101ms → Cannot read properties of undefined (reading 'info') ✓ Email Activities - Simple Tests > MockEmailService > should validate email addresses correctly 0ms × Email Activities - Simple Tests > MockEmailService > should track sent emails for testing 102ms → Cannot read properties of undefined (reading 'info') × Email Activities - Simple Tests > MockEmailService > should filter emails by recipient 101ms → Cannot read properties of undefined (reading 'info') ✓ Email Activities - Simple Tests > MockEmailService > should simulate failures when configured 101ms × Email Activities - Simple Tests > MockEmailService > should handle invalid email addresses 100ms → Cannot read properties of undefined (reading 'info') × Email Activities - Simple Tests > MockEmailService > should handle multiple recipients 100ms → Cannot read properties of undefined (reading 'info') ✓ Email Activities - Simple Tests > MockEmailService > should throw error when no valid recipients 101ms × Email Activities - Simple Tests > MockEmailService > should support email service configuration 0ms → expected Promise{…} to be an instance of MockEmailService ✓ Email Activities - Simple Tests > MockEmailService > should return email templates for testing 0ms ✓ Email Activities - Simple Tests > MockEmailService > should return null for unknown templates 0ms × Email Activities - Simple Tests > MockEmailService > should support clearing sent emails 100ms → Cannot read properties of undefined (reading 'info') × Email Activities - Simple Tests > MockEmailService > should handle delay configuration 102ms → Cannot read properties of undefined (reading 'info') × Email Activities - Simple Tests > Email Service Factory > should create mock service by default 0ms → expected Promise{…} to be an instance of MockEmailService × Email Activities - Simple Tests > Email Service Factory > should create mock service when explicitly requested 0ms → expected Promise{…} to be an instance of MockEmailService × Email Activities - Simple Tests > Email Service Factory > should throw error for unknown providers 0ms → expected [Function] to throw an error × Email Activities - Simple Tests > Email Service Factory > should pass options to mock service 2ms → expected Promise{…} to be an instance of MockEmailService ✓ server/src/test/unit/readAssistantContentFromSse.test.ts (1 test) 2ms 81 MB heap used stdout | server/src/test/e2e/api/projects.e2e.test.ts > Projects API E2E Tests Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/e2e/api/projects.e2e.test.ts > Projects API E2E Tests CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/e2e/api/projects.e2e.test.ts > Projects API E2E Tests CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/projects.e2e.test.ts > Projects API E2E Tests Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/projects.e2e.test.ts > Projects API E2E Tests CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/projects.e2e.test.ts > Projects API E2E Tests Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/e2e/api/projects.e2e.test.ts (22 tests | 22 skipped) 24ms 109 MB heap used ↓ Projects API E2E Tests > Authentication > should reject requests without API key ↓ Projects API E2E Tests > Authentication > should reject requests with invalid API key ↓ Projects API E2E Tests > Authentication > should accept requests with valid API key ↓ Projects API E2E Tests > CRUD Operations > should create a project ↓ Projects API E2E Tests > CRUD Operations > should get a project by ID ↓ Projects API E2E Tests > CRUD Operations > should update a project ↓ Projects API E2E Tests > CRUD Operations > should delete a project ↓ Projects API E2E Tests > CRUD Operations > should list projects with pagination ↓ Projects API E2E Tests > Project Search > should search projects by query ↓ Projects API E2E Tests > Project Statistics > should get project statistics ↓ Projects API E2E Tests > Project Tasks and Tickets > should get project tasks ↓ Projects API E2E Tests > Project Tasks and Tickets > should get project tickets ↓ Projects API E2E Tests > Error Handling > should return 404 for non-existent project ↓ Projects API E2E Tests > Error Handling > should return 400 for invalid project data ↓ Projects API E2E Tests > Error Handling > should return 400 for invalid UUID ↓ Projects API E2E Tests > Filtering > should filter projects by status ↓ Projects API E2E Tests > Filtering > should filter projects by type ↓ Projects API E2E Tests > Filtering > should filter projects by client ↓ Projects API E2E Tests > Project Export > should export projects as CSV ↓ Projects API E2E Tests > Project Export > should export projects as JSON ↓ Projects API E2E Tests > Permissions > should enforce read permissions for listing ↓ Projects API E2E Tests > Permissions > should enforce create permissions ✓ server/src/test/unit/billingPlanSelection.test.ts (5 tests | 1 skipped) 1ms 117 MB heap used stdout | packages/client-portal/src/actions/client-portal-actions/client-tickets.responseSource.test.ts > addClientTicketComment response source metadata > T001: stores metadata.responseSource=client_portal when inserting a client comment Usage statistics enabled (user IDs anonymized) stdout | packages/client-portal/src/actions/client-portal-actions/client-tickets.responseSource.test.ts > addClientTicketComment response source metadata > T001: stores metadata.responseSource=client_portal when inserting a client comment Converted markdown content for client comment: markdown-content ❯ packages/client-portal/src/actions/client-portal-actions/client-tickets.responseSource.test.ts (1 test | 1 failed) 210ms 127 MB heap used × addClientTicketComment response source metadata > T001: stores metadata.responseSource=client_portal when inserting a client comment 210ms → Failed to add comment ✓ server/src/test/unit/docs/contractPurchaseOrderSupport.docs.test.ts (1 test) 1ms 129 MB heap used ✓ server/src/test/unit/workflowsCeStubEntry.unit.test.tsx (1 test) 0ms 131 MB heap used ✓ packages/projects/src/lib/timeEntryContext.test.ts (1 test) 0ms 135 MB heap used ✓ packages/billing/src/components/invoice-designer/state/designerStore.layout.test.ts (5 tests) 3ms 112 MB heap used ✓ packages/billing/src/actions/invoiceTemplatePreviewCacheRemoval.test.ts (2 tests) 0ms 119 MB heap used ✓ sdk/samples/component/invoicing-demo/tests/handler.test.ts (4 tests) 1ms 122 MB heap used ✓ server/src/test/unit/ui/reopenForEdits.test.ts (2 tests) 1ms 123 MB heap used ❯ packages/ui/src/context/SchedulingContext.test.tsx (4 tests | 4 failed) 1ms 136 MB heap used × SchedulingContext > returns default callbacks when no provider is present 0ms → document is not defined × SchedulingContext > renders fallback alert element for agent schedule by default 0ms → document is not defined × SchedulingContext > shows a toast when launching time entry without provider 0ms → document is not defined × SchedulingContext > uses provider callbacks when SchedulingCallbackProvider is present 1ms → document is not defined stdout | server/src/test/unit/project-actions/phaseReordering.test.ts > Phase Reordering Logic > Real-world Phase Drag Scenario > should handle dragging phase to before the first phase Moving Phase 3 before Phase 1: new key = Zz stdout | server/src/test/unit/project-actions/phaseReordering.test.ts > Phase Reordering Logic > Fractional Indexing Key Generation > should handle multiple insertions at the beginning Keys after multiple insertions at beginning: [ 'Zv', 'Zw', 'Zx', 'Zy', 'Zz', 'a0' ] stdout | server/src/test/unit/project-actions/phaseReordering.test.ts > Phase Reordering Logic > Fractional Indexing Key Generation > should generate correct key when placing phase at the end Key for placing after last: a6 (should be > a5) stdout | server/src/test/unit/project-actions/phaseReordering.test.ts > Phase Reordering Logic > Fractional Indexing Key Generation > should generate correct key when placing phase between two phases Key for placing between: a1V (should be between a1 and a2) stdout | server/src/test/unit/project-actions/phaseReordering.test.ts > Phase Reordering Logic > Fractional Indexing Key Generation > should generate correct key when placing phase at the beginning Key for placing before first: Zz (should be < a0) ✓ server/src/test/unit/project-actions/phaseReordering.test.ts (9 tests) 1ms 138 MB heap used ✓ packages/event-bus/src/index.pending.test.ts (1 test) 18ms 120 MB heap used ✓ sdk/samples/component/scheduler-demo/tests/handler.test.ts (6 tests) 1ms 127 MB heap used ✓ packages/billing/src/components/invoice-designer/state/designerStore.labelText.test.ts (4 tests) 2ms 140 MB heap used ❯ server/src/test/unit/timePeriodSuggester.test.ts (10 tests | 10 failed) 10ms 155 MB heap used × TimePeriodSuggester > suggestNewTimePeriod > should suggest monthly periods with no existing periods 0ms → expected undefined to be '2026-02-12' // Object.is equality × TimePeriodSuggester > suggestNewTimePeriod > should suggest monthly periods with existing periods 0ms → expected undefined to be '2025-02-01' // Object.is equality × TimePeriodSuggester > suggestNewTimePeriod > should suggest weekly periods 1ms → expected undefined to be '2026-02-12' // Object.is equality × TimePeriodSuggester > suggestNewTimePeriod > should suggest yearly periods 0ms → expected undefined to be '2026-02-12' // Object.is equality × TimePeriodSuggester > suggestNewTimePeriod > should handle multiple semi-monthly settings together 1ms → expected undefined to be '2025-01-01' // Object.is equality × TimePeriodSuggester > suggestNewTimePeriod > should handle February correctly in leap years 1ms → expected undefined to be '2024-02-01' // Object.is equality × TimePeriodSuggester > suggestNewTimePeriod > should select settings based on period start date, not current date 1ms → expected undefined to be '2025-01-15' // Object.is equality × TimePeriodSuggester > suggestNewTimePeriod > should handle current date before next period start date in semi-monthly periods 0ms → expected undefined to be '2025-01-15' // Object.is equality × TimePeriodSuggester > suggestNewTimePeriod > should suggest next period after existing periods 5ms → expected undefined to be '2025-01-14' // Object.is equality × TimePeriodSuggester > suggestNewTimePeriod > should suggest period starting in the future after current date 0ms → expected undefined to be '2025-06-01' // Object.is equality stdout | server/src/test/integration/accounting/exportDashboard.integration.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/accounting/exportDashboard.integration.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/accounting/exportDashboard.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/accounting/exportDashboard.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/accounting/exportDashboard.integration.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/accounting/exportDashboard.integration.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/accounting/exportDashboard.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/accounting/exportDashboard.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/teams.e2e.test.ts > Teams API E2E Tests Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/e2e/api/teams.e2e.test.ts > Teams API E2E Tests CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/e2e/api/teams.e2e.test.ts > Teams API E2E Tests CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/teams.e2e.test.ts > Teams API E2E Tests Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/teams.e2e.test.ts > Teams API E2E Tests CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/teams.e2e.test.ts > Teams API E2E Tests Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/e2e/api/teams.e2e.test.ts (36 tests | 36 skipped) 2ms 200 MB heap used ↓ Teams API E2E Tests > Authentication > should require API key for all endpoints ↓ Teams API E2E Tests > Authentication > should reject invalid API key ↓ Teams API E2E Tests > CRUD Operations > Create Team (POST /api/v1/teams) > should create a new team ↓ Teams API E2E Tests > CRUD Operations > Create Team (POST /api/v1/teams) > should validate required fields ↓ Teams API E2E Tests > CRUD Operations > Create Team (POST /api/v1/teams) > should validate manager_id is a valid user ↓ Teams API E2E Tests > CRUD Operations > Get Team (GET /api/v1/teams/:id) > should retrieve a team by ID ↓ Teams API E2E Tests > CRUD Operations > Get Team (GET /api/v1/teams/:id) > should return 404 for non-existent team ↓ Teams API E2E Tests > CRUD Operations > Get Team (GET /api/v1/teams/:id) > should not return teams from other tenants ↓ Teams API E2E Tests > CRUD Operations > Update Team (PUT /api/v1/teams/:id) > should update a team ↓ Teams API E2E Tests > CRUD Operations > Update Team (PUT /api/v1/teams/:id) > should return 404 when updating non-existent team ↓ Teams API E2E Tests > CRUD Operations > Update Team (PUT /api/v1/teams/:id) > should validate update data ↓ Teams API E2E Tests > CRUD Operations > Delete Team (DELETE /api/v1/teams/:id) > should delete a team ↓ Teams API E2E Tests > CRUD Operations > Delete Team (DELETE /api/v1/teams/:id) > should return 404 when deleting non-existent team ↓ Teams API E2E Tests > CRUD Operations > Delete Team (DELETE /api/v1/teams/:id) > should handle teams with members ↓ Teams API E2E Tests > List Teams (GET /api/v1/teams) > should list all teams with default pagination ↓ Teams API E2E Tests > List Teams (GET /api/v1/teams) > should support pagination parameters ↓ Teams API E2E Tests > List Teams (GET /api/v1/teams) > should filter by search query ↓ Teams API E2E Tests > List Teams (GET /api/v1/teams) > should sort teams ↓ Teams API E2E Tests > Team Manager Assignment > Assign Team Manager (PUT /api/v1/teams/:id/manager) > should assign manager and automatically add them as team member ↓ Teams API E2E Tests > Team Manager Assignment > Assign Team Manager (PUT /api/v1/teams/:id/manager) > should not duplicate member if manager is already a team member ↓ Teams API E2E Tests > Team Creation with Manager > should automatically add manager as team member when creating team ↓ Teams API E2E Tests > Team Members > Add Team Member (POST /api/v1/teams/:id/members) > should add a member to a team ↓ Teams API E2E Tests > Team Members > Add Team Member (POST /api/v1/teams/:id/members) > should prevent duplicate members ↓ Teams API E2E Tests > Team Members > Add Team Member (POST /api/v1/teams/:id/members) > should validate user exists ↓ Teams API E2E Tests > Team Members > List Team Members (GET /api/v1/teams/:id/members) > should list team members ↓ Teams API E2E Tests > Team Members > Remove Team Member (DELETE /api/v1/teams/:id/members/:userId) > should remove a member from team ↓ Teams API E2E Tests > Team Members > Remove Team Member (DELETE /api/v1/teams/:id/members/:userId) > should return 404 for non-existent member ↓ Teams API E2E Tests > Team Statistics > should get team statistics ↓ Teams API E2E Tests > Error Handling > should handle invalid UUID format ↓ Teams API E2E Tests > Error Handling > should handle invalid query parameters ↓ Teams API E2E Tests > Error Handling > should handle missing required fields on create ↓ Teams API E2E Tests > Permissions > should enforce read permissions for listing ↓ Teams API E2E Tests > Permissions > should enforce create permissions ↓ Teams API E2E Tests > Permissions > should enforce update permissions ↓ Teams API E2E Tests > Permissions > should enforce delete permissions ↓ Teams API E2E Tests > Multi-tenancy > should isolate teams by tenant stdout | server/src/test/integration/contractWizard.integration.test.ts > createClientContractFromWizard Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/contractWizard.integration.test.ts > createClientContractFromWizard CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/contractWizard.integration.test.ts > createClientContractFromWizard CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/contractWizard.integration.test.ts > createClientContractFromWizard Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/contractWizard.integration.test.ts > createClientContractFromWizard CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/contractWizard.integration.test.ts > createClientContractFromWizard Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/integration/contractWizard.integration.test.ts (1 test | 1 skipped) 2ms 207 MB heap used ↓ createClientContractFromWizard > creates downstream client records for fixed-fee contracts ✓ server/src/test/unit/workflowBundleCli.unit.test.ts (2 tests) 4ms 244 MB heap used ✓ packages/core/src/lib/logger.test.ts (1 test) 0ms 247 MB heap used stdout | server/src/test/integration/billing/contractPurchaseOrderSupport.integration.test.ts > Contract Purchase Order Support Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/billing/contractPurchaseOrderSupport.integration.test.ts > Contract Purchase Order Support CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/billing/contractPurchaseOrderSupport.integration.test.ts > Contract Purchase Order Support CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/billing/contractPurchaseOrderSupport.integration.test.ts > Contract Purchase Order Support Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/billing/contractPurchaseOrderSupport.integration.test.ts > Contract Purchase Order Support CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/billing/contractPurchaseOrderSupport.integration.test.ts > Contract Purchase Order Support Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/integration/billing/contractPurchaseOrderSupport.integration.test.ts (5 tests | 5 skipped) 2ms 251 MB heap used ↓ Contract Purchase Order Support > T001: invoices table includes po_number + client_contract_id ↓ Contract Purchase Order Support > T002: invoice creation snapshots client_contracts.po_number onto invoices.po_number ↓ Contract Purchase Order Support > T003: invoice generation blocks when po_required=true and po_number is missing ↓ Contract Purchase Order Support > T004: PO consumption sums finalized invoices and unconsumes when status changes away from finalized ↓ Contract Purchase Order Support > T005: overage calculation uses invoice total_amount and contract po_amount (authorized total spend) ✓ server/src/test/unit/tenantSettingsActions.experimentalFeatures.test.ts (10 tests) 7ms 216 MB heap used stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Time Tracking > should stop a tracking session Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Time Tracking > should stop a tracking session CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Time Tracking > should stop a tracking session CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Time Tracking > should stop a tracking session Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Time Tracking > should stop a tracking session CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Time Tracking > should stop a tracking session Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Time Tracking > should start a tracking session CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Time Tracking > should start a tracking session Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Time Tracking > should start a tracking session CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Time Tracking > should start a tracking session Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by user CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by user Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by user CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by user Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should sort by date CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should sort by date Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should sort by date CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should sort by date Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should support pagination parameters CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should support pagination parameters Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should support pagination parameters CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should support pagination parameters Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by date range CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by date range Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by date range CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by date range Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by billable status CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by billable status Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by billable status CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by billable status Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should list time entries with default pagination CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should list time entries with default pagination Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should list time entries with default pagination CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should list time entries with default pagination Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Export > should export time entries to JSON CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Export > should export time entries to JSON Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Export > should export time entries to JSON CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Export > should export time entries to JSON Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Export > should export time entries to CSV CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Export > should export time entries to CSV Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Export > should export time entries to CSV CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Export > should export time entries to CSV Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Templates > should list time entry templates CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Templates > should list time entry templates Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Templates > should list time entry templates CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Templates > should list time entry templates Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce delete permissions CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce delete permissions Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce delete permissions CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce delete permissions Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce create permissions CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce create permissions Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce create permissions CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce create permissions Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce update permissions CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce update permissions Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce update permissions CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce update permissions Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce read permissions for listing CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce read permissions for listing Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce read permissions for listing CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce read permissions for listing Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Bulk Operations > should bulk delete time entries CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Bulk Operations > should bulk delete time entries Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Bulk Operations > should bulk delete time entries CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Bulk Operations > should bulk delete time entries Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Bulk Operations > should bulk update time entries CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Bulk Operations > should bulk update time entries Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Bulk Operations > should bulk update time entries CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Bulk Operations > should bulk update time entries Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Bulk Operations > should bulk create time entries CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Bulk Operations > should bulk create time entries Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Bulk Operations > should bulk create time entries CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Bulk Operations > should bulk create time entries Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Multi-tenancy > should isolate time entries by tenant CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Multi-tenancy > should isolate time entries by tenant Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Multi-tenancy > should isolate time entries by tenant CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Multi-tenancy > should isolate time entries by tenant Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should not allow deleting approved entries CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should not allow deleting approved entries Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should not allow deleting approved entries CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should not allow deleting approved entries Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should return 404 when deleting non-existent entry CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should return 404 when deleting non-existent entry Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should return 404 when deleting non-existent entry CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should return 404 when deleting non-existent entry Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should delete a time entry CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should delete a time entry Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should delete a time entry CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should delete a time entry Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should not return time entries from other tenants CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should not return time entries from other tenants Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should not return time entries from other tenants CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should not return time entries from other tenants Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should return 404 for non-existent time entry CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should return 404 for non-existent time entry Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should return 404 for non-existent time entry CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should return 404 for non-existent time entry Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should retrieve a time entry by ID CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should retrieve a time entry by ID Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should retrieve a time entry by ID CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should retrieve a time entry by ID Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should not allow updating approved entries CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should not allow updating approved entries Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should not allow updating approved entries CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should not allow updating approved entries Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should return 404 when updating non-existent entry CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should return 404 when updating non-existent entry Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should return 404 when updating non-existent entry CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should return 404 when updating non-existent entry Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should update a time entry CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should update a time entry Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should update a time entry CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should update a time entry Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should validate time periods overlap CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should validate time periods overlap Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should validate time periods overlap CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should validate time periods overlap Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should compute work_date in user timezone and bucket to the correct period CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should compute work_date in user timezone and bucket to the correct period Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should compute work_date in user timezone and bucket to the correct period CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should compute work_date in user timezone and bucket to the correct period Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should validate required fields CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should validate required fields Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should validate required fields CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should validate required fields Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should create a new time entry CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should create a new time entry Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should create a new time entry CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should create a new time entry Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Statistics > should get time entry statistics CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Statistics > should get time entry statistics Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Statistics > should get time entry statistics CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Statistics > should get time entry statistics Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Error Handling > should handle invalid date format CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Error Handling > should handle invalid date format Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Error Handling > should handle invalid date format CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Error Handling > should handle invalid date format Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Error Handling > should handle invalid query parameters CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Error Handling > should handle invalid query parameters Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Error Handling > should handle invalid query parameters CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Error Handling > should handle invalid query parameters Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Error Handling > should handle invalid UUID format CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Error Handling > should handle invalid UUID format Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Error Handling > should handle invalid UUID format CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Error Handling > should handle invalid UUID format Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Authentication > should reject invalid API key CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Authentication > should reject invalid API key Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Authentication > should reject invalid API key CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Authentication > should reject invalid API key Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Authentication > should require API key for all endpoints CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Authentication > should require API key for all endpoints Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Authentication > should require API key for all endpoints CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Authentication > should require API key for all endpoints Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/e2e/api/time-entries.e2e.test.ts (40 tests | 38 failed | 2 skipped) 33ms 236 MB heap used × Time Entries API E2E Tests > Authentication > should require API key for all endpoints 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Authentication > should reject invalid API key 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should create a new time entry 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should compute work_date in user timezone and bucket to the correct period 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should validate required fields 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should validate time periods overlap 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should retrieve a time entry by ID 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should return 404 for non-existent time entry 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should not return time entries from other tenants 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should update a time entry 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should return 404 when updating non-existent entry 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should not allow updating approved entries 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should delete a time entry 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should return 404 when deleting non-existent entry 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should not allow deleting approved entries 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should list time entries with default pagination 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should support pagination parameters 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by date range 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by user 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by billable status 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should sort by date 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Time Tracking > should start a tracking session 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Time Tracking > should stop a tracking session 2ms → → Cannot read properties of undefined (reading 'cleanup') ↓ Time Entries API E2E Tests > Approval Workflow > should approve time entries ↓ Time Entries API E2E Tests > Approval Workflow > should reject invalid entry IDs for approval × Time Entries API E2E Tests > Export > should export time entries to CSV 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Export > should export time entries to JSON 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Statistics > should get time entry statistics 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Templates > should list time entry templates 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Bulk Operations > should bulk create time entries 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Bulk Operations > should bulk update time entries 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Bulk Operations > should bulk delete time entries 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Error Handling > should handle invalid UUID format 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Error Handling > should handle invalid query parameters 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Error Handling > should handle invalid date format 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Permissions > should enforce read permissions for listing 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Permissions > should enforce create permissions 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Permissions > should enforce update permissions 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Permissions > should enforce delete permissions 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Multi-tenancy > should isolate time entries by tenant 1ms → → Cannot read properties of undefined (reading 'cleanup') ✓ server/src/test/unit/menuConfig.experimentalFeatures.test.ts (1 test) 0ms 143 MB heap used ✓ packages/billing/src/actions/invoiceTemplateAstPersistenceWiring.test.ts (3 tests) 1ms 145 MB heap used ✓ packages/billing/tests/deleteContractPermissions.test.ts (1 test) 18ms 150 MB heap used ✓ shared/lib/utils/emailFileConversion.test.ts (4 tests) 4ms 156 MB heap used ✓ ee/server/extensions/samples/ui-kit-showcase/test/scaffold.test.ts (8 tests) 1ms 170 MB heap used stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 59, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 58, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 57, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 56, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 55, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 54, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 53, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 52, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 51, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 50, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 49, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 48, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 47, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 46, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 45, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 44, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 43, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 42, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 41, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 40, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 39, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 38, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 37, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 36, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 35, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 34, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 33, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 32, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 31, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 30, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 29, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 28, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 27, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 26, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 25, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 24, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 23, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 22, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 21, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 20, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 19, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 18, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 17, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 16, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 15, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 14, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 13, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 12, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 11, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 10, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 9, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 8, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 7, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 6, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 5, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 4, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 3, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 2, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 1, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 0, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 0, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 59, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 58, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 57, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 56, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 55, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 54, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 53, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 52, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 51, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 50, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 49, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 48, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 47, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 46, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 45, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 44, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 43, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 42, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 41, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 40, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 39, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 38, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 37, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 36, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 35, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 34, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 33, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 32, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 31, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 30, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 29, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 28, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 27, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 26, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 25, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 24, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 23, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 22, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 21, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 20, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 19, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 18, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 17, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 16, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 15, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 14, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 13, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 12, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 11, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 10, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 9, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 8, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 7, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 6, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 5, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 4, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 3, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 2, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 1, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 0, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Rate limit exceeded { tenantId: 'tenant-1', userId: undefined, remaining: 0, needed: 1, retryAfterMs: 999 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should track tokens separately per user within a tenant [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should track tokens separately per user within a tenant [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: 'user-1', remaining: 1, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should track tokens separately per user within a tenant [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: 'user-1', remaining: 0, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should track tokens separately per user within a tenant [TokenBucketRateLimiter] Rate limit exceeded { tenantId: 'tenant-1', userId: 'user-1', remaining: 0, needed: 1, retryAfterMs: 1000 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should track tokens separately per user within a tenant [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: 'user-2', remaining: 1, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should allow multiple requests until bucket is empty [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should allow multiple requests until bucket is empty [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 2, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should allow multiple requests until bucket is empty [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 1, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should allow multiple requests until bucket is empty [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 0, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should allow multiple requests until bucket is empty [TokenBucketRateLimiter] Rate limit exceeded { tenantId: 'tenant-1', userId: undefined, remaining: 0, needed: 1, retryAfterMs: 1000 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should track tokens separately per tenant [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should track tokens separately per tenant [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 1, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should track tokens separately per tenant [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 0, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should track tokens separately per tenant [TokenBucketRateLimiter] Rate limit exceeded { tenantId: 'tenant-1', userId: undefined, remaining: 0, needed: 1, retryAfterMs: 1000 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should track tokens separately per tenant [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-2', userId: undefined, remaining: 1, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should allow request when bucket has tokens [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should allow request when bucket has tokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 59, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Shutdown > should cleanup on shutdown [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Shutdown > should cleanup on shutdown [TokenBucketRateLimiter] Shutdown complete stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Refill > should not exceed maxTokens when refilling [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Refill > should not exceed maxTokens when refilling [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 4, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Refill > should refill tokens over time [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Refill > should refill tokens over time [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 1, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Refill > should refill tokens over time [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 0, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Refill > should refill tokens over time [TokenBucketRateLimiter] Rate limit exceeded { tenantId: 'tenant-1', userId: undefined, remaining: 0, needed: 1, retryAfterMs: 100 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Refill > should refill tokens over time [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 1, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Retry After Calculation > should include reason when rate limited [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Retry After Calculation > should include reason when rate limited [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 0, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Retry After Calculation > should include reason when rate limited [TokenBucketRateLimiter] Rate limit exceeded { tenantId: 'tenant-1', userId: undefined, remaining: 0, needed: 1, retryAfterMs: 1000 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Retry After Calculation > should return correct retryAfterMs when rate limited [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Retry After Calculation > should return correct retryAfterMs when rate limited [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 0, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Retry After Calculation > should return correct retryAfterMs when rate limited [TokenBucketRateLimiter] Rate limit exceeded { tenantId: 'tenant-1', userId: undefined, remaining: 0, needed: 1, retryAfterMs: 1000 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Get State > should return full bucket for new tenant [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Get State > should return current bucket state [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Get State > should return current bucket state [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 9, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Get State > should return current bucket state [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 8, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Initialization > should warn if initialized twice [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Initialization > should initialize with Redis client [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } ✓ server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts (17 tests) 4ms 176 MB heap used ✓ packages/clients/src/lib/durationHelpers.test.ts (7 tests) 0ms 179 MB heap used ❯ server/src/test/unit/clientContractActions.overlapExclusive.test.ts (3 tests | 3 failed) 1ms 182 MB heap used × Client contract overlap validation ([start, end) semantics) > does not treat touching boundaries as overlap (start == invoiced period end) 0ms → Missing "./models/clientContract" specifier in "@alga-psa/clients" package × Client contract overlap validation ([start, end) semantics) > does not treat touching boundaries as overlap (end exclusive == invoiced period start) 0ms → Missing "./models/clientContract" specifier in "@alga-psa/clients" package × Client contract overlap validation ([start, end) semantics) > rejects true overlaps with an invoiced period 1ms → Missing "./models/clientContract" specifier in "@alga-psa/clients" package stdout | ee/server/src/__tests__/integration/extensionProxyFlow.test.ts > Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should handle Gateway errors and return error message to Client iframeBridge: received message { type: 'apiproxy', origin: 'http://localhost:3000' } iframeBridge: handling apiproxy { requestId: 'req-error', route: '/error-route' } stdout | ee/server/src/__tests__/integration/extensionProxyFlow.test.ts > Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should handle Gateway errors and return error message to Client iframeBridge: fetch completed { status: 500, ok: false, url: '/api/ext-proxy/test-extension-id/error-route' } stdout | ee/server/src/__tests__/integration/extensionProxyFlow.test.ts > Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should handle Gateway errors and return error message to Client iframeBridge: posting apiproxy_response { requestId: 'req-error', targetOrigin: '*' } stdout | ee/server/src/__tests__/integration/extensionProxyFlow.test.ts > Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should forward "apiproxy" message to Gateway and return response to Client iframeBridge: received message { type: 'apiproxy', origin: 'http://localhost:3000' } iframeBridge: handling apiproxy { requestId: 'req-123', route: '/tickets' } stdout | ee/server/src/__tests__/integration/extensionProxyFlow.test.ts > Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should forward "apiproxy" message to Gateway and return response to Client iframeBridge: fetch completed { status: undefined, ok: true, url: '/api/ext-proxy/test-extension-id/tickets' } stdout | ee/server/src/__tests__/integration/extensionProxyFlow.test.ts > Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should forward "apiproxy" message to Gateway and return response to Client iframeBridge: posting apiproxy_response (reader) { requestId: 'req-123', targetOrigin: '*' } ❯ ee/server/src/__tests__/integration/extensionProxyFlow.test.ts (4 tests | 2 failed) 198ms 92 MB heap used ✓ Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should forward "apiproxy" message to Gateway and return response to Client 55ms ✓ Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should handle Gateway errors and return error message to Client 59ms × Extension Proxy Flow Integration > Gateway Handler (Host -> Runner) > should forward request to RunnerBackend and propagate response headers/body 0ms → Failed to resolve import "@alga-psa/db/models/UserSession" from "packages/auth/src/lib/nextAuthOptions.ts". Does the file exist? × Extension Proxy Flow Integration > Gateway Handler (Host -> Runner) > should handle Runner errors gracefully 84ms → Failed to resolve import "@alga-psa/db/models/UserSession" from "packages/auth/src/lib/nextAuthOptions.ts". Does the file exist? stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx Retrieved secret 'db_password_server' from configured provider. ✓ packages/projects/tests/projectInfoDrawer.test.tsx (1 test) 63ms 104 MB heap used ✓ server/src/test/unit/components/AssetNotesPanel.test.tsx (1 test) 7ms 108 MB heap used stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/unit/Chat.streamingIncrementalState.test.tsx (9 tests | 8 failed) 81ms 137 MB heap used × EE Chat (streaming state) > updates the in-progress assistant message as tokens arrive 4ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
    
 ← Back to Projects 
  PRJ-100   Test Project  
        Save as Template   Materials      Edit       Client:   Client One 

    Contact:   N/A 

    Budget:    0.0  of  0.0  hours        
     Notes & Quick Info   aborts the streaming request when Stop is clicked 40ms × EE Chat (streaming state) > stops updating token display and ends generation state after Stop 6ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
    
 ← Back to Projects 
  PRJ-100   Test Project  
        Save as Template   Materials      Edit  
     Client:   Client One 

    Contact:   N/A 

    Budget:    0.0  of  0.0  hours        
     Notes & Quick Info   shows a streaming cursor while receiving tokens 3ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
    
 ← Back to Projects 
  PRJ-100   Test Project  
        Save as Template   Materials      Edit  
     Client:   Client One 

    Contact:   N/A 

    Budget:    0.0  of  0.0  hours        
     Notes & Quick Info   removes the streaming cursor when done is received 6ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
    
 ← Back to Projects 
  PRJ-100   Test Project  
        Save as Template   Materials      Edit  
     Client:   Client One 

    Contact:   N/A 

    Budget:    0.0  of  0.0  hours        
     Notes & Quick Info   shows the partial response when a network error occurs mid-stream 8ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
    
 ← Back to Projects 
  PRJ-100   Test Project  
        Save as Template   Materials      Edit  
     Client:   Client One 

    Contact:   N/A 

    Budget:    0.0  of  0.0  hours        
     Notes & Quick Info        Save  
       
           You  
   

 Ping 

                     Alga     

 Hi 

                  Press Ctrl+Enter or ⌘+Enter to send. 

   SEND    
 
  
 
  OK  
 
   
       I am Alga! Your favorite AI assistant. Ask me a question.  
         Press Ctrl+Enter or ⌘+Enter to send. 

   SEND    
 
  
 
  OK  
 
    × EE Chat (streaming state) > shows an interruption indicator when the stream ends without done=true 5ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
    
 ← Back to Projects 
  PRJ-100   Test Project  
        Save as Template   Materials      Edit       Client:   Client One 

    Contact:   N/A 

    Budget:    0.0  of  0.0  hours        
     Notes & Quick Info   persists the assistant message after streaming completes 4ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
    
 ← Back to Projects 
  PRJ-100   Test Project  
        Save as Template   Materials      Edit  
     Client:   Client One 

    Contact:   N/A 

    Budget:    0.0  of  0.0  hours        
     Notes & Quick Info   persists assistant content matching the final streamed tokens 4ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
    
 ← Back to Projects 
  PRJ-100   Test Project  
        Save as Template   Materials      Edit  
     Client:   Client One 

    Contact:   N/A 

    Budget:    0.0  of  0.0  hours        
     Notes & Quick Info   shows 'AI Assistant' name and description 1012ms → Found multiple elements with the text: AI Assistant Here are the matching elements: Ignored nodes: comments, script, style  AI Assistant 
 Ignored nodes: comments, script, style  AI Assistant  Ignored nodes: comments, script, style  AI Assistant  Ignored nodes: comments, script, style  AI Assistant  Ignored nodes: comments, script, style  AI Assistant  Ignored nodes: comments, script, style  AI Assistant  Ignored nodes: comments, script, style  AI Assistant  Ignored nodes: comments, script, style  AI Assistant  Ignored nodes: comments, script, style  AI Assistant  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
    
 ← Back to Projects 
  PRJ-100   Test Project  
        Save as Template   Materials      Edit       Client:   Client One 

    Contact:   N/A 

    Budget:    0.0  of  0.0  hours        
     Notes & Quick Info     
    
 ← Back to Projects 
  PRJ-100   Test Project  
        Save as Template   Materials      Edit  
     Client:   Client One 

    Contact:   N/A 

    Budget:    0.0  of  0.0  hours        
     Notes & Quick Info   defaults AI Assistant toggle to off 10ms × ExperimentalFeaturesSettings > renders experimental features warning banner 1006ms → Found multiple elements with the text: Experimental Here are the matching elements: Ignored nodes: comments, script, style  Experimental  Ignored nodes: comments, script, style  Experimental  Ignored nodes: comments, script, style  Experimental  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
    
 ← Back to Projects 
  PRJ-100   Test Project  
        Save as Template   Materials      Edit  
     Client:   Client One 

    Contact:   N/A 

    Budget:    0.0  of  0.0  hours        
     Notes & Quick Info     
    
 ← Back to Projects 
  PRJ-100   Test Project  
        Save as Template   Materials      Edit  
     Client:   Client One 

    Contact:   N/A 

    Budget:    0.0  of  0.0  hours        
     Notes & Quick Info   calls updateExperimentalFeatures() with current toggle states on save 1011ms → Found multiple elements with the role "button" and name "Save" Here are the matching elements: Ignored nodes: comments, script, style       Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
    
 ← Back to Projects 
  PRJ-100   Test Project  
        Save as Template   Materials      Edit  
     Client:   Client One 

    Contact:   N/A 

    Budget:    0.0  of  0.0  hours        
     Notes & Quick Info     
    
 ← Back to Projects 
  PRJ-100   Test Project  
        Save as Template   Materials      Edit  
     Client:   Client One 

    Contact:   N/A 

    Budget:    0.0  of  0.0  hours        
     Notes & Quick Info   shows success feedback after saving 1013ms → Found multiple elements with the role "button" and name "Save" Here are the matching elements: Ignored nodes: comments, script, style       Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
    
 ← Back to Projects 
  PRJ-100   Test Project  
        Save as Template   Materials      Edit  
     Client:   Client One 

    Contact:   N/A 

    Budget:    0.0  of  0.0  hours        
     Notes & Quick Info     
    
 ← Back to Projects 
  PRJ-100   Test Project  
        Save as Template   Materials      Edit  
     Client:   Client One 

    Contact:   N/A 

    Budget:    0.0  of  0.0  hours        
     Notes & Quick Info   updates local state when toggled 8ms ✓ ExperimentalFeaturesSettings > loads current settings on mount 4ms × ExperimentalFeaturesSettings > renders list of features with toggles 11ms → expected [ , …(7) ] to have a length of 2 but got 8 × ExperimentalFeaturesSettings > disables AI Assistant toggle when not allowed 5ms → expected 'true' to be 'false' // Object.is equality ❯ packages/billing/tests/contractWizardResume.test.tsx (14 tests | 14 failed) 48ms 167 MB heap used × ContractWizard resume behavior > starts at Step 1 (Contract Basics) when opened (T033) 1ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 1 shows pre-populated client selection from draft (T034) 2ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 1 shows pre-populated contract name from draft (T035) 2ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 1 shows pre-populated dates from draft (T036) 2ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 2 (Fixed Fee) shows pre-populated services from draft (T037) 1ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 3 (Products) shows pre-populated products from draft (T038) 2ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 4 (Hourly) shows pre-populated hourly services from draft (T039) 2ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 5 (Usage) shows pre-populated usage services from draft (T040) 1ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 6 (Review) shows complete draft data for review (T041) 1ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > clicking Save Draft in resumed wizard updates existing draft (T042) 2ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > save draft does not create a duplicate contract (T043) 1ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > save draft preserves the original contract_id (T044) 26ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > completing resumed wizard sets contract status to 'active' (T045) 2ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > completing resumed wizard sets is_active to true (T046) 2ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: ✓ packages/projects/src/components/__tests__/TaskQuickAddPrefill.test.tsx (1 test) 2ms 170 MB heap used stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx Retrieved secret 'db_password_server' from configured provider. stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx Retrieved secret 'postgres_password' from configured provider. stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/unit/RightSidebar.streaming.test.tsx (1 test | 1 failed) 1009ms 170 MB heap used × RightSidebar (streaming) > renders streaming Chat and posts to the streaming completions endpoint 1008ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
     Notes & Quick Info        Save  
 
      
           You  
   

 Ping 

                    [... Ignored nodes: comments, script, style    
     Notes & Quick Info        Save  
       
           You  
   

 Ping 

                    [... ✓ packages/billing/src/components/invoice-designer/DesignerShell.constraints.test.tsx (23 tests) 602ms 253 MB heap used ✓ packages/billing/src/components/invoice-designer/canvas/DesignCanvas.previewMode.test.tsx (15 tests) 50ms 260 MB heap used ❯ packages/billing/src/components/billing-dashboard/InvoiceTemplateEditor.previewWorkspace.test.tsx (11 tests | 1 failed) 1140ms 237 MB heap used ✓ InvoiceTemplateEditor preview workspace integration > preserves nested visual workspace state when switching Visual -> Code -> Visual 17ms ✓ InvoiceTemplateEditor preview workspace integration > hydrates workspace from source-embedded designer state 6ms ✓ InvoiceTemplateEditor preview workspace integration > hydrates workspace from localStorage fallback when source has no embedded state 11ms ✓ InvoiceTemplateEditor preview workspace integration > hydrates workspace from persisted templateAst payload 7ms ✓ InvoiceTemplateEditor preview workspace integration > keeps save payload behavior while preview sub-tab is active 20ms ✓ InvoiceTemplateEditor preview workspace integration > does not trigger save writes from preview interactions alone 6ms ✓ InvoiceTemplateEditor preview workspace integration > allows preview workspace access for new templates before name validation 10ms ✓ InvoiceTemplateEditor preview workspace integration > keeps Code tab generated/read-only for GUI templates 30ms × InvoiceTemplateEditor preview workspace integration > enables visual designer in local QA via forceInvoiceDesigner=1 when feature flag is off 1010ms → Unable to find an element by: [data-testid="designer-visual-workspace"] Ignored nodes: comments, script, style    
     Notes & Quick Info        Save  
       
           You  
   

 Ping 

                    [... Ignored nodes: comments, script, style      
     Notes & Quick Info        Save  
       
           You  
   

 Ping 

                   keeps production behavior when feature flag is off and no override is set 5ms ✓ InvoiceTemplateEditor preview workspace integration > keeps generated source synchronized with GUI model while switching Visual and Code 18ms ✓ server/src/test/unit/tickets/TicketEmailNotifications.ui.test.tsx (7 tests) 107ms 236 MB heap used ✓ packages/billing/src/components/invoice-designer/canvas/DesignCanvas.constraintHighlights.test.tsx (2 tests) 3ms 257 MB heap used ✓ packages/billing/src/components/invoice-designer/DesignerVisualWorkspace.test.tsx (28 tests) 1578ms 291 MB heap used ✓ DesignerVisualWorkspace > calls paginated invoice search with status=all and query filters 317ms ✓ DesignerVisualWorkspace > renders loading, empty, and error states for existing invoice list 620ms ✓ packages/billing/src/components/billing-dashboard/InvoiceTemplateEditor.authoritativeFlow.test.tsx (2 tests) 287ms 289 MB heap used ✓ packages/billing/tests/draftContractsTable.test.tsx (30 tests) 1622ms 380 MB heap used ✓ packages/projects/tests/projectMaterialsDrawer.test.tsx (16 tests) 162ms 398 MB heap used ✓ server/src/test/unit/email/EmailLogsClient.ui.test.tsx (6 tests) 951ms 392 MB heap used ✓ EmailLogsClient > updates results when date range filter changes 307ms ✓ EmailLogsClient > updates results when recipient search changes 307ms ✓ EmailLogsClient > updates results when ticket filter changes 308ms ✓ server/src/test/unit/QuickAskOverlay.streaming.test.tsx (1 test) 14ms 411 MB heap used ✓ packages/billing/tests/contractsActivationFlow.test.tsx (2 tests) 186ms 395 MB heap used Test Files 558 failed | 43 passed (601) Tests 105 failed | 274 passed | 66 skipped | 1 todo (446) Errors 1 error Start at 14:52:46 Duration 25.74s (transform 2.21s, setup 290ms, collect 2.93s, tests 13.48s, environment 235ms, prepare 52ms) (pass). ### 2026-02-12 — T001 implemented - Marked minimal AST schema acceptance as implemented. - Evidence: `packages/billing/src/lib/invoice-template-ast/schema.test.ts` (`validates a minimal AST document`). Verification: - `NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/lib/invoice-template-ast/schema.test.ts` (pass). ### 2026-02-12 — T002 implemented - Marked unknown node-type schema rejection with structured diagnostics as implemented. - Evidence: packages/billing/src/lib/invoice-template-ast/schema.test.ts::returns structured validation errors for invalid AST payloads Verification: - \ WARN  Unsupported engine: wanted: {"node":">=20 <25"} (current: {"node":"v25.5.0","pnpm":"9.15.9"}) RUN v3.2.4 /Users/roberisaacs/alga-psa.worktrees/codex/feature-invoice-designer Running tests with seed "1770925992649" Environment file path: /Users/roberisaacs/alga-psa.worktrees/codex/feature-invoice-designer/.env.localtest ✓ packages/billing/src/components/invoice-designer/state/designerStore.layoutMode.test.ts (2 tests) 8ms 15 MB heap used ✓ server/src/test/unit/DocumentationService.test.ts (4 tests) 1ms 41 MB heap used ✓ packages/billing/src/lib/invoice-renderer/layout-renderer.test.ts (2 tests) 1ms 60 MB heap used stdout | server/src/test/integration/billingInvoiceTiming.integration.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/billingInvoiceTiming.integration.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/billingInvoiceTiming.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/billingInvoiceTiming.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/billingInvoiceTiming.integration.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/billingInvoiceTiming.integration.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/billingInvoiceTiming.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/billingInvoiceTiming.integration.test.ts Retrieved secret 'db_password_server' from configured provider. ✓ packages/billing/src/lib/invoice-template-ast/strategies.test.ts (2 tests) 1ms 254 MB heap used stdout | server/src/test/integration/workflowRuntimeV2.redaction.integration.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/workflowRuntimeV2.redaction.integration.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/workflowRuntimeV2.redaction.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/workflowRuntimeV2.redaction.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/workflowRuntimeV2.redaction.integration.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/workflowRuntimeV2.redaction.integration.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/workflowRuntimeV2.redaction.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/workflowRuntimeV2.redaction.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/accounting/externalTaxImport.integration.test.ts > External Tax Import Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/accounting/externalTaxImport.integration.test.ts > External Tax Import CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/accounting/externalTaxImport.integration.test.ts > External Tax Import CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/accounting/externalTaxImport.integration.test.ts > External Tax Import Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/accounting/externalTaxImport.integration.test.ts > External Tax Import CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/accounting/externalTaxImport.integration.test.ts > External Tax Import Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/integration/accounting/externalTaxImport.integration.test.ts (14 tests | 14 skipped) 20ms 260 MB heap used ↓ External Tax Import > importing tax from external accounting system > should update invoice charges with tax amounts from QuickBooks ↓ External Tax Import > importing tax from external accounting system > should change invoice tax_source from pending_external to external ↓ External Tax Import > importing tax from external accounting system > should create audit record in external_tax_imports table ↓ External Tax Import > importing tax from external accounting system > should update invoice total_amount to include imported tax ↓ External Tax Import > tax allocation across charges > should apply per-line tax amounts from external system ↓ External Tax Import > tax allocation across charges > should handle mix of taxable and non-taxable items ↓ External Tax Import > tax allocation across charges > should handle different tax rates across items ↓ External Tax Import > tax allocation across charges > should distribute proportionally when line matching fails ↓ External Tax Import > tax allocation across charges > should match by charge ID even when external lines are returned out of order ↓ External Tax Import > internal tax calculation is skipped for external delegation > should set tax to zero when invoice has pending_external tax source ↓ External Tax Import > automatic tax import after export > should automatically import tax after exporting invoice with tax delegation ↓ External Tax Import > error handling > should fail if invoice is not pending_external ↓ External Tax Import > error handling > should fail if invoice has no external mapping ↓ External Tax Import > error handling > should fail if external system returns error stdout | server/src/test/integration/workflowRuntimeV2.eventTrigger.integration.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/workflowRuntimeV2.eventTrigger.integration.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/workflowRuntimeV2.eventTrigger.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/workflowRuntimeV2.eventTrigger.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/workflowRuntimeV2.eventTrigger.integration.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/workflowRuntimeV2.eventTrigger.integration.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/workflowRuntimeV2.eventTrigger.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/workflowRuntimeV2.eventTrigger.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/surveyEmailTemplates.integration.test.ts > Survey email templates Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/surveyEmailTemplates.integration.test.ts > Survey email templates CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/surveyEmailTemplates.integration.test.ts > Survey email templates CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/surveyEmailTemplates.integration.test.ts > Survey email templates Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/surveyEmailTemplates.integration.test.ts > Survey email templates CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/surveyEmailTemplates.integration.test.ts > Survey email templates Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/integration/surveyEmailTemplates.integration.test.ts (2 tests | 2 skipped) 1ms 269 MB heap used ↓ Survey email templates > registers system templates for each supported locale ↓ Survey email templates > renders locale-specific content and falls back to English stdout | server/src/test/integration/workflowPayloadContractInference.integration.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/workflowPayloadContractInference.integration.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/workflowPayloadContractInference.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/workflowPayloadContractInference.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/workflowPayloadContractInference.integration.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/workflowPayloadContractInference.integration.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/workflowPayloadContractInference.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/workflowPayloadContractInference.integration.test.ts Retrieved secret 'db_password_server' from configured provider. ✓ packages/billing/src/components/invoice-designer/preview/previewSessionState.test.ts (6 tests) 1ms 277 MB heap used stdout | packages/billing/src/actions/renderTemplateOnServer.ast.integration.test.ts > renderTemplateOnServer AST integration > renders template HTML/CSS from canonical AST payload [Server Action] Successfully rendered template: tpl-1 ✓ packages/billing/src/actions/renderTemplateOnServer.ast.integration.test.ts (2 tests) 5ms 287 MB heap used stdout | server/src/test/unit/billing/billingEngine.prorationExclusive.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/billing/billingEngine.prorationExclusive.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/billing/billingEngine.prorationExclusive.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/billingEngine.prorationExclusive.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/billing/billingEngine.prorationExclusive.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/billing/billingEngine.prorationExclusive.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/billing/billingEngine.prorationExclusive.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/billingEngine.prorationExclusive.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/ticketPermissions.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/ticketPermissions.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/ticketPermissions.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/ticketPermissions.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/ticketPermissions.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/ticketPermissions.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/ticketPermissions.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/ticketPermissions.test.ts Retrieved secret 'db_password_server' from configured provider. ✓ server/src/test/unit/extensions/uiHooks.test.ts (2 tests) 0ms 312 MB heap used ✓ ee/server/src/__tests__/unit/schedulerHostApi.unit.test.ts (72 tests) 9ms 272 MB heap used ❯ server/src/lib/extensions/ui/iframeBridge.test.ts (5 tests | 5 failed) 1ms 279 MB heap used × bootstrapIframe (host bridge) > applies sandbox="allow-scripts" by default when none provided 0ms → window is not defined × bootstrapIframe (host bridge) > throws when allowedOrigin mismatches iframe src origin and RUNNER_PUBLIC_BASE is absolute 0ms → window is not defined × bootstrapIframe (host bridge) > sends bootstrap message with envelope version after load 0ms → window is not defined × bootstrapIframe (host bridge) > adjusts iframe height on resize messages with clamping 0ms → window is not defined × bootstrapIframe (host bridge) > validates contentHash format 0ms → window is not defined stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts > Tax Rate Changes Mid-Billing Period CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts > Tax Rate Changes Mid-Billing Period Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts > Tax Rate Changes Mid-Billing Period CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts > Tax Rate Changes Mid-Billing Period Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts (1 test | 1 skipped) 2ms 285 MB heap used ↓ Tax Rate Changes Mid-Billing Period > should apply correct tax rates based on charge dates stdout | server/src/test/unit/accounting/xeroClientService.spec.ts > XeroClientService – REST usage > refreshes OAuth tokens when expired Successfully wrote tenant secret: /Users/roberisaacs/alga-psa.worktrees/codex/feature-invoice-designer/secrets/tenants/tenant-123/xero_credentials stdout | server/src/test/unit/accounting/xeroClientService.spec.ts > XeroClientService – REST usage > retries after 401 by refreshing token once and logs tenant metadata Successfully wrote tenant secret: /Users/roberisaacs/alga-psa.worktrees/codex/feature-invoice-designer/secrets/tenants/tenant-123/xero_credentials ❯ server/src/test/unit/accounting/xeroClientService.spec.ts (8 tests | 1 failed) 5ms 306 MB heap used ✓ XeroClientService – REST usage > POST /Invoices payload matches spec requirements 0ms ✓ XeroClientService – REST usage > normalizes validation errors returned from POST /Invoices 0ms ✓ XeroClientService – REST usage > handles empty payload array without issuing network request 0ms ✓ XeroClientService – REST usage > sets expected headers for authenticated requests 0ms ✓ XeroClientService – REST usage > refreshes OAuth tokens when expired 1ms ✓ XeroClientService – REST usage > retrieves accounts, items, tax rates, and tracking categories with normalized structures 0ms × XeroClientService – REST usage > retries after 401 by refreshing token once and logs tenant metadata 1ms → expected "spy" to be called 1 times, but got 0 times ✓ XeroClientService – REST usage > allows re-export after validation error once mappings are corrected 0ms ✓ ee/server/src/__tests__/unit/tenant-creation.test.ts (4 tests) 0ms 310 MB heap used ✓ server/src/lib/auth/sessionCookies.test.ts (2 tests) 6ms 313 MB heap used ✓ server/src/test/unit/security/managerScopeRegression.test.ts (1 test) 1ms 314 MB heap used ✓ server/src/test/unit/scheduling/bundledTicketsWorkItemPickerBehavior.test.ts (2 tests) 1ms 316 MB heap used stdout | server/src/lib/email/delayedEmailQueue.redisRecovery.test.ts > DelayedEmailQueue Redis recovery > recreates the Redis client after a zRangeByScore timeout [DelayedEmailQueue] Processing loop started { intervalMs: 60000 } [DelayedEmailQueue] Initialized successfully { maxRetries: 5, baseDelayMs: 60000, maxDelayMs: 900000, checkIntervalMs: 60000 } stdout | server/src/lib/email/delayedEmailQueue.redisRecovery.test.ts > DelayedEmailQueue Redis recovery > recreates the Redis client after a zRangeByScore timeout [DelayedEmailQueue] Shutting down... [DelayedEmailQueue] Shutdown complete ✓ server/src/lib/email/delayedEmailQueue.redisRecovery.test.ts (1 test) 2ms 318 MB heap used ✓ packages/types/src/interfaces/invoice-template-ast-contract.typecheck.test.ts (1 test) 0ms 299 MB heap used ❯ server/src/test/integration/billing/invoiceStatusManagement.integration.test.ts (10 tests | 10 skipped) 1ms 100 MB heap used ↓ Invoice Status Management Integration > Credit Application Status Transitions > should set status to partially_applied when partial credit is applied ↓ Invoice Status Management Integration > Credit Application Status Transitions > should set status to paid when full credit is applied ↓ Invoice Status Management Integration > Credit Application Status Transitions > should accumulate multiple partial credits and update status accordingly ↓ Invoice Status Management Integration > Payment Recording Status Transitions > should set status to partially_applied when partial payment is recorded ↓ Invoice Status Management Integration > Payment Recording Status Transitions > should set status to paid when full payment is recorded ↓ Invoice Status Management Integration > Combined Payment and Credit Scenarios > should correctly calculate status with both payments and credits ↓ Invoice Status Management Integration > Refund Handling and Status Reversals > should transition from paid to partially_applied when partial refund is recorded ↓ Invoice Status Management Integration > Refund Handling and Status Reversals > should transition from paid to sent when full refund is recorded ↓ Invoice Status Management Integration > Status Transition Validation > should not allow payment on cancelled invoice ↓ Invoice Status Management Integration > Status Transition Validation > should not allow credit on draft invoice ❯ server/src/test/unit/scheduling/actionGuardWiring.test.ts (7 tests | 4 failed) 2ms 103 MB heap used ✓ delegation guard wiring (static) > fetchTimePeriods enforces delegation via assertCanActOnBehalf 0ms ✓ delegation guard wiring (static) > fetchOrCreateTimeSheet enforces delegation via assertCanActOnBehalf 0ms × delegation guard wiring (static) > fetchTimeSheet enforces owner-or-delegate access via assertCanActOnBehalf 1ms → expected '\'use server\'\n\nimport {\n ITimeEn…' to match /export const fetchTimeSheet[\\s\\S]*a…/ × delegation guard wiring (static) > fetchTimeEntriesForTimeSheet enforces owner-or-delegate access via assertCanActOnBehalf 0ms → expected '\'use server\'\n\nimport {\n ITimeEn…' to match /export const fetchTimeEntriesForTimeS…/ × delegation guard wiring (static) > fetchWorkItemsForTimeSheet enforces owner-or-delegate access via assertCanActOnBehalf 0ms → expected '\'use server\'\n\nimport { Knex } fro…' to match /export const fetchWorkItemsForTimeShe…/ ✓ delegation guard wiring (static) > reopen/reverse approval is blocked when a timesheet contains invoiced entries 0ms × delegation guard wiring (static) > reopen/reverse approval transitions timesheet and entries to CHANGES_REQUESTED 0ms → expected '\'use server\'\n\nimport {\n ITimeEn…' to match /reverseTimeSheetApproval[\\s\\S]*appr…/ ❯ server/src/test/unit/scheduling/approvalBehavior.test.ts (2 tests | 2 failed) 1ms 108 MB heap used × timesheet approval behavior (static) > approveTimeSheet enforces delegation and marks timesheet APPROVED 0ms → expected '\'use server\'\n\nimport {\n ITimeEn…' to match /export const approveTimeSheet[\\s\\S]…/ × timesheet approval behavior (static) > bulkApproveTimeSheets enforces manager scope via assertCanActOnBehalf 0ms → expected '\'use server\'\n\nimport {\n ITimeEn…' to match /export const bulkApproveTimeSheets[\\…/ ❯ server/src/test/integration/citusTenantFilterEmailProviders.integration.test.ts (2 tests | 2 failed) 2ms 116 MB heap used × Citus safety: tenant-scoped updates on distributed tables > scopes email_providers updates by tenant in Microsoft webhook route 2ms → expected 'export { GET, POST } from \'@alga-psa…' to contain '.where({ id: row.id, tenant: row.tena…' × Citus safety: tenant-scoped updates on distributed tables > scopes email_providers updates by tenant in Google webhook route 1ms → expected 'export { POST } from \'@alga-psa/inte…' to contain '.where({ id: provider.id, tenant: pro…' stdout | server/src/test/integration/accounting/mappingPermissions.integration.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/accounting/mappingPermissions.integration.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/accounting/mappingPermissions.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/accounting/mappingPermissions.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/accounting/mappingPermissions.integration.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/accounting/mappingPermissions.integration.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/accounting/mappingPermissions.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/accounting/mappingPermissions.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | eslint-plugin-custom-rules/migration-filename.test.js All tests passed! ✓ eslint-plugin-custom-rules/migration-filename.test.js (14 tests) 17ms 144 MB heap used ✓ server/src/test/unit/workflowsEntryTypingGuard.unit.test.ts (2 tests) 1ms 146 MB heap used ✓ packages/billing/src/lib/invoice-template-ast/standardTemplates.test.ts (2 tests) 0ms 152 MB heap used stdout | server/src/test/infrastructure/billing/credits/creditExpirationEffects.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/infrastructure/billing/credits/creditExpirationEffects.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/infrastructure/billing/credits/creditExpirationEffects.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/infrastructure/billing/credits/creditExpirationEffects.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/infrastructure/billing/credits/creditExpirationEffects.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/infrastructure/billing/credits/creditExpirationEffects.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/infrastructure/billing/credits/creditExpirationEffects.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/infrastructure/billing/credits/creditExpirationEffects.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/accounting/batchLifecycle.integration.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/accounting/batchLifecycle.integration.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/accounting/batchLifecycle.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/accounting/batchLifecycle.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/accounting/batchLifecycle.integration.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/accounting/batchLifecycle.integration.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/accounting/batchLifecycle.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/accounting/batchLifecycle.integration.test.ts Retrieved secret 'db_password_server' from configured provider. ✓ server/src/test/unit/scheduling/deleteTimeEntryBehavior.test.ts (1 test) 1ms 151 MB heap used ✓ tools/nx-tests/nxAffected.test.ts (2 tests) 3861ms 154 MB heap used ✓ nx affected > identifies affected projects from a file list 3087ms ✓ nx affected > includes @alga-psa/clients when client code changes 774ms ✓ packages/clients/src/lib/durationHelpers.test.ts (7 tests) 0ms 156 MB heap used ✓ sdk/samples/component/scheduler-demo/tests/handler.test.ts (6 tests) 1ms 159 MB heap used ✓ tools/nx-tests/nxWorkspace.test.ts (3 tests) 16106ms 162 MB heap used ✓ nx workspace > can generate an nx graph html file 15400ms ✓ nx workspace > runs the alga-module generator in dry-run mode 413ms ✓ packages/core/src/lib/events/publisher.test.ts (1 test) 5ms 126 MB heap used ✓ server/src/test/unit/email/emailLoggingFailure.test.ts (1 test) 22ms 126 MB heap used ❯ server/src/test/unit/clientFormValidation.test.ts (20 tests | 12 failed) 9ms 130 MB heap used ✓ Client Form Validation > validateClientName > should accept valid client names 1ms × Client Form Validation > validateClientName > should reject invalid client names 0ms → expected null to be 'Client name must contain letters and …' // Object.is equality × Client Form Validation > validateWebsiteUrl > should accept valid URLs 0ms → expected 'Please enter a real business website …' to be null × Client Form Validation > validateWebsiteUrl > should reject invalid URLs 1ms → expected 'Please enter a domain name, not an IP…' to be 'Please enter a valid website URL (e.g…' // Object.is equality × Client Form Validation > validateEmailAddress > should accept valid email addresses 0ms → expected 'Please enter a valid business email a…' to be null × Client Form Validation > validateEmailAddress > should reject invalid email addresses 0ms → expected 'Please enter a valid email address' to be 'Please enter a valid business email a…' // Object.is equality ✓ Client Form Validation > validatePhoneNumber > should accept valid phone numbers 1ms × Client Form Validation > validatePhoneNumber > should reject invalid phone numbers 1ms → expected null to be 'Please enter a valid phone number' // Object.is equality ✓ Client Form Validation > validatePostalCode > should accept valid US ZIP codes 0ms × Client Form Validation > validatePostalCode > should reject invalid US ZIP codes 0ms → expected 'Please enter a valid ZIP code (e.g., …' to be 'Please enter a valid US ZIP code (e.g…' // Object.is equality × Client Form Validation > validatePostalCode > should validate Canadian postal codes 0ms → expected 'Please enter a valid Canadian postal …' to be 'Please enter a valid Canadian postal …' // Object.is equality ✓ Client Form Validation > validateCityName > should accept valid city names 0ms × Client Form Validation > validateCityName > should reject invalid city names 0ms → expected 'City name must contain letters' to be 'City name must be at least 2 characte…' // Object.is equality ✓ Client Form Validation > validateAddress > should accept valid addresses 0ms × Client Form Validation > validateAddress > should reject invalid addresses 0ms → expected 'Address must contain letters' to be 'Address must be at least 5 characters…' // Object.is equality ✓ Client Form Validation > validateContactName > should accept valid contact names 0ms × Client Form Validation > validateContactName > should reject invalid contact names 0ms → expected 'Contact name must contain meaningful …' to be 'Contact name cannot contain emojis' // Object.is equality ✓ Client Form Validation > validateClientForm > should validate a complete form successfully 0ms × Client Form Validation > validateClientForm > should return errors for invalid form data 3ms → the given combination of arguments (undefined and string) is invalid for this assertion. You can use an array, a map, an object, a set, a string, or a weakset instead of a string ✓ Client Form Validation > validateClientForm > should allow empty optional fields 0ms ✓ server/src/test/unit/validation/timeEntrySchemaAuditFields.test.ts (2 tests) 1ms 131 MB heap used stdout | server/src/test/integration/pricingScheduleIntegration.test.ts > Pricing Schedule Integration Tests Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/pricingScheduleIntegration.test.ts > Pricing Schedule Integration Tests CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/pricingScheduleIntegration.test.ts > Pricing Schedule Integration Tests CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/pricingScheduleIntegration.test.ts > Pricing Schedule Integration Tests Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/pricingScheduleIntegration.test.ts > Pricing Schedule Integration Tests CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/pricingScheduleIntegration.test.ts > Pricing Schedule Integration Tests Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/integration/pricingScheduleIntegration.test.ts (10 tests | 10 skipped) 2ms 132 MB heap used ↓ Pricing Schedule Integration Tests > Create and Persist Pricing Schedules > should create a pricing schedule and persist to database ↓ Pricing Schedule Integration Tests > Create and Persist Pricing Schedules > should retrieve active pricing schedule for a billing period ↓ Pricing Schedule Integration Tests > Create and Persist Pricing Schedules > should handle multiple schedules and return the most recent effective schedule ↓ Pricing Schedule Integration Tests > Pricing Schedule Boundaries > should correctly filter schedules across billing period boundaries ↓ Pricing Schedule Integration Tests > Pricing Schedule Boundaries > should treat schedules with null end_date as ongoing ↓ Pricing Schedule Integration Tests > Pricing Schedule Updates and Deletes > should update an existing pricing schedule ↓ Pricing Schedule Integration Tests > Pricing Schedule Updates and Deletes > should delete a pricing schedule ↓ Pricing Schedule Integration Tests > Pricing Schedule Updates and Deletes > should mark a schedule as expired when setting end_date ↓ Pricing Schedule Integration Tests > Pricing Schedule for No Rates > should allow schedules without custom_rate and treat them as null overrides ↓ Pricing Schedule Integration Tests > Pricing Schedule for No Rates > should return no schedule when contract has none defined ❯ ee/temporal-workflows/src/activities/__tests__/portal-domain-reconcile.integration.test.ts (2 tests | 2 failed) 1ms 134 MB heap used × applyPortalDomainResources > routes virtual service traffic to the app once certificate succeeds 0ms → Missing "./admin.js" specifier in "@alga-psa/db" package × applyPortalDomainResources > creates new manifests and prunes legacy virtual services when the domain changes 1ms → Missing "./admin.js" specifier in "@alga-psa/db" package ✓ packages/billing/tests/draftContractsTable.test.tsx (30 tests) 1407ms 177 MB heap used ✓ packages/projects/src/components/__tests__/TaskQuickAddPrefill.test.tsx (1 test) 1ms 181 MB heap used ✓ packages/billing/src/components/billing-dashboard/InvoiceTemplateEditor.previewWorkspace.test.tsx (11 tests) 76ms 190 MB heap used stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx Retrieved secret 'db_password_server' from configured provider. stdout | ee/server/src/__tests__/integration/extensionProxyFlow.test.ts > Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should forward "apiproxy" message to Gateway and return response to Client iframeBridge: received message { type: 'apiproxy', origin: 'http://localhost:3000' } iframeBridge: handling apiproxy { requestId: 'req-123', route: '/tickets' } iframeBridge: posting apiproxy_response { requestId: 'req-123', targetOrigin: '*' } stdout | ee/server/src/__tests__/integration/extensionProxyFlow.test.ts > Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should handle Gateway errors and return error message to Client iframeBridge: received message { type: 'apiproxy', origin: 'http://localhost:3000' } iframeBridge: handling apiproxy { requestId: 'req-error', route: '/error-route' } stdout | ee/server/src/__tests__/integration/extensionProxyFlow.test.ts > Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should handle Gateway errors and return error message to Client iframeBridge: fetch completed { status: 500, ok: false, url: '/api/ext-proxy/test-extension-id/error-route' } stdout | ee/server/src/__tests__/integration/extensionProxyFlow.test.ts > Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should handle Gateway errors and return error message to Client iframeBridge: posting apiproxy_response { requestId: 'req-error', targetOrigin: '*' } ❯ ee/server/src/__tests__/integration/extensionProxyFlow.test.ts (4 tests | 3 failed) 142ms 198 MB heap used × Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should forward "apiproxy" message to Gateway and return response to Client 60ms → expected "fetch" to be called with arguments: [ StringContaining{…}, …(1) ] Number of calls: 0 ✓ Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should handle Gateway errors and return error message to Client 55ms × Extension Proxy Flow Integration > Gateway Handler (Host -> Runner) > should forward request to RunnerBackend and propagate response headers/body 25ms → Failed to resolve import "@alga-psa/db/models/UserSession" from "packages/auth/src/lib/nextAuthOptions.ts". Does the file exist? × Extension Proxy Flow Integration > Gateway Handler (Host -> Runner) > should handle Runner errors gracefully 2ms → Failed to resolve import "@alga-psa/db/models/UserSession" from "packages/auth/src/lib/nextAuthOptions.ts". Does the file exist? ✓ server/src/test/unit/components/AssetNotesPanel.test.tsx (1 test) 3ms 202 MB heap used ✓ packages/billing/tests/contractsActivationFlow.test.tsx (2 tests) 159ms 228 MB heap used ❯ server/src/test/unit/tickets/TicketEmailNotifications.ui.test.tsx (7 tests | 2 failed) 111ms 174 MB heap used ✓ TicketEmailNotifications > renders without errors 1ms ✓ TicketEmailNotifications > is collapsed by default and expands on click 12ms ✓ TicketEmailNotifications > shows loading state while fetching 18ms ✓ TicketEmailNotifications > displays timestamp, recipient, subject, and status for each log entry 12ms ✓ TicketEmailNotifications > shows error message for failed notifications 13ms × TicketEmailNotifications > shows maximum 20 entries initially with Load more when more exist 18ms → Found multiple elements with the role "table" Here are the matching elements: Ignored nodes: comments, script, style       Client        Contract Template        Contract Name        Start Date        End Date        Status        Actions            Acme Co       —       Draft Alpha       —       —        Active          Open menu              Ignored nodes: comments, script, style     Jan 01, 2026, 7:00 AM   user0@example.com   S0      sent     —     Jan 01, 2026, 7:00 AM   user1@example.com   S1      sent     —     Jan 01, 2026, 7:00 AM   user2@example.com   S2      sent     —     Jan 01, 2026, 7:00 AM   user3@example.com   S3      sent     —     Jan 01, 2026, 7:00 AM   user4@example.com   S4      sent     —     Jan 01, 2026, 7:00 AM   user5@example.com   S5      sent     —     Jan 01, 2026, 7:00 AM   user6@example.com   S6      sent     —     Jan 01, 2026, 7:00 AM   user7@example.com   S7      sent     —     Jan 01, 2026, 7:00 AM   user8@example.com   S8      sent     —     Jan 01, 2026, 7:00 AM   user9@example.com   S9      sent     —     Jan 01, 2026, 7:00 AM   user10@example.com   S10      sent     —     Jan 01, 2026, 7:00 AM   user11@example.com   S11      sent     —     Jan 01, 2026, 7:00 AM   user12@example.com   S12      sent     —     Jan 01, 2026, 7:00 AM   user13@example.com   S13      sent     —     Jan 01, 2026, 7:00 AM   user14@example.com   S14      sent     —     Jan 01, 2026, 7:00 AM   user15@example.com   S15      sent     —     Jan 01, 2026, 7:00 AM   user16@example.com   S16      sent     —     Jan 01, 2026, 7:00 AM   user17@example.com   S17      sent     —     Jan 01, 2026, 7:00 AM   user18@example.com   S18      sent     —     Jan 01, 2026, 7:00 AM   user19@example.com   S19      sent     —     (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
     Contracts  
 
 
 Templates | Client Contracts | Drafts 
 
         
 
             Create Contract         ... × TicketEmailNotifications > Load more fetches additional entries 37ms → Found multiple elements with the role "table" Here are the matching elements: Ignored nodes: comments, script, style       Client        Contract Template        Contract Name        Start Date        End Date        Status        Actions            Acme Co       —       Draft Alpha       —       —        Active          Open menu              Ignored nodes: comments, script, style     Jan 01, 2026, 7:00 AM   user0@example.com   S0      sent     —     Jan 01, 2026, 7:00 AM   user1@example.com   S1      sent     —     Jan 01, 2026, 7:00 AM   user2@example.com   S2      sent     —     Jan 01, 2026, 7:00 AM   user3@example.com   S3      sent     —     Jan 01, 2026, 7:00 AM   user4@example.com   S4      sent     —     Jan 01, 2026, 7:00 AM   user5@example.com   S5      sent     —     Jan 01, 2026, 7:00 AM   user6@example.com   S6      sent     —     Jan 01, 2026, 7:00 AM   user7@example.com   S7      sent     —     Jan 01, 2026, 7:00 AM   user8@example.com   S8      sent     —     Jan 01, 2026, 7:00 AM   user9@example.com   S9      sent     —     Jan 01, 2026, 7:00 AM   user10@example.com   S10      sent     —     Jan 01, 2026, 7:00 AM   user11@example.com   S11      sent     —     Jan 01, 2026, 7:00 AM   user12@example.com   S12      sent     —     Jan 01, 2026, 7:00 AM   user13@example.com   S13      sent     —     Jan 01, 2026, 7:00 AM   user14@example.com   S14      sent     —     Jan 01, 2026, 7:00 AM   user15@example.com   S15      sent     —     Jan 01, 2026, 7:00 AM   user16@example.com   S16      sent     —     Jan 01, 2026, 7:00 AM   user17@example.com   S17      sent     —     Jan 01, 2026, 7:00 AM   user18@example.com   S18      sent     —     Jan 01, 2026, 7:00 AM   user19@example.com   S19      sent     —     Jan 01, 2026, 7:00 AM   user20@example.com   S20      sent     —     Jan 01, 2026, 7:00 AM   user21@example.com   S21      sent     —     Jan 01, 2026, 7:00 AM   user22@example.com   S22      sent     —     Jan 01, 2026, 7:00 AM   user23@example.com   S23      sent     —     Jan 01, 2026, 7:00 AM   user24@example.com   S24      sent     —     (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
     Contracts  
 
 
 Templates | Client Contracts | Drafts 
 
         
 
             Create Contract         ... ✓ packages/billing/src/components/invoice-designer/DesignerShell.constraints.test.tsx (23 tests) 479ms 232 MB heap used stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx Retrieved secret 'db_password_server' from configured provider. stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx Retrieved secret 'postgres_password' from configured provider. stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx Retrieved secret 'db_password_server' from configured provider. ❯ packages/billing/tests/contractWizardResume.test.tsx (14 tests | 14 failed) 47ms 246 MB heap used × ContractWizard resume behavior > starts at Step 1 (Contract Basics) when opened (T033) 2ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 1 shows pre-populated client selection from draft (T034) 2ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 1 shows pre-populated contract name from draft (T035) 2ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 1 shows pre-populated dates from draft (T036) 2ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 2 (Fixed Fee) shows pre-populated services from draft (T037) 2ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 3 (Products) shows pre-populated products from draft (T038) 2ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 4 (Hourly) shows pre-populated hourly services from draft (T039) 16ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 5 (Usage) shows pre-populated usage services from draft (T040) 3ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 6 (Review) shows complete draft data for review (T041) 2ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > clicking Save Draft in resumed wizard updates existing draft (T042) 2ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > save draft does not create a duplicate contract (T043) 2ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > save draft preserves the original contract_id (T044) 3ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > completing resumed wizard sets contract status to 'active' (T045) 3ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > completing resumed wizard sets is_active to true (T046) 3ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: ✓ server/src/test/unit/email/EmailLogsClient.ui.test.tsx (6 tests) 949ms 248 MB heap used ✓ EmailLogsClient > updates results when date range filter changes 306ms ✓ EmailLogsClient > updates results when recipient search changes 306ms ✓ EmailLogsClient > updates results when ticket filter changes 306ms ✓ packages/billing/src/components/billing-dashboard/InvoiceTemplateEditor.authoritativeFlow.test.tsx (2 tests) 223ms 183 MB heap used ❯ server/src/test/unit/components/ExperimentalFeaturesSettings.test.tsx (9 tests | 6 failed) 3060ms 189 MB heap used × ExperimentalFeaturesSettings > shows 'AI Assistant' name and description 1005ms → Found multiple elements with the text: AI Assistant Here are the matching elements: Ignored nodes: comments, script, style  AI Assistant  Ignored nodes: comments, script, style  AI Assistant  Ignored nodes: comments, script, style  AI Assistant  Ignored nodes: comments, script, style  AI Assistant  Ignored nodes: comments, script, style  AI Assistant  Ignored nodes: comments, script, style  AI Assistant  Ignored nodes: comments, script, style  AI Assistant  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
    Experimental Features   Enable or disable experimental features for your tenant. 

 
  svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 border-l-4 border-l-warning border-y-0 border-r-0 text-[rgb(var(--color-text-800))] [&>svg]:text-warning bg-warning/10" role="alert" >       Experimental   Experimental features may change or be removed without notice.      AI Assistant   Enable AI-powered Quick Ask and Chat sidebar.            Workflow Automation   Enable experimental workflow automation features in Automation Hub.           Save      ... Ignored nodes: comments, script, style    
    Experimental Features   Enable or disable experimental features for your tenant. 

 
  svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 border-l-4 border-l-warning border-y-0 border-r-0 text-[rgb(var(--color-text-800))] [&>svg]:text-warning bg-warning/10" role="alert" >       Experimental   Experimental features may change or be removed without notice.      AI Assistant   Enable AI-powered Quick Ask and Chat sidebar.            Workflow Automation   Enable experimental workflow automation features in Automation Hub.           Save      ... × ExperimentalFeaturesSettings > defaults AI Assistant toggle to off 4ms → expected 'true' to be 'false' // Object.is equality × ExperimentalFeaturesSettings > renders experimental features warning banner 1006ms → Found multiple elements with the text: Experimental Here are the matching elements: Ignored nodes: comments, script, style  Experimental  Ignored nodes: comments, script, style  Experimental  Ignored nodes: comments, script, style  Experimental  Ignored nodes: comments, script, style  Experimental  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
    Experimental Features   Enable or disable experimental features for your tenant. 

 
  svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 border-l-4 border-l-warning border-y-0 border-r-0 text-[rgb(var(--color-text-800))] [&>svg]:text-warning bg-warning/10" role="alert" >       Experimental   Experimental features may change or be removed without notice.      AI Assistant   Enable AI-powered Quick Ask and Chat sidebar.            Workflow Automation   Enable experimental workflow automation features in Automation Hub.           Save      
    
    Experimental Features   Enable or disable experimental features for your tenant. 

 
  svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 border-l-4 border-l-warning border-y-0 border-r-0 text-[rgb(var(--color-text-800))] [&>svg]:text-warning bg-warning/10" role="alert" >       Experimental   Experimental features may change or be removed without notice. 
     AI Assistant   Enable AI-powered Quick Ask and Chat sidebar.            Workflow Automation   Enable experimental workflow automation features in Automation Hub.           Save      
  calls updateExperimentalFeatures() with current toggle states on save 12ms × ExperimentalFeaturesSettings > shows success feedback after saving 1006ms → Found multiple elements with the role "button" and name "Save" Here are the matching elements: Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
    Experimental Features   Enable or disable experimental features for your tenant. 

 
  svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 border-l-4 border-l-warning border-y-0 border-r-0 text-[rgb(var(--color-text-800))] [&>svg]:text-warning bg-warning/10" role="alert" >       Experimental   Experimental features may change or be removed without notice. 
     AI Assistant   Enable AI-powered Quick Ask and Chat sidebar.            Workflow Automation   Enable experimental workflow automation features in Automation Hub.           Save      
    
    Experimental Features   Enable or disable experimental features for your tenant. 

 
  svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 border-l-4 border-l-warning border-y-0 border-r-0 text-[rgb(var(--color-text-800))] [&>svg]:text-warning bg-warning/10" role="alert" >       Experimental   Experimental features may change or be removed without notice. 
     AI Assistant   Enable AI-powered Quick Ask and Chat sidebar.            Workflow Automation   Enable experimental workflow automation features in Automation Hub.           Save      
  updates local state when toggled 7ms ✓ ExperimentalFeaturesSettings > loads current settings on mount 3ms × ExperimentalFeaturesSettings > renders list of features with toggles 10ms → expected [ , …(11) ] to have a length of 2 but got 12 × ExperimentalFeaturesSettings > disables AI Assistant toggle when not allowed 6ms → expected 'true' to be 'false' // Object.is equality ✓ packages/billing/src/components/invoice-designer/canvas/DesignCanvas.constraintHighlights.test.tsx (2 tests) 3ms 196 MB heap used ✓ packages/billing/src/components/invoice-designer/DesignerVisualWorkspace.test.tsx (28 tests) 1636ms 236 MB heap used ✓ DesignerVisualWorkspace > calls paginated invoice search with status=all and query filters 319ms ✓ DesignerVisualWorkspace > renders loading, empty, and error states for existing invoice list 623ms ✓ server/src/test/unit/RightSidebar.streaming.test.tsx (1 test) 430ms 246 MB heap used ✓ RightSidebar (streaming) > renders streaming Chat and posts to the streaming completions endpoint 430ms ✓ packages/billing/src/components/invoice-designer/canvas/DesignCanvas.previewMode.test.tsx (15 tests) 37ms 285 MB heap used ✓ packages/projects/tests/projectInfoDrawer.test.tsx (1 test) 20ms 253 MB heap used stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.poBanner.ui.test.tsx Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.poBanner.ui.test.tsx CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.poBanner.ui.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.poBanner.ui.test.tsx Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.poBanner.ui.test.tsx CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.poBanner.ui.test.tsx Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.poBanner.ui.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.poBanner.ui.test.tsx Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/unit/Chat.streamingIncrementalState.test.tsx (9 tests | 9 failed) 45ms 272 MB heap used × EE Chat (streaming state) > updates the in-progress assistant message as tokens arrive 4ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
    Experimental Features   Enable or disable experimental features for your tenant. 

 
  svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 border-l-4 border-l-warning border-y-0 border-r-0 text-[rgb(var(--color-text-800))] [&>svg]:text-warning bg-warning/10" role="alert" >       Experimental   Experimental features may change or be removed without notice. 
     AI Assistant   Enable AI-powered Quick Ask and Chat sidebar.            Workflow Automation   Enable experimental workflow automation features in Automation Hub.           Save      ... × EE Chat (streaming state) > aborts the streaming request when Stop is clicked 4ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
    Experimental Features   Enable or disable experimental features for your tenant. 

 
  svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 border-l-4 border-l-warning border-y-0 border-r-0 text-[rgb(var(--color-text-800))] [&>svg]:text-warning bg-warning/10" role="alert" >       Experimental   Experimental features may change or be removed without notice.      AI Assistant   Enable AI-powered Quick Ask and Chat sidebar.            Workflow Automation   Enable experimental workflow automation features in Automation Hub.           Save      ... × EE Chat (streaming state) > stops updating token display and ends generation state after Stop 4ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
    Experimental Features   Enable or disable experimental features for your tenant. 

 
  svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 border-l-4 border-l-warning border-y-0 border-r-0 text-[rgb(var(--color-text-800))] [&>svg]:text-warning bg-warning/10" role="alert" >       Experimental   Experimental features may change or be removed without notice.      AI Assistant   Enable AI-powered Quick Ask and Chat sidebar.            Workflow Automation   Enable experimental workflow automation features in Automation Hub.           Save      ... × EE Chat (streaming state) > shows a streaming cursor while receiving tokens 6ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
    Experimental Features   Enable or disable experimental features for your tenant. 

 
  svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 border-l-4 border-l-warning border-y-0 border-r-0 text-[rgb(var(--color-text-800))] [&>svg]:text-warning bg-warning/10" role="alert" >       Experimental   Experimental features may change or be removed without notice.      AI Assistant   Enable AI-powered Quick Ask and Chat sidebar.            Workflow Automation   Enable experimental workflow automation features in Automation Hub.           Save      ... × EE Chat (streaming state) > removes the streaming cursor when done is received 5ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
    Experimental Features   Enable or disable experimental features for your tenant. 

 
  svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 border-l-4 border-l-warning border-y-0 border-r-0 text-[rgb(var(--color-text-800))] [&>svg]:text-warning bg-warning/10" role="alert" >       Experimental   Experimental features may change or be removed without notice.      AI Assistant   Enable AI-powered Quick Ask and Chat sidebar.            Workflow Automation   Enable experimental workflow automation features in Automation Hub.           Save      ... × EE Chat (streaming state) > shows the partial response when a network error occurs mid-stream 7ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
    Experimental Features   Enable or disable experimental features for your tenant. 

 
  svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 border-l-4 border-l-warning border-y-0 border-r-0 text-[rgb(var(--color-text-800))] [&>svg]:text-warning bg-warning/10" role="alert" >       Experimental   Experimental features may change or be removed without notice.      AI Assistant   Enable AI-powered Quick Ask and Chat sidebar.            Workflow Automation   Enable experimental workflow automation features in Automation Hub.           Save      ... × EE Chat (streaming state) > shows an interruption indicator when the stream ends without done=true 5ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
    Experimental Features   Enable or disable experimental features for your tenant. 

 
  svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 border-l-4 border-l-warning border-y-0 border-r-0 text-[rgb(var(--color-text-800))] [&>svg]:text-warning bg-warning/10" role="alert" >       Experimental   Experimental features may change or be removed without notice.      AI Assistant   Enable AI-powered Quick Ask and Chat sidebar.            Workflow Automation   Enable experimental workflow automation features in Automation Hub.           Save      ... × EE Chat (streaming state) > persists the assistant message after streaming completes 5ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
    Experimental Features   Enable or disable experimental features for your tenant. 

 
  svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 border-l-4 border-l-warning border-y-0 border-r-0 text-[rgb(var(--color-text-800))] [&>svg]:text-warning bg-warning/10" role="alert" >       Experimental   Experimental features may change or be removed without notice.      AI Assistant   Enable AI-powered Quick Ask and Chat sidebar.            Workflow Automation   Enable experimental workflow automation features in Automation Hub.           Save      ... × EE Chat (streaming state) > persists assistant content matching the final streamed tokens 4ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style    
    Experimental Features   Enable or disable experimental features for your tenant. 

 
  svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 border-l-4 border-l-warning border-y-0 border-r-0 text-[rgb(var(--color-text-800))] [&>svg]:text-warning bg-warning/10" role="alert" >       Experimental   Experimental features may change or be removed without notice.      AI Assistant   Enable AI-powered Quick Ask and Chat sidebar.            Workflow Automation   Enable experimental workflow automation features in Automation Hub.           Save      ... ✓ packages/projects/tests/projectMaterialsDrawer.test.tsx (16 tests) 354ms 284 MB heap used ✓ server/src/test/unit/QuickAskOverlay.streaming.test.tsx (1 test) 24ms 304 MB heap used Test Files 561 failed | 40 passed (601) Tests 62 failed | 311 passed | 37 skipped (410) Start at 14:53:12 Duration 37.95s (transform 1.69s, setup 228ms, collect 1.07s, tests 29.30s, environment 249ms, prepare 53ms) (pass). ### 2026-02-12 — T002 implemented - Marked unknown node-type rejection with actionable schema diagnostics as implemented. - Evidence: packages/billing/src/lib/invoice-template-ast/schema.test.ts::returns structured validation errors for invalid AST payloads Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/lib/invoice-template-ast/schema.test.ts packages/billing/src/lib/invoice-template-ast/strategies.test.ts packages/billing/src/lib/invoice-template-ast/evaluator.test.ts' (pass). ### 2026-02-12 — T003 implemented - Marked dynamic-table repeat metadata enforcement as implemented. - Evidence: packages/billing/src/lib/invoice-template-ast/schema.test.ts::requires repeat binding metadata for dynamic-table nodes Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/lib/invoice-template-ast/schema.test.ts packages/billing/src/lib/invoice-template-ast/strategies.test.ts packages/billing/src/lib/invoice-template-ast/evaluator.test.ts' (pass). ### 2026-02-12 — T004 implemented - Marked transform payload shape validation across filter/sort/group/aggregate/computed operations as implemented. - Evidence: packages/billing/src/lib/invoice-template-ast/schema.test.ts::enforces transform payload shapes Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/lib/invoice-template-ast/schema.test.ts packages/billing/src/lib/invoice-template-ast/strategies.test.ts packages/billing/src/lib/invoice-template-ast/evaluator.test.ts' (pass). ### 2026-02-12 — T005 implemented - Marked optional strategyId acceptance in schema validation as implemented. - Evidence: packages/billing/src/lib/invoice-template-ast/schema.test.ts::accepts optional strategyId on transform operations Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/lib/invoice-template-ast/schema.test.ts packages/billing/src/lib/invoice-template-ast/strategies.test.ts packages/billing/src/lib/invoice-template-ast/evaluator.test.ts' (pass). ### 2026-02-12 — T006 implemented - Marked strategy registry allowlist resolution and unknown-ID rejection as implemented. - Evidence: packages/billing/src/lib/invoice-template-ast/strategies.test.ts Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/lib/invoice-template-ast/schema.test.ts packages/billing/src/lib/invoice-template-ast/strategies.test.ts packages/billing/src/lib/invoice-template-ast/evaluator.test.ts' (pass). ### 2026-02-12 — T007 implemented - Marked evaluator filter transform semantics as implemented. - Evidence: packages/billing/src/lib/invoice-template-ast/evaluator.test.ts::applies filter transforms to invoice items Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/lib/invoice-template-ast/schema.test.ts packages/billing/src/lib/invoice-template-ast/strategies.test.ts packages/billing/src/lib/invoice-template-ast/evaluator.test.ts' (pass). ### 2026-02-12 — T008 implemented - Marked deterministic multi-key sort behavior as implemented. - Evidence: packages/billing/src/lib/invoice-template-ast/evaluator.test.ts::applies multi-key sort transforms with stable ordering Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/lib/invoice-template-ast/schema.test.ts packages/billing/src/lib/invoice-template-ast/strategies.test.ts packages/billing/src/lib/invoice-template-ast/evaluator.test.ts' (pass). ### 2026-02-12 — T009 implemented - Marked grouping transform bucket output behavior as implemented. - Evidence: packages/billing/src/lib/invoice-template-ast/evaluator.test.ts::applies grouping and aggregate transforms Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/lib/invoice-template-ast/schema.test.ts packages/billing/src/lib/invoice-template-ast/strategies.test.ts packages/billing/src/lib/invoice-template-ast/evaluator.test.ts' (pass). ### 2026-02-12 — T010 implemented - Marked aggregate totals math (sum/count/avg) as implemented. - Evidence: packages/billing/src/lib/invoice-template-ast/evaluator.test.ts::applies grouping and aggregate transforms Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/lib/invoice-template-ast/schema.test.ts packages/billing/src/lib/invoice-template-ast/strategies.test.ts packages/billing/src/lib/invoice-template-ast/evaluator.test.ts' (pass). ### 2026-02-12 — T011 implemented - Marked computed-field expression and derived totals behavior as implemented. - Evidence: packages/billing/src/lib/invoice-template-ast/evaluator.test.ts::computes derived fields and totals composition values Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/lib/invoice-template-ast/schema.test.ts packages/billing/src/lib/invoice-template-ast/strategies.test.ts packages/billing/src/lib/invoice-template-ast/evaluator.test.ts' (pass). ### 2026-02-12 — T012 implemented - Marked allowlisted strategy hook execution path as implemented. - Evidence: packages/billing/src/lib/invoice-template-ast/evaluator.test.ts::executes allowlisted strategy hooks Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/lib/invoice-template-ast/schema.test.ts packages/billing/src/lib/invoice-template-ast/strategies.test.ts packages/billing/src/lib/invoice-template-ast/evaluator.test.ts' (pass). ### 2026-02-12 — T013 implemented - Added explicit evaluator unit coverage for strategy hook throw behavior. - Evidence: `packages/billing/src/lib/invoice-template-ast/evaluator.test.ts` (`reports explicit strategy execution errors when strategy hooks throw`). Verification: - `NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/lib/invoice-template-ast/evaluator.test.ts` (pass). ### 2026-02-12 — T003 implemented - Marked repeat-binding metadata requirements for dynamic tables as implemented. - Evidence: packages/billing/src/lib/invoice-template-ast/schema.test.ts::requires repeat binding metadata for dynamic-table nodes Verification: - \ WARN  Unsupported engine: wanted: {"node":">=20 <25"} (current: {"node":"v25.5.0","pnpm":"9.15.9"}) RUN v3.2.4 /Users/roberisaacs/alga-psa.worktrees/codex/feature-invoice-designer Running tests with seed "1770926031206" Environment file path: /Users/roberisaacs/alga-psa.worktrees/codex/feature-invoice-designer/.env.localtest stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts > Tax Rate Changes Mid-Billing Period CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts > Tax Rate Changes Mid-Billing Period Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts > Tax Rate Changes Mid-Billing Period CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts > Tax Rate Changes Mid-Billing Period Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts (1 test | 1 skipped) 20ms 43 MB heap used ↓ Tax Rate Changes Mid-Billing Period > should apply correct tax rates based on charge dates ✓ ee/server/src/__tests__/unit/basic.test.ts (3 tests) 1ms 32 MB heap used ❯ ee/extensions/samples/ui-kit-showcase/test/build.test.ts (1 test | 1 failed) 2ms 33 MB heap used × build output > iframe bundle is generated in ui/dist/iframe 2ms → expected false to be true // Object.is equality ✓ packages/scheduling/tests/serverPageSchedulingProvider.test.ts (1 test) 0ms 57 MB heap used ✓ packages/billing/src/actions/invoiceTemplatePreviewCacheRemoval.test.ts (2 tests) 0ms 57 MB heap used ✓ packages/clients/src/schemas/client.schema.test.ts (4 tests) 1ms 60 MB heap used ❯ packages/auth/src/lib/rbac.test.ts (3 tests | 3 failed) 4ms 62 MB heap used × rbac permission checks > allows internal users to use MSP permissions only 0ms → promise rejected "Error: [vitest] No "runWithTenant" export… { codeFrame: '…' }" instead of resolving × rbac permission checks > allows client users to use client permissions only 3ms → promise rejected "Error: [vitest] No "runWithTenant" export… { codeFrame: '…' }" instead of resolving × rbac permission checks > returns aggregated permission results 0ms → [vitest] No "runWithTenant" export is defined on the "@alga-psa/db" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: ✓ packages/types/src/interfaces/comment.interface.typecheck.test.ts (1 test) 0ms 63 MB heap used stdout | ee/temporal-workflows/src/activities/__tests__/test-file-check.test.ts > Check if file actually gets created > should show file exists after test File exists: false File path: /var/folders/8g/3xyjqdpd4hx2h39h4qb2lyvm0000gn/T/test-check-gYZTLn/msp/istio-virtualservice.yaml ✓ ee/temporal-workflows/src/activities/__tests__/test-file-check.test.ts (1 test) 0ms 64 MB heap used stdout | server/src/test/integration/appointmentNotifications.integration.test.ts > Appointment Notification System Integration Tests Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/appointmentNotifications.integration.test.ts > Appointment Notification System Integration Tests CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/appointmentNotifications.integration.test.ts > Appointment Notification System Integration Tests CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/appointmentNotifications.integration.test.ts > Appointment Notification System Integration Tests Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/appointmentNotifications.integration.test.ts > Appointment Notification System Integration Tests CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/appointmentNotifications.integration.test.ts > Appointment Notification System Integration Tests Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/integration/appointmentNotifications.integration.test.ts (29 tests | 29 skipped) 2ms 67 MB heap used ↓ Appointment Notification System Integration Tests > Email Notifications > should send appointment request received email to client ↓ Appointment Notification System Integration Tests > Email Notifications > should send new appointment request email to MSP staff ↓ Appointment Notification System Integration Tests > Email Notifications > should send appointment approved email with correct locale ↓ Appointment Notification System Integration Tests > Email Notifications > should send appointment declined email with reason ↓ Appointment Notification System Integration Tests > Email Notifications > should include tenant settings in all emails ↓ Appointment Notification System Integration Tests > Email Notifications > should replace template variables correctly ↓ Appointment Notification System Integration Tests > Internal Notifications > should create notification for client on request submission ↓ Appointment Notification System Integration Tests > Internal Notifications > should create notifications for MSP staff on request submission ↓ Appointment Notification System Integration Tests > Internal Notifications > should create notification for client on approval ↓ Appointment Notification System Integration Tests > Internal Notifications > should create notification for client on decline ↓ Appointment Notification System Integration Tests > Internal Notifications > should include correct link in notifications ↓ Appointment Notification System Integration Tests > Internal Notifications > should populate metadata correctly for staff notifications ↓ Appointment Notification System Integration Tests > Helper Function Integration > should get correct schedule approvers ↓ Appointment Notification System Integration Tests > Helper Function Integration > should get correct tenant settings ↓ Appointment Notification System Integration Tests > Helper Function Integration > should map contact to client user ID correctly ↓ Appointment Notification System Integration Tests > Helper Function Integration > should return null for non-existent contact ↓ Appointment Notification System Integration Tests > Helper Function Integration > should format dates with correct locale ↓ Appointment Notification System Integration Tests > Helper Function Integration > should format times with correct locale ↓ Appointment Notification System Integration Tests > Multi-Language Notification Support > should send email notifications in different languages ↓ Appointment Notification System Integration Tests > Multi-Language Notification Support > should format dates according to locale in notifications ↓ Appointment Notification System Integration Tests > Multi-Language Notification Support > should default to English when locale is not supported ↓ Appointment Notification System Integration Tests > Cancellation Notifications > should send cancellation notification to client ↓ Appointment Notification System Integration Tests > Cancellation Notifications > should handle cancellation of already cancelled request gracefully ↓ Appointment Notification System Integration Tests > Notification Metadata and Navigation > should include actionable metadata in staff notifications ↓ Appointment Notification System Integration Tests > Notification Metadata and Navigation > should include appropriate links for client notifications ↓ Appointment Notification System Integration Tests > Notification Metadata and Navigation > should set correct notification types for different events ↓ Appointment Notification System Integration Tests > Error Handling and Edge Cases > should handle missing email addresses gracefully ↓ Appointment Notification System Integration Tests > Error Handling and Edge Cases > should batch notifications to multiple staff members efficiently ↓ Appointment Notification System Integration Tests > Error Handling and Edge Cases > should include all required data fields in notifications ✓ packages/billing/src/actions/invoiceTemplateAstPersistenceWiring.test.ts (3 tests) 0ms 67 MB heap used ❯ ee/temporal-workflows/src/activities/__tests__/email-activities.temporal.test.ts (11 tests | 10 failed) 4393ms 108 MB heap used × Email Activities - Temporal Unit Tests > Password Generation with Temporal Context > should generate secure passwords with proper entropy 0ms → expected Promise{…} to have property 'length' × Email Activities - Temporal Unit Tests > Password Generation with Temporal Context > should handle various password lengths correctly 1ms → expected Promise{…} to have property 'length' ✓ Email Activities - Temporal Unit Tests > Password Generation with Temporal Context > should ensure consistent randomness across calls 0ms × Email Activities - Temporal Unit Tests > Email Activity Direct Testing > should send welcome email with valid input 0ms → Cannot read properties of undefined (reading 'info') × Email Activities - Temporal Unit Tests > Email Activity Direct Testing > should handle invalid email addresses gracefully 0ms → Cannot read properties of undefined (reading 'info') × Email Activities - Temporal Unit Tests > Email Activity Direct Testing > should handle empty email addresses 0ms → Cannot read properties of undefined (reading 'info') × Email Activities - Temporal Unit Tests > Email Activity Direct Testing > should work with minimal required fields 0ms → Cannot read properties of undefined (reading 'info') × Email Activities - Temporal Unit Tests > Email Template Generation > should generate proper email content structure 0ms → Cannot read properties of undefined (reading 'info') × Email Activities - Temporal Unit Tests > Email Template Generation > should handle template variable substitution 1ms → Cannot read properties of undefined (reading 'info') × Email Activities - Temporal Unit Tests > Error Handling and Resilience > should not throw exceptions on failure 0ms → Cannot read properties of undefined (reading 'info') × Email Activities - Temporal Unit Tests > Error Handling and Resilience > should handle missing required fields gracefully 0ms → Cannot read properties of undefined (reading 'info') ✓ packages/billing/src/lib/invoice-template-ast/schema.test.ts (5 tests) 3ms 116 MB heap used ❯ server/src/test/unit/scheduling/actionGuardWiring.test.ts (7 tests | 4 failed) 2ms 119 MB heap used ✓ delegation guard wiring (static) > fetchTimePeriods enforces delegation via assertCanActOnBehalf 0ms ✓ delegation guard wiring (static) > fetchOrCreateTimeSheet enforces delegation via assertCanActOnBehalf 0ms × delegation guard wiring (static) > fetchTimeSheet enforces owner-or-delegate access via assertCanActOnBehalf 0ms → expected '\'use server\'\n\nimport {\n ITimeEn…' to match /export const fetchTimeSheet[\\s\\S]*a…/ × delegation guard wiring (static) > fetchTimeEntriesForTimeSheet enforces owner-or-delegate access via assertCanActOnBehalf 0ms → expected '\'use server\'\n\nimport {\n ITimeEn…' to match /export const fetchTimeEntriesForTimeS…/ × delegation guard wiring (static) > fetchWorkItemsForTimeSheet enforces owner-or-delegate access via assertCanActOnBehalf 0ms → expected '\'use server\'\n\nimport { Knex } fro…' to match /export const fetchWorkItemsForTimeShe…/ ✓ delegation guard wiring (static) > reopen/reverse approval is blocked when a timesheet contains invoiced entries 0ms × delegation guard wiring (static) > reopen/reverse approval transitions timesheet and entries to CHANGES_REQUESTED 1ms → expected '\'use server\'\n\nimport {\n ITimeEn…' to match /reverseTimeSheetApproval[\\s\\S]*appr…/ stdout | server/src/test/infrastructure/time-periods/timePeriodsActions.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/infrastructure/time-periods/timePeriodsActions.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/infrastructure/time-periods/timePeriodsActions.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/infrastructure/time-periods/timePeriodsActions.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/infrastructure/time-periods/timePeriodsActions.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/infrastructure/time-periods/timePeriodsActions.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/infrastructure/time-periods/timePeriodsActions.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/infrastructure/time-periods/timePeriodsActions.test.ts Retrieved secret 'db_password_server' from configured provider. ❯ ee/temporal-workflows/src/test-utils/test-connection.test.ts (3 tests | 1 failed) 122ms 170 MB heap used ✓ Temporal Connection Tests > should connect to temporalio/auto-setup Docker container 9ms ✓ Temporal Connection Tests > should create TestWorkflowEnvironment for unit tests 110ms × Temporal Connection Tests > should verify Docker Postgres connection 3ms → ✓ ee/server/src/__tests__/unit/invoicingHostApi.unit.test.ts (4 tests) 3ms 172 MB heap used stdout | packages/billing/src/lib/adapters/invoiceAdapters.test.ts > mapDbInvoiceToWasmViewModel > maps tenant snapshot details when provided by the invoice query payload [mapDbInvoiceToWasmViewModel] Received Data: { "invoice_number": "INV-601", "invoice_date": "2026-02-06", "due_date": "2026-02-20", "currency_code": "USD", "client": { "name": "Blue Harbor Dental", "address": "901 Harbor Ave" }, "tenantClientInfo": { "client_name": "Northwind MSP", "location_address": "400 SW Main St", "logo_url": "https://cdn.example.com/logo.png" }, "invoice_charges": [], "subtotal": 0, "tax": 0, "total": 0 } [mapDbInvoiceToWasmViewModel] Input data appears to be in DbInvoiceViewModel format. Mapping... [mapDbInvoiceToWasmViewModel] Mapped ViewModel: { "invoiceNumber": "INV-601", "issueDate": "2026-02-06", "dueDate": "2026-02-20", "customer": { "name": "Blue Harbor Dental", "address": "901 Harbor Ave" }, "poNumber": null, "tenantClient": { "name": "Northwind MSP", "address": "400 SW Main St", "logoUrl": "https://cdn.example.com/logo.png" }, "items": [], "subtotal": 0, "tax": 0, "total": 0, "taxSource": "internal", "currencyCode": "USD" } stdout | packages/billing/src/lib/adapters/invoiceAdapters.test.ts > mapDbInvoiceToWasmViewModel > handles nullable/partial values safely [mapDbInvoiceToWasmViewModel] Received Data: { "invoice_number": null, "invoice_date": null, "due_date": null, "client": { "name": null, "address": null }, "invoice_charges": [ { "item_id": null, "description": null, "quantity": null, "unit_price": null, "total_price": null } ], "subtotal": null, "tax": null, "total": null } [mapDbInvoiceToWasmViewModel] Input data appears to be in DbInvoiceViewModel format. Mapping... [mapDbInvoiceToWasmViewModel] Mapped ViewModel: { "invoiceNumber": "N/A", "issueDate": "", "dueDate": "", "customer": { "name": "N/A", "address": "N/A" }, "poNumber": null, "tenantClient": null, "items": [ { "id": "", "description": "", "quantity": 0, "unitPrice": 0, "total": 0 } ], "subtotal": 0, "tax": 0, "total": 0, "taxSource": "internal", "currencyCode": "USD" } stdout | packages/billing/src/lib/adapters/invoiceAdapters.test.ts > mapDbInvoiceToWasmViewModel > keeps canonical minor-unit payloads unchanged [mapDbInvoiceToWasmViewModel] Received Data: { "invoice_number": "INV-2026-0147", "invoice_date": "2026-02-06", "due_date": "2026-02-20", "currency_code": "USD", "client": { "name": "Blue Harbor Dental", "address": "901 Harbor Ave" }, "invoice_charges": [ { "item_id": "svc-monitoring", "description": "Managed Endpoint Monitoring", "quantity": 15, "unit_price": 4200, "total_price": 63000 } ], "subtotal": 87000, "tax": 7830, "total": 94830 } [mapDbInvoiceToWasmViewModel] Input data appears to be in DbInvoiceViewModel format. Mapping... [mapDbInvoiceToWasmViewModel] Mapped ViewModel: { "invoiceNumber": "INV-2026-0147", "issueDate": "2026-02-06", "dueDate": "2026-02-20", "customer": { "name": "Blue Harbor Dental", "address": "901 Harbor Ave" }, "poNumber": null, "tenantClient": null, "items": [ { "id": "svc-monitoring", "description": "Managed Endpoint Monitoring", "quantity": 15, "unitPrice": 4200, "total": 63000 } ], "subtotal": 87000, "tax": 7830, "total": 94830, "taxSource": "internal", "currencyCode": "USD" } stdout | packages/billing/src/lib/adapters/invoiceAdapters.test.ts > mapDbInvoiceToWasmViewModel > normalizes legacy existing-invoice major-unit payloads into minor units [mapDbInvoiceToWasmViewModel] Received Data: { "invoice_number": "INV-005", "invoice_date": "2026-01-01", "due_date": "2026-02-16", "currency_code": "USD", "client": { "name": "Emerald City", "address": "1010 Emerald Street" }, "invoice_charges": [ { "item_id": "line-1", "description": "Premium Rabbit Tracking Services", "quantity": 50, "unit_price": 125, "total_price": 6250 }, { "item_id": "line-2", "description": "Monthly Looking Glass Maintenance", "quantity": 1, "unit_price": 1250, "total_price": 1250 } ], "subtotal": 0, "tax": 0, "total": 7500 } [mapDbInvoiceToWasmViewModel] Input data appears to be in DbInvoiceViewModel format. Mapping... [mapDbInvoiceToWasmViewModel] Mapped ViewModel: { "invoiceNumber": "INV-005", "issueDate": "2026-01-01", "dueDate": "2026-02-16", "customer": { "name": "Emerald City", "address": "1010 Emerald Street" }, "poNumber": null, "tenantClient": null, "items": [ { "id": "line-1", "description": "Premium Rabbit Tracking Services", "quantity": 50, "unitPrice": 12500, "total": 625000 }, { "id": "line-2", "description": "Monthly Looking Glass Maintenance", "quantity": 1, "unitPrice": 125000, "total": 125000 } ], "subtotal": 750000, "tax": 0, "total": 750000, "taxSource": "internal", "currencyCode": "USD" } stdout | packages/billing/src/lib/adapters/invoiceAdapters.test.ts > mapDbInvoiceToWasmViewModel > keeps tenant snapshot null when tenant details are not present [mapDbInvoiceToWasmViewModel] Received Data: { "invoice_number": "INV-602", "invoice_date": "2026-02-06", "due_date": "2026-02-20", "currency_code": "USD", "client": { "name": "Blue Harbor Dental", "address": "901 Harbor Ave" }, "invoice_charges": [], "subtotal": 0, "tax": 0, "total": 0 } [mapDbInvoiceToWasmViewModel] Input data appears to be in DbInvoiceViewModel format. Mapping... [mapDbInvoiceToWasmViewModel] Mapped ViewModel: { "invoiceNumber": "INV-602", "issueDate": "2026-02-06", "dueDate": "2026-02-20", "customer": { "name": "Blue Harbor Dental", "address": "901 Harbor Ave" }, "poNumber": null, "tenantClient": null, "items": [], "subtotal": 0, "tax": 0, "total": 0, "taxSource": "internal", "currencyCode": "USD" } stdout | packages/billing/src/lib/adapters/invoiceAdapters.test.ts > mapDbInvoiceToWasmViewModel > maps db invoice payload numeric and string fields into wasm preview model [mapDbInvoiceToWasmViewModel] Received Data: { "invoice_number": "INV-500", "invoice_date": "2026-02-01", "due_date": "2026-02-15", "currency_code": "USD", "po_number": "PO-1", "tax_source": "internal", "client": { "name": "Acme", "address": "123 Main" }, "invoice_charges": [ { "item_id": "item-1", "description": "Managed Service", "quantity": "2", "unit_price": "1000", "total_price": "2000" } ], "subtotal": "2000", "tax": "100", "total": "2100" } [mapDbInvoiceToWasmViewModel] Input data appears to be in DbInvoiceViewModel format. Mapping... [mapDbInvoiceToWasmViewModel] Mapped ViewModel: { "invoiceNumber": "INV-500", "issueDate": "2026-02-01", "dueDate": "2026-02-15", "customer": { "name": "Acme", "address": "123 Main" }, "poNumber": "PO-1", "tenantClient": null, "items": [ { "id": "item-1", "description": "Managed Service", "quantity": 2, "unitPrice": 1000, "total": 2000 } ], "subtotal": 2000, "tax": 100, "total": 2100, "taxSource": "internal", "currencyCode": "USD" } ✓ packages/billing/src/lib/adapters/invoiceAdapters.test.ts (6 tests) 1ms 152 MB heap used ✓ packages/billing/src/components/invoice-designer/ast/workspaceAst.test.ts (3 tests) 1ms 159 MB heap used ✓ server/src/test/unit/migrations/timeEntriesAuditColumns.test.ts (2 tests) 0ms 160 MB heap used stdout | ee/server/src/lib/extensions/__tests__/registry-v2.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | ee/server/src/lib/extensions/__tests__/registry-v2.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | ee/server/src/lib/extensions/__tests__/registry-v2.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | ee/server/src/lib/extensions/__tests__/registry-v2.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | ee/server/src/lib/extensions/__tests__/registry-v2.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | ee/server/src/lib/extensions/__tests__/registry-v2.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | ee/server/src/lib/extensions/__tests__/registry-v2.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | ee/server/src/lib/extensions/__tests__/registry-v2.test.ts Retrieved secret 'db_password_server' from configured provider. ↓ ee/server/src/lib/extensions/__tests__/registry-v2.test.ts (5 tests | 5 skipped) ✓ server/src/test/unit/menuConfig.experimentalFeatures.test.ts (1 test) 0ms 186 MB heap used ✓ server/src/test/unit/workflowRunDialogEventUtils.test.ts (3 tests) 1ms 187 MB heap used ✓ packages/tickets/src/lib/__tests__/ticketOriginCreatePath.test.ts (5 tests) 2ms 193 MB heap used ✓ packages/auth/src/components/ssoProviderButtonsImport.test.ts (1 test) 0ms 195 MB heap used ❯ server/src/test/integration/payments/stripePaymentIntegration.test.ts (21 tests | 21 skipped) 1ms 197 MB heap used ↓ Stripe Payment Integration - Vulnerability Tests > Race Condition in Concurrent Webhook Processing > should correctly update invoice status when processing concurrent webhooks ↓ Stripe Payment Integration - Vulnerability Tests > Race Condition in Concurrent Webhook Processing > should handle duplicate webhook events idempotently ↓ Stripe Payment Integration - Vulnerability Tests > Tenant Isolation Vulnerabilities > should expose tenant isolation gap when webhook contains different tenant_id ↓ Stripe Payment Integration - Vulnerability Tests > Tenant Isolation Vulnerabilities > should prevent cross-tenant payment recording ↓ Stripe Payment Integration - Vulnerability Tests > Missing Amount and Currency Validation > should accept partial payments and update invoice status appropriately ↓ Stripe Payment Integration - Vulnerability Tests > Missing Amount and Currency Validation > should reject payment in different currency than invoice ↓ Stripe Payment Integration - Vulnerability Tests > Missing Refund Handling > should update invoice status when payment is refunded ↓ Stripe Payment Integration - Vulnerability Tests > Missing Refund Handling > should track partial refunds and update invoice balance ↓ Stripe Payment Integration - Vulnerability Tests > Invoice Status Transition Issues > should reject payments for cancelled invoices ↓ Stripe Payment Integration - Vulnerability Tests > Invoice Status Transition Issues > should reject payments for draft invoices ↓ Stripe Payment Integration - Vulnerability Tests > Webhook Error Handling Gaps > should properly report errors for webhooks referencing non-existent invoices ↓ Stripe Payment Integration - Vulnerability Tests > Webhook Error Handling Gaps > should record webhook events for valid invoices ↓ Stripe Payment Integration - Vulnerability Tests > Payment Link Expiration Issues > should expose payment link expiration beyond Stripe limit ↓ Stripe Payment Integration - Vulnerability Tests > Payment Link Expiration Issues > should expose expired payment links remaining in active status ↓ Stripe Payment Integration - Vulnerability Tests > Integer Overflow and Precision Issues > should expose potential precision loss with large payment amounts ↓ Stripe Payment Integration - Vulnerability Tests > Customer Sharing Vulnerability > should expose potential customer sharing across tenants ↓ Stripe Payment Integration - Vulnerability Tests > BUG: Wrong Redirect URLs in Payment Links > should generate correct client portal redirect URLs ↓ Stripe Payment Integration - Vulnerability Tests > BUG: Refund Events Not Parsed Correctly > should parse charge.refunded events with correct amount and currency ↓ Stripe Payment Integration - Vulnerability Tests > BUG: Refund Events Not Parsed Correctly > should process charge.refunded webhook and record refund ↓ Stripe Payment Integration - Vulnerability Tests > BUG: sessionId Parameter Not Used in Verification > should verify the specific session, not just invoice status ↓ Stripe Payment Integration - Vulnerability Tests > BUG: Incorrect Payment Method Recording > should record payment method as "stripe" not "stripe_stripe" ✓ server/src/test/unit/workflowsEntryTypingGuard.unit.test.ts (2 tests) 0ms 201 MB heap used stdout | ee/server/src/lib/extensions/__tests__/assets/url.shared.test.ts > buildExtUiSrc > appends tenant when provided [ext-ui][buildExtUiSrc] { extensionId: 'ext-1', mode: 'rust', clientPath: '/', tenantId: 'tenant-123', overrideBase: null, runnerBase: undefined, publicBase: '/runner' } stdout | ee/server/src/lib/extensions/__tests__/assets/url.shared.test.ts > buildExtUiSrc > supports relative public base for gateway proxy [ext-ui][buildExtUiSrc] { extensionId: 'ext-1', mode: 'rust', clientPath: '/', tenantId: undefined, overrideBase: null, runnerBase: '/runner', publicBase: '/runner' } stdout | ee/server/src/lib/extensions/__tests__/assets/url.shared.test.ts > buildExtUiSrc > uses absolute public base when provided [ext-ui][buildExtUiSrc] { extensionId: 'ext-1', mode: 'rust', clientPath: '/settings', tenantId: undefined, overrideBase: null, runnerBase: 'https://runner.dev/alga', publicBase: 'https://runner.dev/alga' } stdout | ee/server/src/lib/extensions/__tests__/assets/url.shared.test.ts > buildExtUiSrc > honors public base override [ext-ui][buildExtUiSrc] { extensionId: 'ext-1', mode: 'rust', clientPath: '/', tenantId: 'tenant-123', overrideBase: 'http://localhost:8085', runnerBase: undefined, publicBase: 'http://localhost:8085' } stdout | ee/server/src/lib/extensions/__tests__/assets/url.shared.test.ts > buildExtUiSrc > falls back to /runner when no public base is set [ext-ui][buildExtUiSrc] { extensionId: 'ext-1', mode: 'rust', clientPath: '/', tenantId: undefined, overrideBase: null, runnerBase: undefined, publicBase: '/runner' } ✓ ee/server/src/lib/extensions/__tests__/assets/url.shared.test.ts (5 tests) 1ms 204 MB heap used ❯ shared/workflow/actions/__tests__/emailWorkflowActions.responseSource.test.ts (6 tests | 5 failed) 15ms 214 MB heap used × createCommentFromEmail response source metadata > T002: persists metadata.responseSource=inbound_email 0ms → trx is not a function × createCommentFromEmail response source metadata > T003: includes normalized provider type when available 0ms → trx is not a function × createCommentFromEmail response source metadata > google inbound flow resolves to inbound_email metadata source (T017) 0ms → trx is not a function × createCommentFromEmail response source metadata > microsoft inbound flow resolves to inbound_email metadata source (T018) 0ms → trx is not a function × createCommentFromEmail response source metadata > imap inbound flow resolves to inbound_email metadata source (T019) 15ms → trx is not a function ✓ createCommentFromEmail response source metadata > T020: keeps comment response-state semantics unchanged (still non-internal) 0ms ✓ tools/nx-tests/nxWorkspace.test.ts (3 tests) 16520ms 216 MB heap used ✓ nx workspace > initializes and lists projects 423ms ✓ nx workspace > can generate an nx graph html file 15535ms ✓ nx workspace > runs the alga-module generator in dry-run mode 560ms stdout | server/src/test/integration/internal-notifications/notificationPreferences.integration.test.ts > Internal Notification Preferences (integration) Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/internal-notifications/notificationPreferences.integration.test.ts > Internal Notification Preferences (integration) CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/internal-notifications/notificationPreferences.integration.test.ts > Internal Notification Preferences (integration) CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/internal-notifications/notificationPreferences.integration.test.ts > Internal Notification Preferences (integration) Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/internal-notifications/notificationPreferences.integration.test.ts > Internal Notification Preferences (integration) CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/internal-notifications/notificationPreferences.integration.test.ts > Internal Notification Preferences (integration) Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/internal-notifications/notificationPreferences.integration.test.ts > Internal Notification Preferences (integration) CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/internal-notifications/notificationPreferences.integration.test.ts > Internal Notification Preferences (integration) Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/integration/internal-notifications/notificationPreferences.integration.test.ts (5 tests | 5 skipped) 34ms 109 MB heap used ↓ Internal Notification Preferences (integration) > creates a notification when preferences allow it ↓ Internal Notification Preferences (integration) > does not create a notification when category preference is disabled ↓ Internal Notification Preferences (integration) > allows subtype preference to override disabled category ↓ Internal Notification Preferences (integration) > renders notification using user locale when localized template exists ↓ Internal Notification Preferences (integration) > falls back to English template while preserving user locale when translation is missing ↓ server/src/test/integration/inboundEmailInApp.webhooks.integration.test.ts (11 tests | 11 skipped) stdout | server/src/test/unit/notifications/delayedEmailQueue.test.ts > DelayedEmailQueue > Shutdown > should cleanup on shutdown [DelayedEmailQueue] Processing loop started { intervalMs: 10000 } [DelayedEmailQueue] Initialized successfully { maxRetries: 5, baseDelayMs: 60000, maxDelayMs: 900000, checkIntervalMs: 10000 } stdout | server/src/test/unit/notifications/delayedEmailQueue.test.ts > DelayedEmailQueue > Shutdown > should cleanup on shutdown [DelayedEmailQueue] Shutting down... [DelayedEmailQueue] Shutdown complete stdout | server/src/test/unit/notifications/delayedEmailQueue.test.ts > DelayedEmailQueue > Process Ready > should not process emails that are not ready yet [DelayedEmailQueue] Processing loop started { intervalMs: 100000 } [DelayedEmailQueue] Initialized successfully { maxRetries: 5, baseDelayMs: 60000, maxDelayMs: 900000, checkIntervalMs: 100000 } stdout | server/src/test/unit/notifications/delayedEmailQueue.test.ts > DelayedEmailQueue > Process Ready > should process one email per tenant for fair scheduling [DelayedEmailQueue] Processing loop started { intervalMs: 100000 } [DelayedEmailQueue] Initialized successfully { maxRetries: 5, baseDelayMs: 60000, maxDelayMs: 900000, checkIntervalMs: 100000 } stdout | server/src/test/unit/notifications/delayedEmailQueue.test.ts > DelayedEmailQueue > Process Ready > should process one email per tenant for fair scheduling [DelayedEmailQueue] Found ready emails { count: 5 } stdout | server/src/test/unit/notifications/delayedEmailQueue.test.ts > DelayedEmailQueue > Process Ready > should process one email per tenant for fair scheduling [DelayedEmailQueue] Processing queued email { id: 't1-email-1', tenantId: 'tenant-1', to: 'user1@tenant1.com', retryCount: 1 } stdout | server/src/test/unit/notifications/delayedEmailQueue.test.ts > DelayedEmailQueue > Process Ready > should process one email per tenant for fair scheduling [DelayedEmailQueue] Processing queued email { id: 't2-email-1', tenantId: 'tenant-2', to: 'user1@tenant2.com', retryCount: 1 } stdout | server/src/test/unit/notifications/delayedEmailQueue.test.ts > DelayedEmailQueue > Process Ready > should process one email per tenant for fair scheduling [DelayedEmailQueue] Processing cycle complete { processedCount: 2, durationMs: 0 } stdout | server/src/test/unit/notifications/delayedEmailQueue.test.ts > DelayedEmailQueue > Process Ready > should process emails that are ready [DelayedEmailQueue] Processing loop started { intervalMs: 100000 } [DelayedEmailQueue] Initialized successfully { maxRetries: 5, baseDelayMs: 60000, maxDelayMs: 900000, checkIntervalMs: 100000 } stdout | server/src/test/unit/notifications/delayedEmailQueue.test.ts > DelayedEmailQueue > Process Ready > should process emails that are ready [DelayedEmailQueue] Found ready emails { count: 1 } stdout | server/src/test/unit/notifications/delayedEmailQueue.test.ts > DelayedEmailQueue > Process Ready > should process emails that are ready [DelayedEmailQueue] Processing queued email { id: 'test-id-1', tenantId: 'tenant-1', to: 'test@example.com', retryCount: 1 } stdout | server/src/test/unit/notifications/delayedEmailQueue.test.ts > DelayedEmailQueue > Process Ready > should process emails that are ready [DelayedEmailQueue] Processing cycle complete { processedCount: 1, durationMs: 0 } stdout | server/src/test/unit/notifications/delayedEmailQueue.test.ts > DelayedEmailQueue > Stats > should return zero when queue is empty [DelayedEmailQueue] Processing loop started { intervalMs: 10000 } [DelayedEmailQueue] Initialized successfully { maxRetries: 5, baseDelayMs: 60000, maxDelayMs: 900000, checkIntervalMs: 10000 } stdout | server/src/test/unit/notifications/delayedEmailQueue.test.ts > DelayedEmailQueue > Stats > should return pending count [DelayedEmailQueue] Processing loop started { intervalMs: 10000 } [DelayedEmailQueue] Initialized successfully { maxRetries: 5, baseDelayMs: 60000, maxDelayMs: 900000, checkIntervalMs: 10000 } stdout | server/src/test/unit/notifications/delayedEmailQueue.test.ts > DelayedEmailQueue > Retry Count Tracking > should increment retry count on each processing [DelayedEmailQueue] Processing loop started { intervalMs: 100000 } [DelayedEmailQueue] Initialized successfully { maxRetries: 5, baseDelayMs: 60000, maxDelayMs: 900000, checkIntervalMs: 100000 } stdout | server/src/test/unit/notifications/delayedEmailQueue.test.ts > DelayedEmailQueue > Retry Count Tracking > should increment retry count on each processing [DelayedEmailQueue] Found ready emails { count: 1 } stdout | server/src/test/unit/notifications/delayedEmailQueue.test.ts > DelayedEmailQueue > Retry Count Tracking > should increment retry count on each processing [DelayedEmailQueue] Processing queued email { id: 'test-id-1', tenantId: 'tenant-1', to: 'test@example.com', retryCount: 3 } stdout | server/src/test/unit/notifications/delayedEmailQueue.test.ts > DelayedEmailQueue > Retry Count Tracking > should increment retry count on each processing [DelayedEmailQueue] Processing cycle complete { processedCount: 1, durationMs: 1 } stdout | server/src/test/unit/notifications/delayedEmailQueue.test.ts > DelayedEmailQueue > Enqueue > should enqueue email with correct delay [DelayedEmailQueue] Processing loop started { intervalMs: 10000 } [DelayedEmailQueue] Initialized successfully { maxRetries: 5, baseDelayMs: 60000, maxDelayMs: 900000, checkIntervalMs: 10000 } stdout | server/src/test/unit/notifications/delayedEmailQueue.test.ts > DelayedEmailQueue > Enqueue > should enqueue email with correct delay [DelayedEmailQueue] Email enqueued for retry { id: '1770926054867-gxjbfn9vg', tenantId: 'tenant-1', to: 'test@example.com', retryCount: 0, readyAt: '2026-02-12T19:55:19.349Z', delayMs: 64482 } stdout | server/src/test/unit/notifications/delayedEmailQueue.test.ts > DelayedEmailQueue > Initialization > should warn if initialized twice [DelayedEmailQueue] Processing loop started { intervalMs: 10000 } [DelayedEmailQueue] Initialized successfully { maxRetries: 5, baseDelayMs: 60000, maxDelayMs: 900000, checkIntervalMs: 10000 } stdout | server/src/test/unit/notifications/delayedEmailQueue.test.ts > DelayedEmailQueue > Initialization > should initialize with Redis client and callback [DelayedEmailQueue] Processing loop started { intervalMs: 10000 } [DelayedEmailQueue] Initialized successfully { maxRetries: 5, baseDelayMs: 60000, maxDelayMs: 900000, checkIntervalMs: 10000 } ✓ server/src/test/unit/notifications/delayedEmailQueue.test.ts (18 tests) 3ms 111 MB heap used stdout | sdk/samples/component/secrets-demo/tests/handler.test.ts > handler > echoes secrets and config [mock logging] [secrets-demo] request start tenant=tenant-123 requestId=req-1 method=GET url=/demo configKeys=1 secrets=1 build=2025-11-11T17:34:00Z stdout | sdk/samples/component/secrets-demo/tests/handler.test.ts > handler > echoes secrets and config [mock logging] [secrets-demo] greeting secret resolved; emitting response stdout | sdk/samples/component/secrets-demo/tests/handler.test.ts > handler > echoes secrets and config [mock logging] [secrets-demo] request complete requestId=req-1 status=200 build=2025-11-11T17:34:00Z ✓ sdk/samples/component/secrets-demo/tests/handler.test.ts (1 test) 0ms 113 MB heap used stdout | server/src/test/integration/imports/importWorkflow.integration.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/imports/importWorkflow.integration.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/imports/importWorkflow.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/imports/importWorkflow.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/imports/importWorkflow.integration.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/imports/importWorkflow.integration.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/imports/importWorkflow.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/imports/importWorkflow.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/imports/importWorkflow.integration.test.ts > Asset import integration CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/imports/importWorkflow.integration.test.ts > Asset import integration Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/imports/importWorkflow.integration.test.ts > Asset import integration CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/imports/importWorkflow.integration.test.ts > Asset import integration Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/integration/imports/importWorkflow.integration.test.ts (3 tests | 3 skipped) 2ms 132 MB heap used ↓ Asset import integration > registers default CSV/RMM importers in the database ↓ Asset import integration > generates preview summaries with validation and duplicate detection for N-able exports ↓ Asset import integration > detects duplicates via MAC normalization and fuzzy hostname matches ✓ ee/server/extensions/samples/ui-kit-showcase/test/scaffold.test.ts (8 tests) 1ms 134 MB heap used stdout | server/src/test/integration/calendar/webhookProcessing.integration.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/calendar/webhookProcessing.integration.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/calendar/webhookProcessing.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/calendar/webhookProcessing.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/calendar/webhookProcessing.integration.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/calendar/webhookProcessing.integration.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/calendar/webhookProcessing.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/calendar/webhookProcessing.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Initializing event bus [EventBus] Creating new Redis client [RedisConfig] Using configuration: { url: 'redis://localhost:6379', prefix: 'alga-psa:', eventBus: { streamPrefix: 'event-stream:', consumerGroup: 'event-processors', maxStreamLength: 1000, blockingTimeout: 5000, claimTimeout: 30000, batchSize: 10, reconnectStrategy: { retries: 10, initialDelay: 100, maxDelay: 3000 } } } Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout CompositeSecretProvider found app secret 'redis_password' from provider 1 stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout Retrieved secret 'redis_password' from configured provider. stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Redis Client Connected [EventBus] Redis Client Ready stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:TICKET_CREATED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:TICKET_UPDATED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:TICKET_CLOSED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:TICKET_DELETED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:TICKET_ASSIGNED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:TICKET_ADDITIONAL_AGENT_ASSIGNED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:TICKET_COMMENT_ADDED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:TICKET_COMMENT_UPDATED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:TICKET_RESPONSE_STATE_CHANGED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:TICKET_STATUS_CHANGED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:TICKET_PRIORITY_CHANGED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:TICKET_UNASSIGNED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:TICKET_REOPENED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:TICKET_ESCALATED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:TICKET_QUEUE_CHANGED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:TICKET_MESSAGE_ADDED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:TICKET_CUSTOMER_REPLIED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:TICKET_INTERNAL_NOTE_ADDED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:TICKET_SLA_STAGE_ENTERED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:TICKET_SLA_STAGE_MET stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:TICKET_SLA_STAGE_BREACHED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:PROJECT_CREATED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:PROJECT_UPDATED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:PROJECT_CLOSED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:PROJECT_ASSIGNED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:PROJECT_TASK_ASSIGNED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:PROJECT_TASK_ADDITIONAL_AGENT_ASSIGNED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:TASK_COMMENT_ADDED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:TASK_COMMENT_UPDATED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:TIME_ENTRY_SUBMITTED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:TIME_ENTRY_APPROVED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:INVOICE_GENERATED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:INVOICE_FINALIZED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:CUSTOM_EVENT stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:INBOUND_EMAIL_RECEIVED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:ACCOUNTING_EXPORT_COMPLETED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:ACCOUNTING_EXPORT_FAILED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:SCHEDULE_ENTRY_CREATED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:SCHEDULE_ENTRY_UPDATED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:SCHEDULE_ENTRY_DELETED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:CALENDAR_SYNC_STARTED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:CALENDAR_SYNC_COMPLETED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:CALENDAR_SYNC_FAILED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:CALENDAR_CONFLICT_DETECTED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:MESSAGE_SENT stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:USER_MENTIONED_IN_DOCUMENT stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:APPOINTMENT_REQUEST_CREATED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:APPOINTMENT_REQUEST_APPROVED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:APPOINTMENT_REQUEST_DECLINED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:APPOINTMENT_REQUEST_CANCELLED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:RMM_DEVICE_CREATED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:RMM_DEVICE_UPDATED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:RMM_DEVICE_DELETED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:RMM_DEVICE_ONLINE stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:RMM_DEVICE_OFFLINE stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:RMM_ALERT_TRIGGERED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:RMM_ALERT_RESOLVED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:RMM_SYNC_STARTED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:RMM_SYNC_COMPLETED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:RMM_SYNC_FAILED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Created consumer group for stream: alga-psa:event-stream:global:RMM_WEBHOOK_RECEIVED stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] No active subscriptions, waiting for handlers to be registered stdout | packages/event-bus/src/index.hardTimeout.test.ts > EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout [EventBus] Added handler: { eventType: 'TICKET_CREATED', channel: 'global', handlerName: '', handlersCount: 1 } ❯ packages/event-bus/src/index.hardTimeout.test.ts (1 test | 1 failed) 34ms 209 MB heap used × EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout 34ms → expected 1 to be greater than or equal to 2 ✔ T001: fails with clear error when --test is missing (51.485041ms) ✔ T002: fails with clear error when bundle.json is missing (48.800541ms) ✔ T003: fails with clear error when test.cjs is missing (46.599083ms) stdout | server/src/test/integration/accounting/auditTrail.integration.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/accounting/auditTrail.integration.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/accounting/auditTrail.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/accounting/auditTrail.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/accounting/auditTrail.integration.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/accounting/auditTrail.integration.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/accounting/auditTrail.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/accounting/auditTrail.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/tickets.e2e.test.ts > Ticket API E2E Tests Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/e2e/api/tickets.e2e.test.ts > Ticket API E2E Tests CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/e2e/api/tickets.e2e.test.ts > Ticket API E2E Tests CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/tickets.e2e.test.ts > Ticket API E2E Tests Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/tickets.e2e.test.ts > Ticket API E2E Tests CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/tickets.e2e.test.ts > Ticket API E2E Tests Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/e2e/api/tickets.e2e.test.ts (47 tests | 47 skipped) 2ms 275 MB heap used ↓ Ticket API E2E Tests > Authentication > should require API key for all endpoints ↓ Ticket API E2E Tests > Authentication > should reject invalid API key ↓ Ticket API E2E Tests > CRUD Operations > Create Ticket (POST /api/v1/tickets) > should create a new ticket ↓ Ticket API E2E Tests > CRUD Operations > Create Ticket (POST /api/v1/tickets) > should validate required fields ↓ Ticket API E2E Tests > CRUD Operations > Create Ticket (POST /api/v1/tickets) > should create ticket with all optional fields ↓ Ticket API E2E Tests > CRUD Operations > Get Ticket (GET /api/v1/tickets/:id) > should retrieve a ticket by ID ↓ Ticket API E2E Tests > CRUD Operations > Get Ticket (GET /api/v1/tickets/:id) > should return 404 for non-existent ticket ↓ Ticket API E2E Tests > CRUD Operations > Get Ticket (GET /api/v1/tickets/:id) > should not return tickets from other tenants ↓ Ticket API E2E Tests > CRUD Operations > Update Ticket (PUT /api/v1/tickets/:id) > should update a ticket ↓ Ticket API E2E Tests > CRUD Operations > Update Ticket (PUT /api/v1/tickets/:id) > should return 404 when updating non-existent ticket ↓ Ticket API E2E Tests > CRUD Operations > Update Ticket (PUT /api/v1/tickets/:id) > should validate update data ↓ Ticket API E2E Tests > CRUD Operations > Delete Ticket (DELETE /api/v1/tickets/:id) > should delete a ticket ↓ Ticket API E2E Tests > CRUD Operations > Delete Ticket (DELETE /api/v1/tickets/:id) > should return 404 when deleting non-existent ticket ↓ Ticket API E2E Tests > List Tickets (GET /api/v1/tickets) > should list all tickets with default pagination ↓ Ticket API E2E Tests > List Tickets (GET /api/v1/tickets) > should support pagination parameters ↓ Ticket API E2E Tests > List Tickets (GET /api/v1/tickets) > should filter by client_id ↓ Ticket API E2E Tests > List Tickets (GET /api/v1/tickets) > should filter by status ↓ Ticket API E2E Tests > List Tickets (GET /api/v1/tickets) > should filter by priority ↓ Ticket API E2E Tests > List Tickets (GET /api/v1/tickets) > should filter by assigned user ↓ Ticket API E2E Tests > List Tickets (GET /api/v1/tickets) > should filter overdue tickets ↓ Ticket API E2E Tests > List Tickets (GET /api/v1/tickets) > should sort tickets by created date ↓ Ticket API E2E Tests > Search Tickets (GET /api/v1/tickets/search) > should search tickets by query ↓ Ticket API E2E Tests > Search Tickets (GET /api/v1/tickets/search) > should search in specified fields ↓ Ticket API E2E Tests > Search Tickets (GET /api/v1/tickets/search) > should limit search results ↓ Ticket API E2E Tests > Ticket Comments (POST /api/v1/tickets/:id/comments) > should add a comment to a ticket ↓ Ticket API E2E Tests > Ticket Comments (POST /api/v1/tickets/:id/comments) > should add an internal comment ↓ Ticket API E2E Tests > Ticket Comments (POST /api/v1/tickets/:id/comments) > should list ticket comments ↓ Ticket API E2E Tests > Ticket Comments (POST /api/v1/tickets/:id/comments) > should return 404 when adding comment to non-existent ticket ↓ Ticket API E2E Tests > Ticket Status Updates (PUT /api/v1/tickets/:id/status) > should update ticket status ↓ Ticket API E2E Tests > Ticket Status Updates (PUT /api/v1/tickets/:id/status) > should validate status transitions ↓ Ticket API E2E Tests > Ticket Assignment (PUT /api/v1/tickets/:id/assignment) > should assign ticket to user ↓ Ticket API E2E Tests > Ticket Assignment (PUT /api/v1/tickets/:id/assignment) > should unassign ticket ↓ Ticket API E2E Tests > Ticket Statistics (GET /api/v1/tickets/stats) > should return ticket statistics ↓ Ticket API E2E Tests > Ticket Statistics (GET /api/v1/tickets/stats) > should filter statistics by date range ↓ Ticket API E2E Tests > Ticket Statistics (GET /api/v1/tickets/stats) > should filter statistics by client ↓ Ticket API E2E Tests > Create Ticket from Asset (POST /api/v1/tickets/from-asset) > should create ticket from asset ↓ Ticket API E2E Tests > Error Handling > should handle invalid UUID format ↓ Ticket API E2E Tests > Error Handling > should handle invalid query parameters ↓ Ticket API E2E Tests > Error Handling > should handle missing required fields on create ↓ Ticket API E2E Tests > Error Handling > should handle invalid date formats ↓ Ticket API E2E Tests > Permissions > should enforce read permissions for GET endpoints ↓ Ticket API E2E Tests > Permissions > should enforce write permissions for POST/PUT/DELETE ↓ Ticket API E2E Tests > Permissions > should enforce assignment permissions ↓ Ticket API E2E Tests > Multi-tenancy > should isolate tickets by tenant ↓ Ticket API E2E Tests > Advanced Features > should support bulk operations ↓ Ticket API E2E Tests > Advanced Features > should support ticket templates ↓ Ticket API E2E Tests > Advanced Features > should track ticket history stdout | server/src/test/unit/ticketPermissions.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/ticketPermissions.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/ticketPermissions.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/ticketPermissions.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/ticketPermissions.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/ticketPermissions.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/ticketPermissions.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/ticketPermissions.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/invoiceTemplates/standardTemplatePoNumber.test.ts > Standard invoice template PO header > T010: default template renders PO number in header only when invoice has po_number Input JSON to WASM: {"invoiceNumber":"INV-PO","issueDate":"2025-01-01","dueDate":"2025-02-01","currencyCode":"USD","customer":{"name":"Alpha Co","address":"1 Test St"},"tenantClient":{"name":"Tenant","address":"Tenant Address","logoUrl":null},"items":[{"id":"1","description":"Service","quantity":1,"unitPrice":100,"total":100}],"subtotal":100,"tax":0,"total":100,"poNumber":"PO-XYZ"} [Wasm Log]: Wasm (standard-default): Received data string. [Wasm Log]: Wasm (standard-default): Deserialized Invoice #: INV-PO [Wasm Log]: Wasm (standard-default): Serializing layout... [Wasm Log]: Wasm (standard-default): Returning serialized layout. Output JSON from WASM: {"type": "Document", "children": [{"type": "Section", "children": [{"type": "Row", "children": [{"type": "Column", "span": 3, "children": [{"type": "Text", "content": "[Tenant Logo]", "variant": "", "id": ""}], "id": ""},{"type": "Column", "span": 5, "children": [{"type": "Text", "content": "Tenant", "variant": "heading3", "id": ""},{"type": "Text", "content": "Tenant Address", "variant": "", "id": ""}], "id": "", "style": {"paddingLeft": "0.5em", "paddingTop": "0.5em"}},{"type": "Column", "span": 4, "children": [{"type": "Text", "content": "Invoice #: INV-PO", "variant": "", "id": ""},{"type": "Text", "content": "Date: 2025-01-01", "variant": "", "id": ""},{"type": "Text", "content": "PO #: PO-XYZ", "variant": "", "id": ""}], "id": "", "style": {"textAlign": "right", "paddingRight": "0.5em"}}], "id": ""},{"type": "Row", "children": [{"type": "Column", "span": 6, "children": [{"type": "Text", "content": "Bill To:", "variant": "heading3", "id": ""},{"type": "Text", "content": "Alpha Co", "variant": "", "id": ""},{"type": "Text", "content": "1 Test St", "variant": "", "id": ""}], "id": "", "style": {"paddingLeft": "1em", "paddingTop": "0.5em"}}], "id": ""}], "id": "invoice-header-std-default"},{"type": "Section", "children": [{"type": "Text", "content": "Items", "variant": "heading3", "id": "", "style": {"marginTop": "1em", "paddingLeft": "0.5em", "paddingBottom": "0.2em"}},{"type": "Section", "children": [{"type": "Row", "children": [{"type": "Column", "span": 6, "children": [{"type": "Text", "content": "Description", "variant": "label", "id": ""}], "id": "", "style": {"paddingLeft": "0.5em"}},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "Qty", "variant": "label", "id": ""}], "id": "", "style": {"textAlign": "right"}},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "Unit Price", "variant": "label", "id": ""}], "id": "", "style": {"textAlign": "right"}},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "Total", "variant": "label", "id": "", "style": {"fontWeight": "bold", "paddingRight": "0.5em"}}], "id": "", "style": {"textAlign": "right"}}], "id": "", "style": {"fontWeight": "bold", "paddingBottom": "0.5em", "borderBottom": "1px solid #ccc"}},{"type": "Row", "children": [{"type": "Column", "span": 6, "children": [{"type": "Text", "content": "Service", "variant": "", "id": ""}], "id": "", "style": {"paddingLeft": "0.5em"}},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "1.0", "variant": "", "id": ""}], "id": "", "style": {"textAlign": "right"}},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "$1.00", "variant": "", "id": ""}], "id": "", "style": {"textAlign": "right"}},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "$1.00", "variant": "", "id": ""}], "id": "", "style": {"textAlign": "right", "paddingRight": "0.5em"}}], "id": "item-row-1", "style": {"paddingTop": "0.3em", "paddingBottom": "0.3em", "borderBottom": "0px"}}], "id": "items-table-section-items", "style": {"paddingLeft": "1em", "paddingRight": "1em", "paddingTop": "1em", "paddingBottom": "1em", "border": "1px solid #ccc", "marginBottom": "1em"}}], "id": "invoice-items-std-default"},{"type": "Section", "children": [{"type": "Row", "children": [{"type": "Column", "span": 7, "children": [], "id": ""},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "Subtotal", "variant": "", "id": ""},{"type": "Text", "content": "Tax", "variant": "", "id": ""},{"type": "Text", "content": "Total", "variant": "", "id": ""}], "id": "", "style": {"textAlign": "right", "paddingRight": "1em"}},{"type": "Column", "span": 3, "children": [{"type": "Text", "content": "$1.00", "variant": "", "id": ""},{"type": "Text", "content": "$0.00", "variant": "", "id": ""},{"type": "Text", "content": "$1.00", "variant": "", "id": "", "style": {"fontWeight": "bold"}}], "id": "", "style": {"textAlign": "right", "paddingRight": "0.5em"}}], "id": ""}], "id": "invoice-totals-std-default", "style": {"marginTop": "1em", "paddingTop": "1em", "paddingBottom": "1em", "borderTop": "1px solid #eee"}},{"type": "Section", "children": [{"type": "Text", "content": "Thank you for your business!", "variant": "", "id": "", "style": {"marginTop": "1em", "paddingLeft": "0.5em"}}], "id": "invoice-notes-std-default", "style": {"marginTop": "2em"}}], "id": "invoice-document-standard-default"} stdout | server/src/test/unit/invoiceTemplates/standardTemplatePoNumber.test.ts > Standard invoice template PO header > T010: default template renders PO number in header only when invoice has po_number Input JSON to WASM: {"invoiceNumber":"INV-PO","issueDate":"2025-01-01","dueDate":"2025-02-01","currencyCode":"USD","customer":{"name":"Alpha Co","address":"1 Test St"},"tenantClient":{"name":"Tenant","address":"Tenant Address","logoUrl":null},"items":[{"id":"1","description":"Service","quantity":1,"unitPrice":100,"total":100}],"subtotal":100,"tax":0,"total":100,"poNumber":null} [Wasm Log]: Wasm (standard-default): Received data string. [Wasm Log]: Wasm (standard-default): Deserialized Invoice #: INV-PO [Wasm Log]: Wasm (standard-default): Serializing layout... [Wasm Log]: Wasm (standard-default): Returning serialized layout. Output JSON from WASM: {"type": "Document", "children": [{"type": "Section", "children": [{"type": "Row", "children": [{"type": "Column", "span": 3, "children": [{"type": "Text", "content": "[Tenant Logo]", "variant": "", "id": ""}], "id": ""},{"type": "Column", "span": 5, "children": [{"type": "Text", "content": "Tenant", "variant": "heading3", "id": ""},{"type": "Text", "content": "Tenant Address", "variant": "", "id": ""}], "id": "", "style": {"paddingLeft": "0.5em", "paddingTop": "0.5em"}},{"type": "Column", "span": 4, "children": [{"type": "Text", "content": "Invoice #: INV-PO", "variant": "", "id": ""},{"type": "Text", "content": "Date: 2025-01-01", "variant": "", "id": ""}], "id": "", "style": {"textAlign": "right", "paddingRight": "0.5em"}}], "id": ""},{"type": "Row", "children": [{"type": "Column", "span": 6, "children": [{"type": "Text", "content": "Bill To:", "variant": "heading3", "id": ""},{"type": "Text", "content": "Alpha Co", "variant": "", "id": ""},{"type": "Text", "content": "1 Test St", "variant": "", "id": ""}], "id": "", "style": {"paddingLeft": "1em", "paddingTop": "0.5em"}}], "id": ""}], "id": "invoice-header-std-default"},{"type": "Section", "children": [{"type": "Text", "content": "Items", "variant": "heading3", "id": "", "style": {"marginTop": "1em", "paddingLeft": "0.5em", "paddingBottom": "0.2em"}},{"type": "Section", "children": [{"type": "Row", "children": [{"type": "Column", "span": 6, "children": [{"type": "Text", "content": "Description", "variant": "label", "id": ""}], "id": "", "style": {"paddingLeft": "0.5em"}},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "Qty", "variant": "label", "id": ""}], "id": "", "style": {"textAlign": "right"}},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "Unit Price", "variant": "label", "id": ""}], "id": "", "style": {"textAlign": "right"}},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "Total", "variant": "label", "id": "", "style": {"fontWeight": "bold", "paddingRight": "0.5em"}}], "id": "", "style": {"textAlign": "right"}}], "id": "", "style": {"fontWeight": "bold", "paddingBottom": "0.5em", "borderBottom": "1px solid #ccc"}},{"type": "Row", "children": [{"type": "Column", "span": 6, "children": [{"type": "Text", "content": "Service", "variant": "", "id": ""}], "id": "", "style": {"paddingLeft": "0.5em"}},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "1.0", "variant": "", "id": ""}], "id": "", "style": {"textAlign": "right"}},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "$1.00", "variant": "", "id": ""}], "id": "", "style": {"textAlign": "right"}},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "$1.00", "variant": "", "id": ""}], "id": "", "style": {"textAlign": "right", "paddingRight": "0.5em"}}], "id": "item-row-1", "style": {"paddingTop": "0.3em", "paddingBottom": "0.3em", "borderBottom": "0px"}}], "id": "items-table-section-items", "style": {"paddingLeft": "1em", "paddingRight": "1em", "paddingTop": "1em", "paddingBottom": "1em", "border": "1px solid #ccc", "marginBottom": "1em"}}], "id": "invoice-items-std-default"},{"type": "Section", "children": [{"type": "Row", "children": [{"type": "Column", "span": 7, "children": [], "id": ""},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "Subtotal", "variant": "", "id": ""},{"type": "Text", "content": "Tax", "variant": "", "id": ""},{"type": "Text", "content": "Total", "variant": "", "id": ""}], "id": "", "style": {"textAlign": "right", "paddingRight": "1em"}},{"type": "Column", "span": 3, "children": [{"type": "Text", "content": "$1.00", "variant": "", "id": ""},{"type": "Text", "content": "$0.00", "variant": "", "id": ""},{"type": "Text", "content": "$1.00", "variant": "", "id": "", "style": {"fontWeight": "bold"}}], "id": "", "style": {"textAlign": "right", "paddingRight": "0.5em"}}], "id": ""}], "id": "invoice-totals-std-default", "style": {"marginTop": "1em", "paddingTop": "1em", "paddingBottom": "1em", "borderTop": "1px solid #eee"}},{"type": "Section", "children": [{"type": "Text", "content": "Thank you for your business!", "variant": "", "id": "", "style": {"marginTop": "1em", "paddingLeft": "0.5em"}}], "id": "invoice-notes-std-default", "style": {"marginTop": "2em"}}], "id": "invoice-document-standard-default"} ✓ server/src/test/unit/invoiceTemplates/standardTemplatePoNumber.test.ts (1 test) 1436ms 293 MB heap used ✓ server/src/test/unit/email/replyTokenExtraction.test.ts (10 tests) 3ms 263 MB heap used ❯ ee/temporal-workflows/src/activities/__tests__/email-activities-standalone.test.ts (8 tests | 5 failed) 3ms 268 MB heap used × Email Activities - Standalone Tests > Password Generation > should generate secure passwords with default length 0ms → expected Promise{…} to have property 'length' × Email Activities - Standalone Tests > Password Generation > should generate passwords with custom length 0ms → expected Promise{…} to have property 'length' ✓ Email Activities - Standalone Tests > Password Generation > should generate unique passwords 0ms × Email Activities - Standalone Tests > Email Activity > should send welcome email successfully 0ms → expected false to be true // Object.is equality × Email Activities - Standalone Tests > Email Activity > should handle invalid email gracefully 1ms → expected 'Tenant ID must be a UUID with 32 hex …' to contain 'Invalid email address' × Email Activities - Standalone Tests > Email Activity > should work with minimal required fields 0ms → expected false to be true // Object.is equality ✓ Email Activities - Standalone Tests > Mock Email Service Integration > should validate email service templates 0ms ✓ Email Activities - Standalone Tests > Mock Email Service Integration > should handle unknown templates 0ms ✓ packages/tickets/src/lib/timeEntryContext.test.ts (3 tests) 0ms 223 MB heap used stdout | server/src/test/unit/timeEntryBillingContractLineSelection.test.tsx Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/timeEntryBillingContractLineSelection.test.tsx CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/timeEntryBillingContractLineSelection.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/timeEntryBillingContractLineSelection.test.tsx Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/timeEntryBillingContractLineSelection.test.tsx CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/timeEntryBillingContractLineSelection.test.tsx Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/timeEntryBillingContractLineSelection.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/timeEntryBillingContractLineSelection.test.tsx Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/billing/billingEngine.prorationExclusive.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/billing/billingEngine.prorationExclusive.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/billing/billingEngine.prorationExclusive.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/billingEngine.prorationExclusive.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/billing/billingEngine.prorationExclusive.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/billing/billingEngine.prorationExclusive.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/billing/billingEngine.prorationExclusive.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/billingEngine.prorationExclusive.test.ts Retrieved secret 'db_password_server' from configured provider. ✓ packages/core/src/lib/events/publisher.test.ts (1 test) 3ms 266 MB heap used stdout | server/src/test/unit/services/chatCompletionsService.streaming.test.ts > ChatCompletionsService (streaming) > passes stream: true to OpenRouter OpenAI client Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/services/chatCompletionsService.streaming.test.ts > ChatCompletionsService (streaming) > passes stream: true to OpenRouter OpenAI client CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/services/chatCompletionsService.streaming.test.ts > ChatCompletionsService (streaming) > passes stream: true to OpenRouter OpenAI client CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/services/chatCompletionsService.streaming.test.ts > ChatCompletionsService (streaming) > passes stream: true to OpenRouter OpenAI client Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/services/chatCompletionsService.streaming.test.ts > ChatCompletionsService (streaming) > passes stream: true to OpenRouter OpenAI client CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/services/chatCompletionsService.streaming.test.ts > ChatCompletionsService (streaming) > passes stream: true to OpenRouter OpenAI client Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/services/chatCompletionsService.streaming.test.ts > ChatCompletionsService (streaming) > passes stream: true to OpenRouter OpenAI client CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/services/chatCompletionsService.streaming.test.ts > ChatCompletionsService (streaming) > passes stream: true to OpenRouter OpenAI client Retrieved secret 'db_password_server' from configured provider. ✓ server/src/test/unit/services/chatCompletionsService.streaming.test.ts (1 test) 96ms 278 MB heap used ✓ server/src/test/unit/internal-notifications/mentionParser.test.ts (28 tests) 2ms 283 MB heap used ❯ server/src/test/integration/internal-notifications/mentionNotifications.integration.test.ts (2 tests | 2 skipped) 19ms 286 MB heap used ↓ Mention notifications via TICKET_COMMENT_ADDED > creates notifications for mentioned users and excludes the author ↓ Mention notifications via TICKET_COMMENT_ADDED > does not notify client portal contact for internal comments ✓ server/src/test/unit/services/numberingService.test.ts (5 tests) 2ms 290 MB heap used ✓ ee/extensions/samples/ui-kit-showcase/test/scaffold.test.ts (8 tests) 1ms 293 MB heap used ❯ packages/ui/src/context/SchedulingContext.test.tsx (4 tests | 4 failed) 1ms 297 MB heap used × SchedulingContext > returns default callbacks when no provider is present 0ms → document is not defined × SchedulingContext > renders fallback alert element for agent schedule by default 0ms → document is not defined × SchedulingContext > shows a toast when launching time entry without provider 1ms → document is not defined × SchedulingContext > uses provider callbacks when SchedulingCallbackProvider is present 0ms → document is not defined stdout | server/src/test/integration/email/baseEmailServiceLogging.integration.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/email/baseEmailServiceLogging.integration.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/email/baseEmailServiceLogging.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/email/baseEmailServiceLogging.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/email/baseEmailServiceLogging.integration.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/email/baseEmailServiceLogging.integration.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/email/baseEmailServiceLogging.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/email/baseEmailServiceLogging.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/email/baseEmailServiceLogging.integration.test.ts > BaseEmailService → email_sending_logs CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/email/baseEmailServiceLogging.integration.test.ts > BaseEmailService → email_sending_logs Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/email/baseEmailServiceLogging.integration.test.ts > BaseEmailService → email_sending_logs CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/email/baseEmailServiceLogging.integration.test.ts > BaseEmailService → email_sending_logs Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/integration/email/baseEmailServiceLogging.integration.test.ts (2 tests | 2 skipped) 2ms 243 MB heap used ↓ BaseEmailService → email_sending_logs > successful send creates log entry with status sent ↓ BaseEmailService → email_sending_logs > failed send creates log entry with status failed and error_message ❯ server/src/test/integration/billing/invoiceStatusManagement.integration.test.ts (10 tests | 10 skipped) 1ms 246 MB heap used ↓ Invoice Status Management Integration > Credit Application Status Transitions > should set status to partially_applied when partial credit is applied ↓ Invoice Status Management Integration > Credit Application Status Transitions > should set status to paid when full credit is applied ↓ Invoice Status Management Integration > Credit Application Status Transitions > should accumulate multiple partial credits and update status accordingly ↓ Invoice Status Management Integration > Payment Recording Status Transitions > should set status to partially_applied when partial payment is recorded ↓ Invoice Status Management Integration > Payment Recording Status Transitions > should set status to paid when full payment is recorded ↓ Invoice Status Management Integration > Combined Payment and Credit Scenarios > should correctly calculate status with both payments and credits ↓ Invoice Status Management Integration > Refund Handling and Status Reversals > should transition from paid to partially_applied when partial refund is recorded ↓ Invoice Status Management Integration > Refund Handling and Status Reversals > should transition from paid to sent when full refund is recorded ↓ Invoice Status Management Integration > Status Transition Validation > should not allow payment on cancelled invoice ↓ Invoice Status Management Integration > Status Transition Validation > should not allow credit on draft invoice stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Contact Statistics (GET /api/v1/contacts/stats) > should return contact statistics Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Contact Statistics (GET /api/v1/contacts/stats) > should return contact statistics CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Contact Statistics (GET /api/v1/contacts/stats) > should return contact statistics CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Contact Statistics (GET /api/v1/contacts/stats) > should return contact statistics Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Contact Statistics (GET /api/v1/contacts/stats) > should return contact statistics CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Contact Statistics (GET /api/v1/contacts/stats) > should return contact statistics Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Permissions > should enforce write permissions for POST/PUT/DELETE CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Permissions > should enforce write permissions for POST/PUT/DELETE Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Permissions > should enforce write permissions for POST/PUT/DELETE CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Permissions > should enforce write permissions for POST/PUT/DELETE Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Permissions > should enforce read permissions for GET endpoints CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Permissions > should enforce read permissions for GET endpoints Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Permissions > should enforce read permissions for GET endpoints CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Permissions > should enforce read permissions for GET endpoints Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Multi-tenancy > should isolate contacts by tenant CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Multi-tenancy > should isolate contacts by tenant Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Multi-tenancy > should isolate contacts by tenant CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Multi-tenancy > should isolate contacts by tenant Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Error Handling > should handle database errors gracefully CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Error Handling > should handle database errors gracefully Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Error Handling > should handle database errors gracefully CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Error Handling > should handle database errors gracefully Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Error Handling > should handle invalid query parameters CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Error Handling > should handle invalid query parameters Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Error Handling > should handle invalid query parameters CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Error Handling > should handle invalid query parameters Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > List Contacts (GET /api/v1/contacts) > should filter by is_inactive status CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > List Contacts (GET /api/v1/contacts) > should filter by is_inactive status Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > List Contacts (GET /api/v1/contacts) > should filter by is_inactive status CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > List Contacts (GET /api/v1/contacts) > should filter by is_inactive status Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > List Contacts (GET /api/v1/contacts) > should filter by client_id CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > List Contacts (GET /api/v1/contacts) > should filter by client_id Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > List Contacts (GET /api/v1/contacts) > should filter by client_id CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > List Contacts (GET /api/v1/contacts) > should filter by client_id Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > List Contacts (GET /api/v1/contacts) > should support pagination parameters CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > List Contacts (GET /api/v1/contacts) > should support pagination parameters Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > List Contacts (GET /api/v1/contacts) > should support pagination parameters CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > List Contacts (GET /api/v1/contacts) > should support pagination parameters Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > List Contacts (GET /api/v1/contacts) > should sort contacts by name CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > List Contacts (GET /api/v1/contacts) > should sort contacts by name Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > List Contacts (GET /api/v1/contacts) > should sort contacts by name CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > List Contacts (GET /api/v1/contacts) > should sort contacts by name Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > List Contacts (GET /api/v1/contacts) > should list all contacts with default pagination CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > List Contacts (GET /api/v1/contacts) > should list all contacts with default pagination Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > List Contacts (GET /api/v1/contacts) > should list all contacts with default pagination CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > List Contacts (GET /api/v1/contacts) > should list all contacts with default pagination Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Export Contacts (GET /api/v1/contacts/export) > should export contacts as JSON CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Export Contacts (GET /api/v1/contacts/export) > should export contacts as JSON Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Export Contacts (GET /api/v1/contacts/export) > should export contacts as JSON CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Export Contacts (GET /api/v1/contacts/export) > should export contacts as JSON Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Export Contacts (GET /api/v1/contacts/export) > should export only active contacts by default CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Export Contacts (GET /api/v1/contacts/export) > should export only active contacts by default Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Export Contacts (GET /api/v1/contacts/export) > should export only active contacts by default CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Export Contacts (GET /api/v1/contacts/export) > should export only active contacts by default Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Export Contacts (GET /api/v1/contacts/export) > should export contacts as CSV CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Export Contacts (GET /api/v1/contacts/export) > should export contacts as CSV Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Export Contacts (GET /api/v1/contacts/export) > should export contacts as CSV CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Export Contacts (GET /api/v1/contacts/export) > should export contacts as CSV Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Search Contacts (GET /api/v1/contacts/search) > should search in specified fields CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Search Contacts (GET /api/v1/contacts/search) > should search in specified fields Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Search Contacts (GET /api/v1/contacts/search) > should search in specified fields CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Search Contacts (GET /api/v1/contacts/search) > should search in specified fields Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Search Contacts (GET /api/v1/contacts/search) > should limit search results CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Search Contacts (GET /api/v1/contacts/search) > should limit search results Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Search Contacts (GET /api/v1/contacts/search) > should limit search results CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Search Contacts (GET /api/v1/contacts/search) > should limit search results Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Search Contacts (GET /api/v1/contacts/search) > should search contacts by query CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Search Contacts (GET /api/v1/contacts/search) > should search contacts by query Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Search Contacts (GET /api/v1/contacts/search) > should search contacts by query CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Search Contacts (GET /api/v1/contacts/search) > should search contacts by query Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Update Contact (PUT /api/v1/contacts/:id) > should return 404 when updating non-existent contact CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Update Contact (PUT /api/v1/contacts/:id) > should return 404 when updating non-existent contact Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Update Contact (PUT /api/v1/contacts/:id) > should return 404 when updating non-existent contact CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Update Contact (PUT /api/v1/contacts/:id) > should return 404 when updating non-existent contact Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Update Contact (PUT /api/v1/contacts/:id) > should update a contact CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Update Contact (PUT /api/v1/contacts/:id) > should update a contact Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Update Contact (PUT /api/v1/contacts/:id) > should update a contact CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Update Contact (PUT /api/v1/contacts/:id) > should update a contact Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Get Contact (GET /api/v1/contacts/:id) > should return 404 for non-existent contact CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Get Contact (GET /api/v1/contacts/:id) > should return 404 for non-existent contact Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Get Contact (GET /api/v1/contacts/:id) > should return 404 for non-existent contact CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Get Contact (GET /api/v1/contacts/:id) > should return 404 for non-existent contact Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Get Contact (GET /api/v1/contacts/:id) > should not return contacts from other tenants CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Get Contact (GET /api/v1/contacts/:id) > should not return contacts from other tenants Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Get Contact (GET /api/v1/contacts/:id) > should not return contacts from other tenants CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Get Contact (GET /api/v1/contacts/:id) > should not return contacts from other tenants Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Get Contact (GET /api/v1/contacts/:id) > should retrieve a contact by ID CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Get Contact (GET /api/v1/contacts/:id) > should retrieve a contact by ID Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Get Contact (GET /api/v1/contacts/:id) > should retrieve a contact by ID CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Get Contact (GET /api/v1/contacts/:id) > should retrieve a contact by ID Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Delete Contact (DELETE /api/v1/contacts/:id) > should return 404 when deleting non-existent contact CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Delete Contact (DELETE /api/v1/contacts/:id) > should return 404 when deleting non-existent contact Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Delete Contact (DELETE /api/v1/contacts/:id) > should return 404 when deleting non-existent contact CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Delete Contact (DELETE /api/v1/contacts/:id) > should return 404 when deleting non-existent contact Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Delete Contact (DELETE /api/v1/contacts/:id) > should delete a contact CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Delete Contact (DELETE /api/v1/contacts/:id) > should delete a contact Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Delete Contact (DELETE /api/v1/contacts/:id) > should delete a contact CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Delete Contact (DELETE /api/v1/contacts/:id) > should delete a contact Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Create Contact (POST /api/v1/contacts) > should validate required fields CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Create Contact (POST /api/v1/contacts) > should validate required fields Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Create Contact (POST /api/v1/contacts) > should validate required fields CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Create Contact (POST /api/v1/contacts) > should validate required fields Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Create Contact (POST /api/v1/contacts) > should validate email format CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Create Contact (POST /api/v1/contacts) > should validate email format Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Create Contact (POST /api/v1/contacts) > should validate email format CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Create Contact (POST /api/v1/contacts) > should validate email format Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Create Contact (POST /api/v1/contacts) > should create a new contact CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Create Contact (POST /api/v1/contacts) > should create a new contact Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Create Contact (POST /api/v1/contacts) > should create a new contact CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > CRUD Operations > Create Contact (POST /api/v1/contacts) > should create a new contact Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Authentication > should reject invalid API key CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Authentication > should reject invalid API key Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Authentication > should reject invalid API key CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Authentication > should reject invalid API key Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Authentication > should require API key for all endpoints CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Authentication > should require API key for all endpoints Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Authentication > should require API key for all endpoints CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/contacts.e2e.test.ts > Contact API E2E Tests > Authentication > should require API key for all endpoints Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/e2e/api/contacts.e2e.test.ts (29 tests | 29 failed) 22ms 259 MB heap used × Contact API E2E Tests > Authentication > should require API key for all endpoints 1ms → × Contact API E2E Tests > Authentication > should reject invalid API key 1ms → × Contact API E2E Tests > CRUD Operations > Create Contact (POST /api/v1/contacts) > should create a new contact 1ms → × Contact API E2E Tests > CRUD Operations > Create Contact (POST /api/v1/contacts) > should validate required fields 1ms → × Contact API E2E Tests > CRUD Operations > Create Contact (POST /api/v1/contacts) > should validate email format 1ms → × Contact API E2E Tests > CRUD Operations > Get Contact (GET /api/v1/contacts/:id) > should retrieve a contact by ID 1ms → × Contact API E2E Tests > CRUD Operations > Get Contact (GET /api/v1/contacts/:id) > should return 404 for non-existent contact 1ms → × Contact API E2E Tests > CRUD Operations > Get Contact (GET /api/v1/contacts/:id) > should not return contacts from other tenants 1ms → × Contact API E2E Tests > CRUD Operations > Update Contact (PUT /api/v1/contacts/:id) > should update a contact 1ms → × Contact API E2E Tests > CRUD Operations > Update Contact (PUT /api/v1/contacts/:id) > should return 404 when updating non-existent contact 1ms → × Contact API E2E Tests > CRUD Operations > Delete Contact (DELETE /api/v1/contacts/:id) > should delete a contact 1ms → × Contact API E2E Tests > CRUD Operations > Delete Contact (DELETE /api/v1/contacts/:id) > should return 404 when deleting non-existent contact 1ms → × Contact API E2E Tests > List Contacts (GET /api/v1/contacts) > should list all contacts with default pagination 1ms → × Contact API E2E Tests > List Contacts (GET /api/v1/contacts) > should support pagination parameters 1ms → × Contact API E2E Tests > List Contacts (GET /api/v1/contacts) > should filter by client_id 1ms → × Contact API E2E Tests > List Contacts (GET /api/v1/contacts) > should filter by is_inactive status 1ms → × Contact API E2E Tests > List Contacts (GET /api/v1/contacts) > should sort contacts by name 1ms → × Contact API E2E Tests > Search Contacts (GET /api/v1/contacts/search) > should search contacts by query 1ms → × Contact API E2E Tests > Search Contacts (GET /api/v1/contacts/search) > should search in specified fields 1ms → × Contact API E2E Tests > Search Contacts (GET /api/v1/contacts/search) > should limit search results 1ms → × Contact API E2E Tests > Export Contacts (GET /api/v1/contacts/export) > should export contacts as CSV 1ms → × Contact API E2E Tests > Export Contacts (GET /api/v1/contacts/export) > should export contacts as JSON 1ms → × Contact API E2E Tests > Export Contacts (GET /api/v1/contacts/export) > should export only active contacts by default 1ms → × Contact API E2E Tests > Contact Statistics (GET /api/v1/contacts/stats) > should return contact statistics 1ms → × Contact API E2E Tests > Error Handling > should handle invalid query parameters 1ms → × Contact API E2E Tests > Error Handling > should handle database errors gracefully 1ms → × Contact API E2E Tests > Permissions > should enforce read permissions for GET endpoints 1ms → × Contact API E2E Tests > Permissions > should enforce write permissions for POST/PUT/DELETE 1ms → × Contact API E2E Tests > Multi-tenancy > should isolate contacts by tenant 1ms → ↓ server/src/test/integration/inboundEmailInApp.featureFlag.integration.test.ts (1 test | 1 skipped) ❯ server/src/lib/eventBus/index.hardTimeout.test.ts (1 test | 1 failed) 4ms 266 MB heap used × EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout 4ms → Failed to resolve entry for package "@alga-psa/event-schemas". The package may have incorrect main/module/exports specified in its package.json. stdout | server/src/test/integration/internal-notifications/notificationCrud.integration.test.ts > Internal notification CRUD (integration) Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/internal-notifications/notificationCrud.integration.test.ts > Internal notification CRUD (integration) CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/internal-notifications/notificationCrud.integration.test.ts > Internal notification CRUD (integration) CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/internal-notifications/notificationCrud.integration.test.ts > Internal notification CRUD (integration) Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/internal-notifications/notificationCrud.integration.test.ts > Internal notification CRUD (integration) CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/internal-notifications/notificationCrud.integration.test.ts > Internal notification CRUD (integration) Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/internal-notifications/notificationCrud.integration.test.ts > Internal notification CRUD (integration) CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/internal-notifications/notificationCrud.integration.test.ts > Internal notification CRUD (integration) Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/integration/internal-notifications/notificationCrud.integration.test.ts (6 tests | 6 skipped) 8ms 275 MB heap used ↓ Internal notification CRUD (integration) > creates notification with metadata and default locale ↓ Internal notification CRUD (integration) > supports locale preference during creation ↓ Internal notification CRUD (integration) > paginates and filters notifications ↓ Internal notification CRUD (integration) > returns unread counts with category breakdown ↓ Internal notification CRUD (integration) > marks notification as read with timestamp and broadcast ↓ Internal notification CRUD (integration) > marks all notifications as read and soft deletes ✓ server/src/test/unit/workflowBundleCli.unit.test.ts (2 tests) 4ms 279 MB heap used ✓ server/src/test/unit/readAssistantContentFromSse.test.ts (1 test) 1ms 281 MB heap used ✓ packages/billing/tests/draftContractsActions.test.ts (6 tests) 19ms 288 MB heap used ✓ packages/billing/src/components/invoice-designer/preview/previewStatus.test.ts (5 tests) 0ms 291 MB heap used ✓ packages/billing/src/components/invoice-designer/preview/previewSessionState.test.ts (6 tests) 1ms 298 MB heap used ✓ sdk/samples/component/scheduler-demo/tests/handler.test.ts (6 tests) 1ms 302 MB heap used ✓ server/src/test/unit/api/chatExecute.route.gating.test.ts (1 test) 4ms 251 MB heap used ❯ packages/msp-composition/src/scheduling/MspSchedulingProvider.test.tsx (2 tests | 2 failed) 1ms 257 MB heap used × MspSchedulingProvider > provides renderAgentSchedule that returns AgentScheduleView 0ms → document is not defined × MspSchedulingProvider > provides launchTimeEntry that calls launchTimeEntryForWorkItem 0ms → document is not defined ✓ packages/scheduling/tests/scheduleEntry.test.ts (16 tests) 4ms 266 MB heap used ✓ packages/billing/src/components/invoice-designer/DesignerShell.fitSection.test.ts (11 tests) 1ms 276 MB heap used 2026-02-12T19:54:19.842538Z WARN temporalio_sdk_core::worker::heartbeat: Worker heartbeating configured for runtime, but server version does not support it. 2026-02-12T19:54:20.240112Z WARN temporalio_sdk_core::worker::heartbeat: Worker heartbeating configured for runtime, but server version does not support it. 2026-02-12T19:54:20.597915Z WARN temporalio_sdk_core::worker::heartbeat: Worker heartbeating configured for runtime, but server version does not support it. ✓ ee/temporal-workflows/src/workflows/portal-domains/__tests__/registration.workflow.integration.test.ts (3 tests) 1776ms 430 MB heap used ✓ portalDomainRegistrationWorkflow > marks the domain as certificate_failed when ACME registration fails 343ms ✓ portalDomainRegistrationWorkflow > moves the domain to deploying after applying resources 1062ms ✓ portalDomainRegistrationWorkflow > retries after a failure and succeeds on the next attempt 371ms stdout | server/src/test/integration/accounting/exportDashboard.integration.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/accounting/exportDashboard.integration.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/accounting/exportDashboard.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/accounting/exportDashboard.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/accounting/exportDashboard.integration.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/accounting/exportDashboard.integration.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/accounting/exportDashboard.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/accounting/exportDashboard.integration.test.ts Retrieved secret 'db_password_server' from configured provider. ✓ ee/server/src/__tests__/unit/schedulerHostApi.unit.test.ts (72 tests) 6ms 424 MB heap used ✓ ee/server/src/lib/extensions/__tests__/manifest-v2.schema.test.ts (5 tests) 1ms 433 MB heap used stdout | server/src/test/integration/emailProviderCreation.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/emailProviderCreation.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/emailProviderCreation.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/emailProviderCreation.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/emailProviderCreation.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/emailProviderCreation.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/emailProviderCreation.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/emailProviderCreation.test.ts Retrieved secret 'db_password_server' from configured provider. ✓ packages/billing/src/components/invoice-designer/state/designerStore.size.test.ts (4 tests) 4ms 294 MB heap used stdout | shared/lib/utils/contentConversion.test.ts > convertHtmlToBlockNote > should handle linked images (image inside anchor) Linked Image Result: { "type": "link", "href": "https://google.com", "content": [ { "type": "text", "text": "🖼️ Logo", "styles": {} } ] } ✓ shared/lib/utils/contentConversion.test.ts (14 tests) 7ms 300 MB heap used ✓ server/src/test/unit/mention-detection.test.ts (12 tests) 1ms 304 MB heap used ✓ packages/billing/src/components/invoice-designer/canvas/DesignCanvas.previewModel.test.ts (5 tests) 1ms 313 MB heap used ❯ server/src/test/infrastructure/billing/invoices/clientBillingCycle.test.ts (1 test | 1 skipped) 2ms 319 MB heap used ↓ Client Billing Cycle Creation > creates a monthly billing cycle if none exists stdout | server/src/test/integration/emailProviderDatabase.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/emailProviderDatabase.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/emailProviderDatabase.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/emailProviderDatabase.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/emailProviderDatabase.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/emailProviderDatabase.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/emailProviderDatabase.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/emailProviderDatabase.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/emailProviderDatabase.test.ts > Email Provider Database Integration Tests CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/emailProviderDatabase.test.ts > Email Provider Database Integration Tests Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/emailProviderDatabase.test.ts > Email Provider Database Integration Tests CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/emailProviderDatabase.test.ts > Email Provider Database Integration Tests Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/integration/emailProviderDatabase.test.ts (6 tests | 6 skipped) 1ms 337 MB heap used ↓ Email Provider Database Integration Tests > Google Provider Database Operations > should create a Google provider record in the database ↓ Email Provider Database Integration Tests > Google Provider Database Operations > should handle Google Workspace email addresses ↓ Email Provider Database Integration Tests > Google Provider Database Operations > should update an existing Google provider ↓ Email Provider Database Integration Tests > Google Provider Database Operations > should list all Google providers for a tenant ↓ Email Provider Database Integration Tests > Google Provider Database Operations > should handle provider creation with all optional fields ↓ Email Provider Database Integration Tests > Google Provider Database Operations > should enforce database constraints stdout | server/src/test/integration/surveyEmailTemplates.integration.test.ts > Survey email templates Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/surveyEmailTemplates.integration.test.ts > Survey email templates CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/surveyEmailTemplates.integration.test.ts > Survey email templates CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/surveyEmailTemplates.integration.test.ts > Survey email templates Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/surveyEmailTemplates.integration.test.ts > Survey email templates CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/surveyEmailTemplates.integration.test.ts > Survey email templates Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/integration/surveyEmailTemplates.integration.test.ts (2 tests | 2 skipped) 2ms 342 MB heap used ↓ Survey email templates > registers system templates for each supported locale ↓ Survey email templates > renders locale-specific content and falls back to English ✓ packages/billing/src/components/invoice-designer/state/designerStore.layoutMode.test.ts (2 tests) 3ms 354 MB heap used ✓ server/src/test/unit/resendWebhookEvents.test.ts (8 tests) 2ms 300 MB heap used stdout | server/src/test/integration/accounting/invoiceSelection.integration.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/accounting/invoiceSelection.integration.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/accounting/invoiceSelection.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/accounting/invoiceSelection.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/accounting/invoiceSelection.integration.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/accounting/invoiceSelection.integration.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/accounting/invoiceSelection.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/accounting/invoiceSelection.integration.test.ts Retrieved secret 'db_password_server' from configured provider. ✓ server/src/test/unit/imports/FieldMapper.test.ts (2 tests) 1ms 333 MB heap used stdout | server/src/test/unit/db/workDate.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/db/workDate.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/db/workDate.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/db/workDate.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/db/workDate.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/db/workDate.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/db/workDate.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/db/workDate.test.ts Retrieved secret 'db_password_server' from configured provider. ✓ server/src/test/unit/db/workDate.test.ts (1 test) 3ms 339 MB heap used stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts > Email Settings OAuth Flow Tests 🏗️ Initializing Email Settings Test Fixture (one-time setup)... 📊 Setting up database and services... 🚀 Initializing E2E Test Context... 🔧 Set E2E environment variables: { DB_HOST: 'localhost', DB_PORT: '5433', DB_NAME_SERVER: 'server_test', DB_USER_ADMIN: 'postgres', PGBOUNCER_HOST: 'localhost', PGBOUNCER_PORT: '6434', REDIS_HOST: 'localhost', REDIS_PORT: '6380', EMAIL_HOST: 'localhost', EMAIL_PORT: '1025' } stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts > Email Settings OAuth Flow Tests CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts > Email Settings OAuth Flow Tests Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts > Email Settings OAuth Flow Tests CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts > Email Settings OAuth Flow Tests Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts > Email Settings OAuth Flow Tests 🧹 Final test fixture cleanup... ❯ server/src/test/e2e/email-settings/oauth-flow.test.ts (7 tests | 7 skipped) 3ms 352 MB heap used ↓ Email Settings OAuth Flow Tests > Microsoft OAuth Flow > should complete OAuth flow and store tokens ↓ Email Settings OAuth Flow Tests > Microsoft OAuth Flow > should handle OAuth error scenarios ↓ Email Settings OAuth Flow Tests > Microsoft OAuth Flow > should handle Microsoft webhook validation token ↓ Email Settings OAuth Flow Tests > Google OAuth Flow > should complete OAuth flow with Pub/Sub setup ↓ Email Settings OAuth Flow Tests > Google OAuth Flow > should handle expired refresh token ↓ Email Settings OAuth Flow Tests > Token Storage and Encryption > should store tokens securely in database ↓ Email Settings OAuth Flow Tests > State Parameter Validation > should validate state parameter in OAuth callback stdout | shared/services/email/__tests__/EmailWebhookMaintenanceService.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | shared/services/email/__tests__/EmailWebhookMaintenanceService.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | shared/services/email/__tests__/EmailWebhookMaintenanceService.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | shared/services/email/__tests__/EmailWebhookMaintenanceService.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | shared/services/email/__tests__/EmailWebhookMaintenanceService.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | shared/services/email/__tests__/EmailWebhookMaintenanceService.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | shared/services/email/__tests__/EmailWebhookMaintenanceService.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | shared/services/email/__tests__/EmailWebhookMaintenanceService.test.ts Retrieved secret 'db_password_server' from configured provider. ❯ shared/services/email/__tests__/EmailWebhookMaintenanceService.test.ts (3 tests | 1 failed) 2ms 362 MB heap used ✓ EmailWebhookMaintenanceService > should find candidates and renew expired subscription 0ms × EmailWebhookMaintenanceService > should recreate subscription if renewal fails with 404 1ms → expected "spy" to be called with arguments: [ 'https://api.example.com/webhook' ] Number of calls: 0 ✓ EmailWebhookMaintenanceService > should handle unexpected errors gracefully 0ms ✓ packages/auth/src/lib/session.test.ts (6 tests) 3ms 350 MB heap used stdout | server/src/test/integration/emailProviderErrorMessages.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/emailProviderErrorMessages.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/emailProviderErrorMessages.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/emailProviderErrorMessages.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/emailProviderErrorMessages.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/emailProviderErrorMessages.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/emailProviderErrorMessages.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/emailProviderErrorMessages.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/emailProviderErrorMessages.test.ts > Email Provider Error Messages CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/emailProviderErrorMessages.test.ts > Email Provider Error Messages Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/emailProviderErrorMessages.test.ts > Email Provider Error Messages CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/emailProviderErrorMessages.test.ts > Email Provider Error Messages Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/integration/emailProviderErrorMessages.test.ts (10 tests | 10 skipped) 1ms 360 MB heap used ↓ Email Provider Error Messages > User-Friendly Error Messages > should return clear error when provider name is missing ↓ Email Provider Error Messages > User-Friendly Error Messages > should return clear error when email is invalid ↓ Email Provider Error Messages > User-Friendly Error Messages > should return clear error when Google Client ID is missing ↓ Email Provider Error Messages > User-Friendly Error Messages > should return multiple errors in a clear format ↓ Email Provider Error Messages > User-Friendly Error Messages > should return helpful error for invalid provider type ↓ Email Provider Error Messages > User-Friendly Error Messages > should return clear error for provider name that is too long ↓ Email Provider Error Messages > User-Friendly Error Messages > should return helpful error for invalid Microsoft tenant ID ↓ Email Provider Error Messages > User-Friendly Error Messages > should return clear error for invalid max emails per sync ↓ Email Provider Error Messages > User-Friendly Error Messages > should return helpful hint for Google Client ID format ↓ Email Provider Error Messages > User-Friendly Error Messages > should successfully create provider when all fields are valid stdout | server/src/test/unit/templateRenderer.test.tsx Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/templateRenderer.test.tsx CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/templateRenderer.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/templateRenderer.test.tsx Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/templateRenderer.test.tsx CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/templateRenderer.test.tsx Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/templateRenderer.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/templateRenderer.test.tsx Retrieved secret 'db_password_server' from configured provider. ✓ tools/nx-tests/nxCache.test.ts (2 tests) 3726ms 356 MB heap used ✓ nx caching > reuses the local computation cache for repeated builds 732ms ✓ nx caching > caches @alga-psa/core builds when unchanged 2994ms ❯ ee/temporal-workflows/src/activities/__tests__/email-activities-simple.test.ts (24 tests | 17 failed) 916ms 365 MB heap used × Email Activities - Simple Tests > generateTemporaryPassword > should generate password with default length of 12 0ms → expected Promise{…} to have property 'length' × Email Activities - Simple Tests > generateTemporaryPassword > should generate password with custom length 0ms → expected Promise{…} to have property 'length' ✓ Email Activities - Simple Tests > generateTemporaryPassword > should generate different passwords each time 0ms × Email Activities - Simple Tests > generateTemporaryPassword > should contain at least one character from each category 0ms → .toMatch() expects to receive a string, but got object × Email Activities - Simple Tests > generateTemporaryPassword > should not contain ambiguous characters 0ms → .toMatch() expects to receive a string, but got object × Email Activities - Simple Tests > generateTemporaryPassword > should handle minimum length of 4 0ms → expected Promise{…} to have property 'length' ✓ Email Activities - Simple Tests > generateTemporaryPassword > should generate secure passwords with high entropy 0ms × Email Activities - Simple Tests > MockEmailService > should send emails successfully 102ms → Cannot read properties of undefined (reading 'info') ✓ Email Activities - Simple Tests > MockEmailService > should validate email addresses correctly 0ms × Email Activities - Simple Tests > MockEmailService > should track sent emails for testing 101ms → Cannot read properties of undefined (reading 'info') × Email Activities - Simple Tests > MockEmailService > should filter emails by recipient 102ms → Cannot read properties of undefined (reading 'info') ✓ Email Activities - Simple Tests > MockEmailService > should simulate failures when configured 101ms × Email Activities - Simple Tests > MockEmailService > should handle invalid email addresses 101ms → Cannot read properties of undefined (reading 'info') × Email Activities - Simple Tests > MockEmailService > should handle multiple recipients 101ms → Cannot read properties of undefined (reading 'info') ✓ Email Activities - Simple Tests > MockEmailService > should throw error when no valid recipients 101ms × Email Activities - Simple Tests > MockEmailService > should support email service configuration 0ms → expected Promise{…} to be an instance of MockEmailService ✓ Email Activities - Simple Tests > MockEmailService > should return email templates for testing 0ms ✓ Email Activities - Simple Tests > MockEmailService > should return null for unknown templates 0ms × Email Activities - Simple Tests > MockEmailService > should support clearing sent emails 101ms → Cannot read properties of undefined (reading 'info') × Email Activities - Simple Tests > MockEmailService > should handle delay configuration 102ms → Cannot read properties of undefined (reading 'info') × Email Activities - Simple Tests > Email Service Factory > should create mock service by default 0ms → expected Promise{…} to be an instance of MockEmailService × Email Activities - Simple Tests > Email Service Factory > should create mock service when explicitly requested 0ms → expected Promise{…} to be an instance of MockEmailService × Email Activities - Simple Tests > Email Service Factory > should throw error for unknown providers 0ms → expected [Function] to throw an error × Email Activities - Simple Tests > Email Service Factory > should pass options to mock service 0ms → expected Promise{…} to be an instance of MockEmailService ✓ tools/nx-tests/moduleBoundaries.test.ts (2 tests) 6ms 382 MB heap used ✓ packages/client-portal/src/actions/client-portal-actions/client-tickets.ticketOrigin.test.ts (4 tests) 15ms 392 MB heap used ❯ packages/core/src/index.test.ts (1 test | 1 failed) 48ms 303 MB heap used × @alga-psa/core public exports > exports logger, secrets, events, and encryption APIs 48ms → expected 'undefined' to be 'function' // Object.is equality ✓ server/src/test/integration/emailProviderIntegration.test.ts (11 tests) 5ms 313 MB heap used stdout | server/src/test/unit/calendar/CalendarProviderEncryption.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/calendar/CalendarProviderEncryption.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/calendar/CalendarProviderEncryption.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/calendar/CalendarProviderEncryption.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/calendar/CalendarProviderEncryption.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/calendar/CalendarProviderEncryption.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/calendar/CalendarProviderEncryption.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/calendar/CalendarProviderEncryption.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/calendar/CalendarProviderEncryption.test.ts > CalendarProviderService encryption helpers > encrypts and decrypts Microsoft provider credentials CompositeSecretProvider: app secret 'calendar_oauth_encryption_key' not found in any provider stdout | server/src/test/unit/calendar/CalendarProviderEncryption.test.ts > CalendarProviderService encryption helpers > encrypts and decrypts Microsoft provider credentials Secret 'calendar_oauth_encryption_key' not found via provider, checking env var 'CALENDAR_OAUTH_ENCRYPTION_KEY'. ✓ server/src/test/unit/calendar/CalendarProviderEncryption.test.ts (3 tests) 1ms 321 MB heap used stdout | server/src/test/integration/email/emailLogActions.getEmailLogs.integration.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/email/emailLogActions.getEmailLogs.integration.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/email/emailLogActions.getEmailLogs.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/email/emailLogActions.getEmailLogs.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/email/emailLogActions.getEmailLogs.integration.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/email/emailLogActions.getEmailLogs.integration.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/email/emailLogActions.getEmailLogs.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/email/emailLogActions.getEmailLogs.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/email/emailLogActions.getEmailLogs.integration.test.ts > emailLogActions.getEmailLogs CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/email/emailLogActions.getEmailLogs.integration.test.ts > emailLogActions.getEmailLogs Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/email/emailLogActions.getEmailLogs.integration.test.ts > emailLogActions.getEmailLogs CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/email/emailLogActions.getEmailLogs.integration.test.ts > emailLogActions.getEmailLogs Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/integration/email/emailLogActions.getEmailLogs.integration.test.ts (6 tests | 6 skipped) 2ms 334 MB heap used ↓ emailLogActions.getEmailLogs > returns paginated results ↓ emailLogActions.getEmailLogs > filters by date range when provided ↓ emailLogActions.getEmailLogs > treats date-only endDate as inclusive end of day ↓ emailLogActions.getEmailLogs > filters by status when provided ↓ emailLogActions.getEmailLogs > filters by recipient email when provided ↓ emailLogActions.getEmailLogs > supports sorting by sent_at ascending/descending ❯ server/src/test/integration/onboardingProgressSubsteps.integration.test.ts (1 test | 1 failed) 1ms 339 MB heap used × getOnboardingProgressAction (substeps) > returns portal + email steps with substeps 1ms → Cannot find package '@alga-psa/onboarding/actions' imported from '/Users/roberisaacs/alga-psa.worktrees/codex/feature-invoice-designer/server/src/test/integration/onboardingProgressSubsteps.integration.test.ts' ✓ ee/server/src/__tests__/unit/routeParams.resolveInstallId.test.ts (3 tests) 0ms 343 MB heap used ✓ packages/msp-composition/src/packageDependencies.test.ts (1 test) 0ms 347 MB heap used ✓ packages/tickets/src/lib/__tests__/ticketOrigin.test.ts (5 tests) 0ms 354 MB heap used ✓ packages/tickets/src/components/ticket/TicketDetails.originBadge.contract.test.ts (3 tests) 2ms 362 MB heap used ❯ packages/tickets/src/components/ticket/AgentScheduleDrawer.test.tsx (2 tests | 2 failed) 1ms 317 MB heap used × AgentScheduleDrawer > renders calendar when provider is present 0ms → document is not defined × AgentScheduleDrawer > shows fallback alert when no provider is present 1ms → document is not defined ❯ server/src/test/integration/citusTenantFilterEmailProviders.integration.test.ts (2 tests | 2 failed) 2ms 321 MB heap used × Citus safety: tenant-scoped updates on distributed tables > scopes email_providers updates by tenant in Microsoft webhook route 1ms → expected 'export { GET, POST } from \'@alga-psa…' to contain '.where({ id: row.id, tenant: row.tena…' × Citus safety: tenant-scoped updates on distributed tables > scopes email_providers updates by tenant in Google webhook route 1ms → expected 'export { POST } from \'@alga-psa/inte…' to contain '.where({ id: provider.id, tenant: pro…' stdout | server/src/test/integration/surveyTokenService.integration.test.ts > Survey Token Service integration Initializing composite secret provider system Building composite secret provider. Read chain: [env, filesystem], Write provider: filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/surveyTokenService.integration.test.ts > Survey Token Service integration CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/surveyTokenService.integration.test.ts > Survey Token Service integration CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/surveyTokenService.integration.test.ts > Survey Token Service integration Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/surveyTokenService.integration.test.ts > Survey Token Service integration CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/surveyTokenService.integration.test.ts > Survey Token Service integration Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/integration/surveyTokenService.integration.test.ts (2 tests | 2 failed) 2ms 327 MB heap used × Survey Token Service integration > resolves invitation metadata for a valid survey token 0ms → × Survey Token Service integration > throws when the survey token has expired 0ms → ✓ packages/projects/src/lib/timeEntryContext.test.ts (1 test) 0ms 336 MB heap used ✓ server/src/test/unit/billing/billingCycleAnchors.validationMessages.test.ts (3 tests) 1ms 341 MB heap used ✓ packages/billing/tests/contractsTabs.test.ts (5 tests) 0ms 345 MB heap used stdout | server/src/test/integration/accounting/batchLifecycle.integration.test.ts Initializing composite secret provider system Building composite secret provider. Read chain: [env, filesystem], Write provider: filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/accounting/batchLifecycle.integration.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/accounting/batchLifecycle.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/accounting/batchLifecycle.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/accounting/batchLifecycle.integration.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/accounting/batchLifecycle.integration.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/accounting/batchLifecycle.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/accounting/batchLifecycle.integration.test.ts Retrieved secret 'db_password_server' from configured provider. ✓ ee/server/src/__tests__/unit/invoicingInternalApi.unit.test.ts (1 test) 4ms 375 MB heap used stdout | server/src/test/e2e/workflowRuntimeV2.e2e.test.ts Initializing composite secret provider system Building composite secret provider. Read chain: [env, filesystem], Write provider: filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/e2e/workflowRuntimeV2.e2e.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/e2e/workflowRuntimeV2.e2e.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/workflowRuntimeV2.e2e.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/workflowRuntimeV2.e2e.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/workflowRuntimeV2.e2e.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/workflowRuntimeV2.e2e.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/workflowRuntimeV2.e2e.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should assert successful responses Initializing composite secret provider system Building composite secret provider. Read chain: [env, filesystem], Write provider: filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should assert successful responses CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should assert successful responses CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should assert successful responses Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should assert successful responses CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should assert successful responses Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should assert error responses CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should assert error responses Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should assert error responses CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should assert error responses Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should build query strings correctly CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should build query strings correctly Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should build query strings correctly CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should build query strings correctly Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Contact Test Data Factory > should create a single contact CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Contact Test Data Factory > should create a single contact Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Contact Test Data Factory > should create a single contact CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Contact Test Data Factory > should create a single contact Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Contact Test Data Factory > should create multiple contacts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Contact Test Data Factory > should create multiple contacts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Contact Test Data Factory > should create multiple contacts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Contact Test Data Factory > should create multiple contacts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Contact Test Data Factory > should generate random contact data CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Contact Test Data Factory > should generate random contact data Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Contact Test Data Factory > should generate random contact data CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Contact Test Data Factory > should generate random contact data Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Client > should be able to make requests CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Client > should be able to make requests Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Client > should be able to make requests CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Client > should be able to make requests Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Client > should have API key configured CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Client > should have API key configured Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Client > should have API key configured CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Client > should have API key configured Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created a user CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created a user Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created a user CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created a user Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created a tenant CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created a tenant Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created a tenant CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created a tenant Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have a valid database connection CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have a valid database connection Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have a valid database connection CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have a valid database connection Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created an API key CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created an API key Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created an API key CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created an API key Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should create a complete test environment CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should create a complete test environment Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should create a complete test environment CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should create a complete test environment Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/e2e/utils/utilities.test.ts (13 tests | 13 failed) 792ms 381 MB heap used × E2E Test Utilities > Test Environment Setup > should create a complete test environment 39ms → no such database: test_database × E2E Test Utilities > Test Environment Setup > should have a valid database connection 52ms → no such database: test_database × E2E Test Utilities > Test Environment Setup > should have created a tenant 38ms → no such database: test_database × E2E Test Utilities > Test Environment Setup > should have created a user 52ms → no such database: test_database × E2E Test Utilities > Test Environment Setup > should have created an API key 30ms → no such database: test_database × E2E Test Utilities > Contact Test Data Factory > should generate random contact data 42ms → no such database: test_database × E2E Test Utilities > Contact Test Data Factory > should create a single contact 56ms → no such database: test_database × E2E Test Utilities > Contact Test Data Factory > should create multiple contacts 49ms → no such database: test_database × E2E Test Utilities > API Test Helpers > should build query strings correctly 50ms → no such database: test_database × E2E Test Utilities > API Test Helpers > should assert successful responses 215ms → no such database: test_database × E2E Test Utilities > API Test Helpers > should assert error responses 80ms → no such database: test_database × E2E Test Utilities > API Client > should have API key configured 44ms → no such database: test_database × E2E Test Utilities > API Client > should be able to make requests 45ms → no such database: test_database ✓ ee/server/src/lib/extensions/__tests__/runner/backend.test.ts (4 tests) 11ms 388 MB heap used stdout | server/src/test/unit/portalDomainSessionOtt.test.ts Initializing composite secret provider system Building composite secret provider. Read chain: [env, filesystem], Write provider: filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/portalDomainSessionOtt.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/portalDomainSessionOtt.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/portalDomainSessionOtt.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/portalDomainSessionOtt.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/portalDomainSessionOtt.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/portalDomainSessionOtt.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/portalDomainSessionOtt.test.ts Retrieved secret 'db_password_server' from configured provider. ✓ server/src/test/unit/portalDomainSessionOtt.test.ts (5 tests) 3ms 345 MB heap used ✓ packages/projects/tests/packageDependencies.test.ts (1 test) 0ms 350 MB heap used stdout | server/src/test/unit/documentPreviewGenerator.test.ts > generateDocumentPreviews > creates thumbnail and preview uploads for large images [generateDocumentPreviews] Generating previews for document doc-2 (image/png) stdout | server/src/test/unit/documentPreviewGenerator.test.ts > generateDocumentPreviews > creates thumbnail and preview uploads for large images [generateImagePreviews] Image dimensions: 1200x900 stdout | server/src/test/unit/documentPreviewGenerator.test.ts > generateDocumentPreviews > creates thumbnail and preview uploads for large images [generateImagePreviews] Thumbnail generated: thumb-1 stdout | server/src/test/unit/documentPreviewGenerator.test.ts > generateDocumentPreviews > creates thumbnail and preview uploads for large images [generateImagePreviews] Preview generated: preview-2 stdout | server/src/test/unit/documentPreviewGenerator.test.ts > generateDocumentPreviews > skips storage uploads for unsupported mime types [generateDocumentPreviews] Generating previews for document doc-1 (text/plain) [generateDocumentPreviews] Unsupported file type: text/plain ✓ server/src/test/unit/documentPreviewGenerator.test.ts (2 tests) 2ms 373 MB heap used ✓ packages/billing/src/components/invoice-designer/canvas/DesignCanvas.selectionState.test.ts (9 tests) 1ms 379 MB heap used stdout | server/src/test/e2e/email-processing.test.ts Initializing composite secret provider system Building composite secret provider. Read chain: [env, filesystem], Write provider: filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/e2e/email-processing.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/e2e/email-processing.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/email-processing.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/email-processing.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/email-processing.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/email-processing.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/email-processing.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/email-processing.test.ts > Email Processing E2E Tests 🧪 Initializing persistent E2E test context... 🚀 Initializing E2E Test Context... 🔧 Set E2E environment variables: { DB_HOST: 'localhost', DB_PORT: '5433', DB_NAME_SERVER: 'server_test', DB_USER_ADMIN: 'postgres', PGBOUNCER_HOST: 'localhost', PGBOUNCER_PORT: '6434', REDIS_HOST: 'localhost', REDIS_PORT: '6380', EMAIL_HOST: 'localhost', EMAIL_PORT: '1025' } stdout | server/src/test/e2e/email-processing.test.ts > Email Processing E2E Tests CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/email-processing.test.ts > Email Processing E2E Tests Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/email-processing.test.ts > Email Processing E2E Tests CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/email-processing.test.ts > Email Processing E2E Tests Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/email-processing.test.ts > Email Processing E2E Tests 🧹 Cleaning up persistent E2E test context... ❯ server/src/test/e2e/email-processing.test.ts (5 tests | 5 skipped) 2ms 350 MB heap used ↓ Email Processing E2E Tests > Basic Email Ingestion > should process a simple email and create a ticket ↓ Email Processing E2E Tests > Basic Email Ingestion > should handle emails with attachments ↓ Email Processing E2E Tests > Email Threading > should properly thread email replies ↓ Email Processing E2E Tests > Client Matching > should match emails to existing clients ↓ Email Processing E2E Tests > Client Matching > should handle unknown email addresses with manual fallback ✓ tools/nx-tests/nxAffected.test.ts (2 tests) 621ms 357 MB heap used ✓ nx affected > includes @alga-psa/clients when client code changes 334ms ↓ server/src/test/integration/workflowWorkerV2.inboundEmailSmoke.integration.test.ts (1 test | 1 skipped) ✓ server/src/test/unit/enterpriseAliasEnvSwitch.unit.test.ts (2 tests) 197ms 369 MB heap used ❯ server/src/test/integration/internal-notifications/eventSubscribers.integration.test.ts (14 tests | 14 skipped) 2ms 375 MB heap used ↓ internal notification event subscriber registration > subscribes to all expected event types on the internal channel ↓ internal notification event handling > creates notification for ticket assignment events targeting the assignee ↓ internal notification event handling > creates notifications for ticket additional agent assignments (agent, primary assignee, and client) ↓ internal notification event handling > does not invoke notification creation for events without handlers ↓ internal notification event handling > creates notifications for ticket created events for assignee and portal contact ↓ internal notification event handling > creates status change notifications for ticket updated events ↓ internal notification event handling > creates notifications for ticket closed events including client portal user ↓ internal notification event handling > creates project created notifications for assigned user ↓ internal notification event handling > creates project assigned notifications ↓ internal notification event handling > creates project task assigned notifications ↓ internal notification event handling > creates project task additional agent notifications for the new agent and the primary assignee ↓ internal notification event handling > creates invoice generated notifications ↓ internal notification event handling > creates message sent notifications for recipients ↓ internal notification event handling > creates document mention notifications ❯ server/src/test/unit/clientContractActions.overlapExclusive.test.ts (3 tests | 3 failed) 2ms 380 MB heap used × Client contract overlap validation ([start, end) semantics) > does not treat touching boundaries as overlap (start == invoiced period end) 0ms → Missing "./models/clientContract" specifier in "@alga-psa/clients" package × Client contract overlap validation ([start, end) semantics) > does not treat touching boundaries as overlap (end exclusive == invoiced period start) 1ms → Missing "./models/clientContract" specifier in "@alga-psa/clients" package × Client contract overlap validation ([start, end) semantics) > rejects true overlaps with an invoiced period 0ms → Missing "./models/clientContract" specifier in "@alga-psa/clients" package ✓ server/src/test/unit/RightSidebar.streaming.test.tsx (1 test) 486ms 87 MB heap used ✓ RightSidebar (streaming) > renders streaming Chat and posts to the streaming completions endpoint 485ms ❯ packages/billing/tests/contractWizardResume.test.tsx (14 tests | 14 failed) 52ms 118 MB heap used × ContractWizard resume behavior > starts at Step 1 (Contract Basics) when opened (T033) 1ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 1 shows pre-populated client selection from draft (T034) 1ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 1 shows pre-populated contract name from draft (T035) 1ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 1 shows pre-populated dates from draft (T036) 2ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 2 (Fixed Fee) shows pre-populated services from draft (T037) 2ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 3 (Products) shows pre-populated products from draft (T038) 1ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 4 (Hourly) shows pre-populated hourly services from draft (T039) 1ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 5 (Usage) shows pre-populated usage services from draft (T040) 1ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 6 (Review) shows complete draft data for review (T041) 2ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > clicking Save Draft in resumed wizard updates existing draft (T042) 2ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > save draft does not create a duplicate contract (T043) 2ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > save draft preserves the original contract_id (T044) 32ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > completing resumed wizard sets contract status to 'active' (T045) 1ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > completing resumed wizard sets is_active to true (T046) 2ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: ✓ packages/projects/tests/projectInfoDrawer.test.tsx (1 test) 43ms 77 MB heap used stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.poBanner.ui.test.tsx Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.poBanner.ui.test.tsx CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.poBanner.ui.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.poBanner.ui.test.tsx Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.poBanner.ui.test.tsx CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.poBanner.ui.test.tsx Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.poBanner.ui.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.poBanner.ui.test.tsx Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/unit/components/ExperimentalFeaturesSettings.test.tsx (9 tests | 7 failed) 4053ms 113 MB heap used × ExperimentalFeaturesSettings > shows 'AI Assistant' name and description 1003ms → Found multiple elements with the text: AI Assistant Here are the matching elements: Ignored nodes: comments, script, style  AI Assistant  Ignored nodes: comments, script, style  AI Assistant  Ignored nodes: comments, script, style  AI Assistant  Ignored nodes: comments, script, style  AI Assistant  Ignored nodes: comments, script, style  AI Assistant  Ignored nodes: comments, script, style  AI Assistant  Ignored nodes: comments, script, style  AI Assistant  Ignored nodes: comments, script, style  AI Assistant  Ignored nodes: comments, script, style  AI Assistant  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
    
 ← Back to Projects 
  PRJ-100   Test Project  
        Save as Template   Materials      Edit       Client:   Client One 

    Contact:   N/A 

    Budget:    0.0  of  0.0  hours        
    Experimental Features   Enable or disable experimental features for your tenant. 

 
  svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 border-l-4 border-l-warning border-y-0 border-r-0 text-[rgb(var(--color-text-800))] [&>svg]:text-warning bg-warning/10" role="alert" >  
    
 ← Back to Projects 
  PRJ-100   Test Project  
        Save as Template   Materials      Edit       Client:   Client One 

    Contact:   N/A 

    Budget:    0.0  of  0.0  hours        
    Experimental Features   Enable or disable experimental features for your tenant. 

 
  svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 border-l-4 border-l-warning border-y-0 border-r-0 text-[rgb(var(--color-text-800))] [&>svg]:text-warning bg-warning/10" role="alert" >  defaults AI Assistant toggle to off 3ms → expected 'true' to be 'false' // Object.is equality × ExperimentalFeaturesSettings > renders experimental features warning banner 1004ms → Found multiple elements with the text: Experimental Here are the matching elements: Ignored nodes: comments, script, style  Experimental  Ignored nodes: comments, script, style  Experimental  Ignored nodes: comments, script, style  Experimental  Ignored nodes: comments, script, style  Experimental  Ignored nodes: comments, script, style  Experimental  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
    
 ← Back to Projects 
  PRJ-100   Test Project  
        Save as Template   Materials      Edit       Client:   Client One 

    Contact:   N/A 

    Budget:    0.0  of  0.0  hours        
    Experimental Features   Enable or disable experimental features for your tenant. 

 
  svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 border-l-4 border-l-warning border-y-0 border-r-0 text-[rgb(var(--color-text-800))] [&>svg]:text-warning bg-warning/10" role="alert" >  
    
 ← Back to Projects 
  PRJ-100   Test Project  
        Save as Template   Materials      Edit       Client:   Client One 

    Contact:   N/A 

    Budget:    0.0  of  0.0  hours        
    Experimental Features   Enable or disable experimental features for your tenant. 

 
  svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 border-l-4 border-l-warning border-y-0 border-r-0 text-[rgb(var(--color-text-800))] [&>svg]:text-warning bg-warning/10" role="alert" >  calls updateExperimentalFeatures() with current toggle states on save 1007ms → Found multiple elements with the role "button" and name "Save" Here are the matching elements: Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
    
 ← Back to Projects 
  PRJ-100   Test Project  
        Save as Template   Materials      Edit       Client:   Client One 

    Contact:   N/A 

    Budget:    0.0  of  0.0  hours        
    Experimental Features   Enable or disable experimental features for your tenant. 

 
  svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 border-l-4 border-l-warning border-y-0 border-r-0 text-[rgb(var(--color-text-800))] [&>svg]:text-warning bg-warning/10" role="alert" >  
    
 ← Back to Projects 
  PRJ-100   Test Project  
        Save as Template   Materials      Edit       Client:   Client One 

    Contact:   N/A 

    Budget:    0.0  of  0.0  hours        
    Experimental Features   Enable or disable experimental features for your tenant. 

 
  svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 border-l-4 border-l-warning border-y-0 border-r-0 text-[rgb(var(--color-text-800))] [&>svg]:text-warning bg-warning/10" role="alert" >  shows success feedback after saving 1009ms → Found multiple elements with the role "button" and name "Save" Here are the matching elements: Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
    
 ← Back to Projects 
  PRJ-100   Test Project  
        Save as Template   Materials      Edit       Client:   Client One 

    Contact:   N/A 

    Budget:    0.0  of  0.0  hours        
    Experimental Features   Enable or disable experimental features for your tenant. 

 
  svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 border-l-4 border-l-warning border-y-0 border-r-0 text-[rgb(var(--color-text-800))] [&>svg]:text-warning bg-warning/10" role="alert" >  
    
 ← Back to Projects 
  PRJ-100   Test Project  
        Save as Template   Materials      Edit       Client:   Client One 

    Contact:   N/A 

    Budget:    0.0  of  0.0  hours        
    Experimental Features   Enable or disable experimental features for your tenant. 

 
  svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 border-l-4 border-l-warning border-y-0 border-r-0 text-[rgb(var(--color-text-800))] [&>svg]:text-warning bg-warning/10" role="alert" >  updates local state when toggled 11ms ✓ ExperimentalFeaturesSettings > loads current settings on mount 3ms × ExperimentalFeaturesSettings > renders list of features with toggles 8ms → expected [ , …(3) ] to have a length of 2 but got 4 × ExperimentalFeaturesSettings > disables AI Assistant toggle when not allowed 4ms → expected 'true' to be 'false' // Object.is equality ✓ packages/projects/src/components/__tests__/TaskQuickAddPrefill.test.tsx (1 test) 1ms 116 MB heap used ✓ packages/billing/src/components/billing-dashboard/InvoiceTemplateEditor.previewWorkspace.test.tsx (11 tests) 115ms 129 MB heap used ✓ server/src/test/unit/email/EmailLogsClient.ui.test.tsx (6 tests) 960ms 113 MB heap used ✓ EmailLogsClient > updates results when date range filter changes 308ms ✓ EmailLogsClient > updates results when recipient search changes 308ms ✓ EmailLogsClient > updates results when ticket filter changes 310ms stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx Retrieved secret 'db_password_server' from configured provider. ✓ packages/projects/tests/projectMaterialsDrawer.test.tsx (16 tests) 166ms 140 MB heap used ✓ packages/billing/src/components/billing-dashboard/InvoiceTemplateEditor.authoritativeFlow.test.tsx (2 tests) 249ms 294 MB heap used stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx Retrieved secret 'db_password_server' from configured provider. stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx Retrieved secret 'postgres_password' from configured provider. stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx Retrieved secret 'db_password_server' from configured provider. ✓ packages/billing/tests/contractsActivationFlow.test.tsx (2 tests) 219ms 308 MB heap used ✓ packages/billing/src/components/invoice-designer/canvas/DesignCanvas.previewMode.test.tsx (15 tests) 35ms 342 MB heap used ✓ packages/billing/src/components/invoice-designer/canvas/DesignCanvas.constraintHighlights.test.tsx (2 tests) 3ms 347 MB heap used ✓ server/src/test/unit/components/AssetNotesPanel.test.tsx (1 test) 2ms 331 MB heap used ✓ packages/billing/src/components/invoice-designer/DesignerVisualWorkspace.test.tsx (28 tests) 1559ms 376 MB heap used ✓ DesignerVisualWorkspace > calls paginated invoice search with status=all and query filters 316ms ✓ DesignerVisualWorkspace > renders loading, empty, and error states for existing invoice list 619ms ✓ packages/billing/tests/draftContractsTable.test.tsx (30 tests) 1264ms 271 MB heap used stdout | ee/server/src/__tests__/integration/extensionProxyFlow.test.ts > Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should handle Gateway errors and return error message to Client iframeBridge: received message { type: 'apiproxy', origin: 'http://localhost:3000' } iframeBridge: handling apiproxy { requestId: 'req-error', route: '/error-route' } stdout | ee/server/src/__tests__/integration/extensionProxyFlow.test.ts > Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should handle Gateway errors and return error message to Client iframeBridge: fetch completed { status: 500, ok: false, url: '/api/ext-proxy/test-extension-id/error-route' } stdout | ee/server/src/__tests__/integration/extensionProxyFlow.test.ts > Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should handle Gateway errors and return error message to Client iframeBridge: posting apiproxy_response { requestId: 'req-error', targetOrigin: '*' } stdout | ee/server/src/__tests__/integration/extensionProxyFlow.test.ts > Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should forward "apiproxy" message to Gateway and return response to Client iframeBridge: received message { type: 'apiproxy', origin: 'http://localhost:3000' } iframeBridge: handling apiproxy { requestId: 'req-123', route: '/tickets' } iframeBridge: posting apiproxy_response { requestId: 'req-123', targetOrigin: '*' } ❯ ee/server/src/__tests__/integration/extensionProxyFlow.test.ts (4 tests | 3 failed) 141ms 254 MB heap used × Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should forward "apiproxy" message to Gateway and return response to Client 58ms → expected "spy" to be called with arguments: [ StringContaining{…}, …(1) ] Number of calls: 0 ✓ Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should handle Gateway errors and return error message to Client 57ms × Extension Proxy Flow Integration > Gateway Handler (Host -> Runner) > should forward request to RunnerBackend and propagate response headers/body 3ms → Failed to resolve import "@alga-psa/db/models/UserSession" from "packages/auth/src/lib/nextAuthOptions.ts". Does the file exist? × Extension Proxy Flow Integration > Gateway Handler (Host -> Runner) > should handle Runner errors gracefully 24ms → Failed to resolve import "@alga-psa/db/models/UserSession" from "packages/auth/src/lib/nextAuthOptions.ts". Does the file exist? ❯ server/src/test/unit/tickets/TicketEmailNotifications.ui.test.tsx (7 tests | 3 failed) 92ms 264 MB heap used ✓ TicketEmailNotifications > renders without errors 1ms ✓ TicketEmailNotifications > is collapsed by default and expands on click 10ms ✓ TicketEmailNotifications > shows loading state while fetching 11ms × TicketEmailNotifications > displays timestamp, recipient, subject, and status for each log entry 12ms → Found multiple elements with the text: /2026/ Here are the matching elements: Ignored nodes: comments, script, style  1/1/2026  Ignored nodes: comments, script, style  Jan 01, 2026, 7:00 AM  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
     Contracts  
 
 
  Templates    Client Contracts    Drafts   1 
   
 
         
           Contract Name        Client       shows error message for failed notifications 9ms × TicketEmailNotifications > shows maximum 20 entries initially with Load more when more exist 16ms → Found multiple elements with the role "table" Here are the matching elements: Ignored nodes: comments, script, style       Contract Name        Client        Created        Last Modified    ↓       Actions            Draft Alpha       Acme Co       12/31/2025       1/1/2026         Open menu              Ignored nodes: comments, script, style     Jan 01, 2026, 7:00 AM   user0@example.com   S0      sent     —     Jan 01, 2026, 7:00 AM   user1@example.com   S1      sent     —     Jan 01, 2026, 7:00 AM   user2@example.com   S2      sent     —     Jan 01, 2026, 7:00 AM   user3@example.com   S3      sent     —     Jan 01, 2026, 7:00 AM   user4@example.com   S4      sent     —     Jan 01, 2026, 7:00 AM   user5@example.com   S5      sent     —     Jan 01, 2026, 7:00 AM   user6@example.com   S6      sent     —     Jan 01, 2026, 7:00 AM   user7@example.com   S7      sent     —     Jan 01, 2026, 7:00 AM   user8@example.com   S8      sent     —     Jan 01, 2026, 7:00 AM   user9@example.com   S9      sent     —     Jan 01, 2026, 7:00 AM   user10@example.com   S10      sent     —     Jan 01, 2026, 7:00 AM   user11@example.com   S11      sent     —     Jan 01, 2026, 7:00 AM   user12@example.com   S12      sent     —     Jan 01, 2026, 7:00 AM   user13@example.com   S13      sent     —     Jan 01, 2026, 7:00 AM   user14@example.com   S14      sent     —     Jan 01, 2026, 7:00 AM   user15@example.com   S15      sent     —     Jan 01, 2026, 7:00 AM   user16@example.com   S16      sent     —     Jan 01, 2026, 7:00 AM   user17@example.com   S17      sent     —     Jan 01, 2026, 7:00 AM   user18@example.com   S18      sent     —     Jan 01, 2026, 7:00 AM   user19@example.com   S19      sent     —     (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
     Contracts  
 
 
  Templates    Client Contracts    Drafts   1 
   
 
         
           Contract Name        Client       Load more fetches additional entries 33ms → Found multiple elements with the role "table" Here are the matching elements: Ignored nodes: comments, script, style       Contract Name        Client        Created        Last Modified    ↓       Actions            Draft Alpha       Acme Co       12/31/2025       1/1/2026         Open menu              Ignored nodes: comments, script, style     Jan 01, 2026, 7:00 AM   user0@example.com   S0      sent     —     Jan 01, 2026, 7:00 AM   user1@example.com   S1      sent     —     Jan 01, 2026, 7:00 AM   user2@example.com   S2      sent     —     Jan 01, 2026, 7:00 AM   user3@example.com   S3      sent     —     Jan 01, 2026, 7:00 AM   user4@example.com   S4      sent     —     Jan 01, 2026, 7:00 AM   user5@example.com   S5      sent     —     Jan 01, 2026, 7:00 AM   user6@example.com   S6      sent     —     Jan 01, 2026, 7:00 AM   user7@example.com   S7      sent     —     Jan 01, 2026, 7:00 AM   user8@example.com   S8      sent     —     Jan 01, 2026, 7:00 AM   user9@example.com   S9      sent     —     Jan 01, 2026, 7:00 AM   user10@example.com   S10      sent     —     Jan 01, 2026, 7:00 AM   user11@example.com   S11      sent     —     Jan 01, 2026, 7:00 AM   user12@example.com   S12      sent     —     Jan 01, 2026, 7:00 AM   user13@example.com   S13      sent     —     Jan 01, 2026, 7:00 AM   user14@example.com   S14      sent     —     Jan 01, 2026, 7:00 AM   user15@example.com   S15      sent     —     Jan 01, 2026, 7:00 AM   user16@example.com   S16      sent     —     Jan 01, 2026, 7:00 AM   user17@example.com   S17      sent     —     Jan 01, 2026, 7:00 AM   user18@example.com   S18      sent     —     Jan 01, 2026, 7:00 AM   user19@example.com   S19      sent     —     Jan 01, 2026, 7:00 AM   user20@example.com   S20      sent     —     Jan 01, 2026, 7:00 AM   user21@example.com   S21      sent     —     Jan 01, 2026, 7:00 AM   user22@example.com   S22      sent     —     Jan 01, 2026, 7:00 AM   user23@example.com   S23      sent     —     Jan 01, 2026, 7:00 AM   user24@example.com   S24      sent     —     (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
     Notes & Quick Info        Save  
       
     Contracts  
 
 
  Templates    Client Contracts    Drafts   1 
   
 
         
     ... ✓ server/src/test/unit/QuickAskOverlay.streaming.test.tsx (1 test) 13ms 282 MB heap used stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/unit/Chat.streamingIncrementalState.test.tsx (9 tests | 9 failed) 31ms 266 MB heap used × EE Chat (streaming state) > updates the in-progress assistant message as tokens arrive 4ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
     Contracts  
 
 
  Templates    Client Contracts    Drafts   1 
   
 
         
           Contract Name        Client       aborts the streaming request when Stop is clicked 4ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
     Contracts  
 
 
  Templates    Client Contracts    Drafts   1 
   
 
         
           Contract Name        Client       stops updating token display and ends generation state after Stop 3ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
     Contracts  
 
 
  Templates    Client Contracts    Drafts   1 
   
 
         
           Contract Name        Client       shows a streaming cursor while receiving tokens 3ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
     Contracts  
 
 
  Templates    Client Contracts    Drafts   1 
   
 
         
           Contract Name        Client       removes the streaming cursor when done is received 5ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
     Contracts  
 
 
  Templates    Client Contracts    Drafts   1 
   
 
         
           Contract Name        Client       shows the partial response when a network error occurs mid-stream 3ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
     Contracts  
 
 
  Templates    Client Contracts    Drafts   1 
   
 
         
           Contract Name        Client       shows an interruption indicator when the stream ends without done=true 3ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
     Contracts  
 
 
  Templates    Client Contracts    Drafts   1 
   
 
         
           Contract Name        Client       persists the assistant message after streaming completes 3ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
     Contracts  
 
 
  Templates    Client Contracts    Drafts   1 
   
 
         
           Contract Name        Client       persists assistant content matching the final streamed tokens 3ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
     Contracts  
 
 
  Templates    Client Contracts    Drafts   1 
   
 
         
           Contract Name        Client      =20 <25"} (current: {"node":"v25.5.0","pnpm":"9.15.9"}) RUN v3.2.4 /Users/roberisaacs/alga-psa.worktrees/codex/feature-invoice-designer Running tests with seed "1770926085818" Environment file path: /Users/roberisaacs/alga-psa.worktrees/codex/feature-invoice-designer/.env.localtest stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 59, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 58, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 57, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 56, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 55, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 54, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 53, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 52, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 51, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 50, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 49, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 48, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 47, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 46, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 45, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 44, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 43, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 42, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 41, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 40, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 39, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 38, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 37, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 36, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 35, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 34, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 33, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 32, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 31, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 30, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 29, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 28, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 27, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 26, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 25, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 24, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 23, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 22, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 21, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 20, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 19, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 18, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 17, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 16, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 15, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 14, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 13, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 12, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 11, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 10, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 9, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 8, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 7, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 6, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 5, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 4, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 3, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 2, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 1, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 0, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Sustained Rate > should allow sustained rate equal to refill rate [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 0, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 59, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 58, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 57, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 56, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 55, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 54, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 53, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 52, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 51, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 50, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 49, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 48, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 47, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 46, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 45, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 44, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 43, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 42, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 41, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 40, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 39, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 38, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 37, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 36, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 35, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 34, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 33, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 32, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 31, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 30, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 29, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 28, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 27, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 26, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 25, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 24, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 23, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 22, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 21, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 20, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 19, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 18, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 17, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 16, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 15, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 14, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 13, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 12, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 11, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 10, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 9, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 8, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 7, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 6, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 5, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 4, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 3, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 2, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 1, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 0, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > Token Bucket vs Sliding Window Comparison > Burst Handling > should allow burst up to maxTokens [TokenBucketRateLimiter] Rate limit exceeded { tenantId: 'tenant-1', userId: undefined, remaining: 0, needed: 1, retryAfterMs: 999 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Initialization > should initialize with Redis client [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Initialization > should warn if initialized twice [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Shutdown > should cleanup on shutdown [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Shutdown > should cleanup on shutdown [TokenBucketRateLimiter] Shutdown complete stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should allow request when bucket has tokens [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should allow request when bucket has tokens [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 59, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should track tokens separately per tenant [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should track tokens separately per tenant [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 1, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should track tokens separately per tenant [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 0, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should track tokens separately per tenant [TokenBucketRateLimiter] Rate limit exceeded { tenantId: 'tenant-1', userId: undefined, remaining: 0, needed: 1, retryAfterMs: 1000 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should track tokens separately per tenant [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-2', userId: undefined, remaining: 1, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should track tokens separately per user within a tenant [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should track tokens separately per user within a tenant [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: 'user-1', remaining: 1, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should track tokens separately per user within a tenant [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: 'user-1', remaining: 0, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should track tokens separately per user within a tenant [TokenBucketRateLimiter] Rate limit exceeded { tenantId: 'tenant-1', userId: 'user-1', remaining: 0, needed: 1, retryAfterMs: 1000 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should track tokens separately per user within a tenant [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: 'user-2', remaining: 1, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should allow multiple requests until bucket is empty [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should allow multiple requests until bucket is empty [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 2, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should allow multiple requests until bucket is empty [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 1, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should allow multiple requests until bucket is empty [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 0, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Consumption > should allow multiple requests until bucket is empty [TokenBucketRateLimiter] Rate limit exceeded { tenantId: 'tenant-1', userId: undefined, remaining: 0, needed: 1, retryAfterMs: 1000 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Get State > should return full bucket for new tenant [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Get State > should return current bucket state [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Get State > should return current bucket state [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 9, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Get State > should return current bucket state [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 8, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Refill > should not exceed maxTokens when refilling [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Refill > should not exceed maxTokens when refilling [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 4, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Refill > should refill tokens over time [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Refill > should refill tokens over time [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 1, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Refill > should refill tokens over time [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 0, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Refill > should refill tokens over time [TokenBucketRateLimiter] Rate limit exceeded { tenantId: 'tenant-1', userId: undefined, remaining: 0, needed: 1, retryAfterMs: 100 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Token Refill > should refill tokens over time [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 1, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Retry After Calculation > should include reason when rate limited [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Retry After Calculation > should include reason when rate limited [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 0, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Retry After Calculation > should include reason when rate limited [TokenBucketRateLimiter] Rate limit exceeded { tenantId: 'tenant-1', userId: undefined, remaining: 0, needed: 1, retryAfterMs: 1000 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Retry After Calculation > should return correct retryAfterMs when rate limited [TokenBucketRateLimiter] Initialized successfully { defaultMaxTokens: 60, defaultRefillRate: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Retry After Calculation > should return correct retryAfterMs when rate limited [TokenBucketRateLimiter] Token consumed { tenantId: 'tenant-1', userId: undefined, remaining: 0, consumed: 1 } stdout | server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts > TokenBucketRateLimiter > Retry After Calculation > should return correct retryAfterMs when rate limited [TokenBucketRateLimiter] Rate limit exceeded { tenantId: 'tenant-1', userId: undefined, remaining: 0, needed: 1, retryAfterMs: 1000 } ✓ server/src/test/unit/notifications/tokenBucketRateLimiter.test.ts (17 tests) 7ms 15 MB heap used stdout | server/src/test/integration/googleProviderDataPersistence.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/googleProviderDataPersistence.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/googleProviderDataPersistence.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/googleProviderDataPersistence.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/googleProviderDataPersistence.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/googleProviderDataPersistence.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/googleProviderDataPersistence.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/googleProviderDataPersistence.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/googleProviderDataPersistence.test.ts > Google Provider Data Persistence Tests CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/googleProviderDataPersistence.test.ts > Google Provider Data Persistence Tests Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/googleProviderDataPersistence.test.ts > Google Provider Data Persistence Tests CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/googleProviderDataPersistence.test.ts > Google Provider Data Persistence Tests Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/integration/googleProviderDataPersistence.test.ts (6 tests | 6 skipped) 19ms 90 MB heap used ↓ Google Provider Data Persistence Tests > should create a Google provider record with all required fields in the database ↓ Google Provider Data Persistence Tests > should persist Google Workspace (non-gmail.com) configurations correctly ↓ Google Provider Data Persistence Tests > should store OAuth tokens and authentication data when provided ↓ Google Provider Data Persistence Tests > should enforce proper database constraints for Google providers ↓ Google Provider Data Persistence Tests > should enforce validation for required fields ↓ Google Provider Data Persistence Tests > should correctly handle updates to existing Google provider configurations ❯ server/src/test/unit/Chat.streamingEndpoint.test.ts (2 tests | 1 failed) 3ms 97 MB heap used ✓ EE Chat (source) > uses the streaming completions endpoint for new messages 0ms × EE Chat (source) > reads the streaming response via response.body.getReader() 2ms → expected '\'use client\';\n\nimport React, { us…' to contain 'response.body.getReader()' ✓ packages/billing/src/actions/invoiceTemplateCompileParity.test.ts (2 tests) 0ms 100 MB heap used ✓ packages/billing/src/components/invoice-designer/state/designerStore.layout.test.ts (5 tests) 3ms 104 MB heap used ✓ packages/tickets/src/lib/timeEntryContext.test.ts (3 tests) 1ms 106 MB heap used ✓ server/src/test/unit/scheduling/eligibleSubjects.test.ts (3 tests) 1ms 107 MB heap used ✓ shared/workflow/runtime/__tests__/mappingResolver.test.ts (18 tests) 5ms 114 MB heap used ✓ packages/billing/src/components/invoice-designer/DesignerShell.fitSection.test.ts (11 tests) 1ms 123 MB heap used stdout | server/src/test/unit/billing/billingEngine.endExclusiveQueries.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/billing/billingEngine.endExclusiveQueries.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/billing/billingEngine.endExclusiveQueries.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/billingEngine.endExclusiveQueries.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/billing/billingEngine.endExclusiveQueries.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/billing/billingEngine.endExclusiveQueries.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/billing/billingEngine.endExclusiveQueries.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/billingEngine.endExclusiveQueries.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/billing/billingEngine.prorationExclusive.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/billing/billingEngine.prorationExclusive.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/billing/billingEngine.prorationExclusive.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/billingEngine.prorationExclusive.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/billing/billingEngine.prorationExclusive.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/billing/billingEngine.prorationExclusive.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/billing/billingEngine.prorationExclusive.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/billingEngine.prorationExclusive.test.ts Retrieved secret 'db_password_server' from configured provider. ✓ packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts (4 tests) 8ms 220 MB heap used ❯ server/src/test/integration/ticketBundling.integration.test.ts (8 tests | 8 skipped) 1ms 231 MB heap used ↓ Ticket bundling integration > enforces permissions for bundle operations ↓ Ticket bundling integration > creates bundles, manages membership, and enforces invariants ↓ Ticket bundling integration > supports promote-to-master and preserves membership ↓ Ticket bundling integration > sync_updates propagates workflow changes; children lock workflow fields ↓ Ticket bundling integration > sync_updates mirrors public comments to children, marking them system-generated and immutable ↓ Ticket bundling integration > reopen-on-reply can reopen the master when a client replies on a child ↓ Ticket bundling integration > surfaces inbound child public replies on the master as aggregated view-only items ↓ Ticket bundling integration > blocks time entries on bundled children and allows time entries on masters stdout | server/src/test/integration/workflowRuntimeV2.email.integration.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/workflowRuntimeV2.email.integration.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/workflowRuntimeV2.email.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/workflowRuntimeV2.email.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/workflowRuntimeV2.email.integration.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/workflowRuntimeV2.email.integration.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/workflowRuntimeV2.email.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/workflowRuntimeV2.email.integration.test.ts Retrieved secret 'db_password_server' from configured provider. ✓ packages/core/src/lib/events/publisher.test.ts (1 test) 4ms 239 MB heap used stdout | server/src/test/integration/emailProviderCreation.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/emailProviderCreation.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/emailProviderCreation.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/emailProviderCreation.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/emailProviderCreation.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/emailProviderCreation.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/emailProviderCreation.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/emailProviderCreation.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/contractTemplateWizardCurrency.integration.test.ts > createContractTemplateFromWizard with Currency Support Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/contractTemplateWizardCurrency.integration.test.ts > createContractTemplateFromWizard with Currency Support CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/contractTemplateWizardCurrency.integration.test.ts > createContractTemplateFromWizard with Currency Support CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/contractTemplateWizardCurrency.integration.test.ts > createContractTemplateFromWizard with Currency Support Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/contractTemplateWizardCurrency.integration.test.ts > createContractTemplateFromWizard with Currency Support CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/contractTemplateWizardCurrency.integration.test.ts > createContractTemplateFromWizard with Currency Support Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/integration/contractTemplateWizardCurrency.integration.test.ts (7 tests | 7 skipped) 2ms 251 MB heap used ↓ createContractTemplateFromWizard with Currency Support > creates a template with USD currency and persists it correctly ↓ createContractTemplateFromWizard with Currency Support > creates a template with EUR currency and persists it correctly ↓ createContractTemplateFromWizard with Currency Support > creates a template with GBP currency and persists it correctly ↓ createContractTemplateFromWizard with Currency Support > creates templates with multiple currencies in same tenant ↓ createContractTemplateFromWizard with Currency Support > creates draft template with currency and verifies status and currency ↓ createContractTemplateFromWizard with Currency Support > creates contract from template and inherits template currency (EUR) ↓ createContractTemplateFromWizard with Currency Support > creates contract with JPY currency from template and preserves currency ❯ packages/core/src/lib/logger.outputs.test.ts (2 tests | 2 failed) 3ms 257 MB heap used × logger outputs > defaults to console-only transport 1ms → Target cannot be null or undefined. × logger outputs > configures external and file transports when enabled 1ms → Cannot read properties of undefined (reading 'find') stdout | server/src/lib/workflow/visualization/ast/flowGraphBuilder.test.ts > flowGraphBuilder > buildFlowGraph > should skip edges that involve state transitions Sorted components by source location: [ 'action at line 2:1' ] Sequential edge: connecting action-action1-2-1 (handle: right) to action-action1-2-1 (handle: left) stdout | server/src/lib/workflow/visualization/ast/flowGraphBuilder.test.ts > flowGraphBuilder > buildFlowGraph > should exclude state transitions from the graph Sorted components by source location: [ 'action at line 3:1' ] ❯ server/src/lib/workflow/visualization/ast/flowGraphBuilder.test.ts (3 tests | 2 failed) 55ms 275 MB heap used ✓ flowGraphBuilder > buildFlowGraph > should exclude state transitions from the graph 0ms × flowGraphBuilder > buildFlowGraph > should skip edges that involve state transitions 1ms → expected 'action-action1-2-1' to be 'action-0' // Object.is equality × flowGraphBuilder > applyLayout > should position nodes in a directed layout 53ms → expected 12 to be +0 // Object.is equality ✓ packages/billing/src/lib/invoice-template-ast/server-render.test.ts (1 test) 1ms 247 MB heap used ✓ packages/core/src/lib/logger.test.ts (1 test) 0ms 249 MB heap used ❯ packages/ui/src/context/SchedulingContext.test.tsx (4 tests | 4 failed) 1ms 275 MB heap used × SchedulingContext > returns default callbacks when no provider is present 1ms → document is not defined × SchedulingContext > renders fallback alert element for agent schedule by default 0ms → document is not defined × SchedulingContext > shows a toast when launching time entry without provider 0ms → document is not defined × SchedulingContext > uses provider callbacks when SchedulingCallbackProvider is present 0ms → document is not defined ✓ packages/billing/src/actions/invoiceLegacyCompilerRemoval.test.ts (2 tests) 0ms 286 MB heap used ✓ server/src/test/unit/ui/timeTrackingSubjectSelector.test.ts (3 tests) 1ms 287 MB heap used stdout | server/src/test/integration/email/emailSendingLogsMigration.integration.test.ts > email_sending_logs entity context migrations Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/email/emailSendingLogsMigration.integration.test.ts > email_sending_logs entity context migrations CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/email/emailSendingLogsMigration.integration.test.ts > email_sending_logs entity context migrations CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/email/emailSendingLogsMigration.integration.test.ts > email_sending_logs entity context migrations Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/email/emailSendingLogsMigration.integration.test.ts > email_sending_logs entity context migrations CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/email/emailSendingLogsMigration.integration.test.ts > email_sending_logs entity context migrations Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/integration/email/emailSendingLogsMigration.integration.test.ts (7 tests | 7 skipped) 2ms 297 MB heap used ↓ email_sending_logs entity context migrations > adds entity_type column ↓ email_sending_logs entity context migrations > adds entity_id column ↓ email_sending_logs entity context migrations > adds contact_id column ↓ email_sending_logs entity context migrations > adds notification_subtype_id column ↓ email_sending_logs entity context migrations > creates tenant/entity index ↓ email_sending_logs entity context migrations > creates tenant/contact index ↓ email_sending_logs entity context migrations > migration files export up/down functions ✓ packages/tickets/src/lib/__tests__/responseSource.test.ts (8 tests) 0ms 266 MB heap used stdout | server/src/test/unit/accounting/xeroClientService.spec.ts > XeroClientService – REST usage > refreshes OAuth tokens when expired Successfully wrote tenant secret: /Users/roberisaacs/alga-psa.worktrees/codex/feature-invoice-designer/secrets/tenants/tenant-123/xero_credentials stdout | server/src/test/unit/accounting/xeroClientService.spec.ts > XeroClientService – REST usage > retries after 401 by refreshing token once and logs tenant metadata Successfully wrote tenant secret: /Users/roberisaacs/alga-psa.worktrees/codex/feature-invoice-designer/secrets/tenants/tenant-123/xero_credentials ❯ server/src/test/unit/accounting/xeroClientService.spec.ts (8 tests | 1 failed) 4ms 271 MB heap used ✓ XeroClientService – REST usage > POST /Invoices payload matches spec requirements 0ms ✓ XeroClientService – REST usage > normalizes validation errors returned from POST /Invoices 0ms ✓ XeroClientService – REST usage > handles empty payload array without issuing network request 0ms ✓ XeroClientService – REST usage > sets expected headers for authenticated requests 0ms ✓ XeroClientService – REST usage > refreshes OAuth tokens when expired 1ms ✓ XeroClientService – REST usage > retrieves accounts, items, tax rates, and tracking categories with normalized structures 1ms × XeroClientService – REST usage > retries after 401 by refreshing token once and logs tenant metadata 1ms → expected "spy" to be called 1 times, but got 0 times ✓ XeroClientService – REST usage > allows re-export after validation error once mappings are corrected 0ms stdout | server/src/test/integration/projectTemplatesIntegration.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/projectTemplatesIntegration.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/projectTemplatesIntegration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/projectTemplatesIntegration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/projectTemplatesIntegration.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/projectTemplatesIntegration.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/projectTemplatesIntegration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/projectTemplatesIntegration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/invoiceTemplates/standardTemplatePoNumber.test.ts > Standard invoice template PO header > T010: default template renders PO number in header only when invoice has po_number Input JSON to WASM: {"invoiceNumber":"INV-PO","issueDate":"2025-01-01","dueDate":"2025-02-01","currencyCode":"USD","customer":{"name":"Alpha Co","address":"1 Test St"},"tenantClient":{"name":"Tenant","address":"Tenant Address","logoUrl":null},"items":[{"id":"1","description":"Service","quantity":1,"unitPrice":100,"total":100}],"subtotal":100,"tax":0,"total":100,"poNumber":"PO-XYZ"} [Wasm Log]: Wasm (standard-default): Received data string. [Wasm Log]: Wasm (standard-default): Deserialized Invoice #: INV-PO [Wasm Log]: Wasm (standard-default): Serializing layout... [Wasm Log]: Wasm (standard-default): Returning serialized layout. Output JSON from WASM: {"type": "Document", "children": [{"type": "Section", "children": [{"type": "Row", "children": [{"type": "Column", "span": 3, "children": [{"type": "Text", "content": "[Tenant Logo]", "variant": "", "id": ""}], "id": ""},{"type": "Column", "span": 5, "children": [{"type": "Text", "content": "Tenant", "variant": "heading3", "id": ""},{"type": "Text", "content": "Tenant Address", "variant": "", "id": ""}], "id": "", "style": {"paddingLeft": "0.5em", "paddingTop": "0.5em"}},{"type": "Column", "span": 4, "children": [{"type": "Text", "content": "Invoice #: INV-PO", "variant": "", "id": ""},{"type": "Text", "content": "Date: 2025-01-01", "variant": "", "id": ""},{"type": "Text", "content": "PO #: PO-XYZ", "variant": "", "id": ""}], "id": "", "style": {"textAlign": "right", "paddingRight": "0.5em"}}], "id": ""},{"type": "Row", "children": [{"type": "Column", "span": 6, "children": [{"type": "Text", "content": "Bill To:", "variant": "heading3", "id": ""},{"type": "Text", "content": "Alpha Co", "variant": "", "id": ""},{"type": "Text", "content": "1 Test St", "variant": "", "id": ""}], "id": "", "style": {"paddingLeft": "1em", "paddingTop": "0.5em"}}], "id": ""}], "id": "invoice-header-std-default"},{"type": "Section", "children": [{"type": "Text", "content": "Items", "variant": "heading3", "id": "", "style": {"marginTop": "1em", "paddingLeft": "0.5em", "paddingBottom": "0.2em"}},{"type": "Section", "children": [{"type": "Row", "children": [{"type": "Column", "span": 6, "children": [{"type": "Text", "content": "Description", "variant": "label", "id": ""}], "id": "", "style": {"paddingLeft": "0.5em"}},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "Qty", "variant": "label", "id": ""}], "id": "", "style": {"textAlign": "right"}},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "Unit Price", "variant": "label", "id": ""}], "id": "", "style": {"textAlign": "right"}},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "Total", "variant": "label", "id": "", "style": {"fontWeight": "bold", "paddingRight": "0.5em"}}], "id": "", "style": {"textAlign": "right"}}], "id": "", "style": {"fontWeight": "bold", "paddingBottom": "0.5em", "borderBottom": "1px solid #ccc"}},{"type": "Row", "children": [{"type": "Column", "span": 6, "children": [{"type": "Text", "content": "Service", "variant": "", "id": ""}], "id": "", "style": {"paddingLeft": "0.5em"}},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "1.0", "variant": "", "id": ""}], "id": "", "style": {"textAlign": "right"}},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "$1.00", "variant": "", "id": ""}], "id": "", "style": {"textAlign": "right"}},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "$1.00", "variant": "", "id": ""}], "id": "", "style": {"textAlign": "right", "paddingRight": "0.5em"}}], "id": "item-row-1", "style": {"paddingTop": "0.3em", "paddingBottom": "0.3em", "borderBottom": "0px"}}], "id": "items-table-section-items", "style": {"paddingLeft": "1em", "paddingRight": "1em", "paddingTop": "1em", "paddingBottom": "1em", "border": "1px solid #ccc", "marginBottom": "1em"}}], "id": "invoice-items-std-default"},{"type": "Section", "children": [{"type": "Row", "children": [{"type": "Column", "span": 7, "children": [], "id": ""},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "Subtotal", "variant": "", "id": ""},{"type": "Text", "content": "Tax", "variant": "", "id": ""},{"type": "Text", "content": "Total", "variant": "", "id": ""}], "id": "", "style": {"textAlign": "right", "paddingRight": "1em"}},{"type": "Column", "span": 3, "children": [{"type": "Text", "content": "$1.00", "variant": "", "id": ""},{"type": "Text", "content": "$0.00", "variant": "", "id": ""},{"type": "Text", "content": "$1.00", "variant": "", "id": "", "style": {"fontWeight": "bold"}}], "id": "", "style": {"textAlign": "right", "paddingRight": "0.5em"}}], "id": ""}], "id": "invoice-totals-std-default", "style": {"marginTop": "1em", "paddingTop": "1em", "paddingBottom": "1em", "borderTop": "1px solid #eee"}},{"type": "Section", "children": [{"type": "Text", "content": "Thank you for your business!", "variant": "", "id": "", "style": {"marginTop": "1em", "paddingLeft": "0.5em"}}], "id": "invoice-notes-std-default", "style": {"marginTop": "2em"}}], "id": "invoice-document-standard-default"} stdout | server/src/test/unit/invoiceTemplates/standardTemplatePoNumber.test.ts > Standard invoice template PO header > T010: default template renders PO number in header only when invoice has po_number Input JSON to WASM: {"invoiceNumber":"INV-PO","issueDate":"2025-01-01","dueDate":"2025-02-01","currencyCode":"USD","customer":{"name":"Alpha Co","address":"1 Test St"},"tenantClient":{"name":"Tenant","address":"Tenant Address","logoUrl":null},"items":[{"id":"1","description":"Service","quantity":1,"unitPrice":100,"total":100}],"subtotal":100,"tax":0,"total":100,"poNumber":null} [Wasm Log]: Wasm (standard-default): Received data string. [Wasm Log]: Wasm (standard-default): Deserialized Invoice #: INV-PO [Wasm Log]: Wasm (standard-default): Serializing layout... [Wasm Log]: Wasm (standard-default): Returning serialized layout. Output JSON from WASM: {"type": "Document", "children": [{"type": "Section", "children": [{"type": "Row", "children": [{"type": "Column", "span": 3, "children": [{"type": "Text", "content": "[Tenant Logo]", "variant": "", "id": ""}], "id": ""},{"type": "Column", "span": 5, "children": [{"type": "Text", "content": "Tenant", "variant": "heading3", "id": ""},{"type": "Text", "content": "Tenant Address", "variant": "", "id": ""}], "id": "", "style": {"paddingLeft": "0.5em", "paddingTop": "0.5em"}},{"type": "Column", "span": 4, "children": [{"type": "Text", "content": "Invoice #: INV-PO", "variant": "", "id": ""},{"type": "Text", "content": "Date: 2025-01-01", "variant": "", "id": ""}], "id": "", "style": {"textAlign": "right", "paddingRight": "0.5em"}}], "id": ""},{"type": "Row", "children": [{"type": "Column", "span": 6, "children": [{"type": "Text", "content": "Bill To:", "variant": "heading3", "id": ""},{"type": "Text", "content": "Alpha Co", "variant": "", "id": ""},{"type": "Text", "content": "1 Test St", "variant": "", "id": ""}], "id": "", "style": {"paddingLeft": "1em", "paddingTop": "0.5em"}}], "id": ""}], "id": "invoice-header-std-default"},{"type": "Section", "children": [{"type": "Text", "content": "Items", "variant": "heading3", "id": "", "style": {"marginTop": "1em", "paddingLeft": "0.5em", "paddingBottom": "0.2em"}},{"type": "Section", "children": [{"type": "Row", "children": [{"type": "Column", "span": 6, "children": [{"type": "Text", "content": "Description", "variant": "label", "id": ""}], "id": "", "style": {"paddingLeft": "0.5em"}},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "Qty", "variant": "label", "id": ""}], "id": "", "style": {"textAlign": "right"}},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "Unit Price", "variant": "label", "id": ""}], "id": "", "style": {"textAlign": "right"}},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "Total", "variant": "label", "id": "", "style": {"fontWeight": "bold", "paddingRight": "0.5em"}}], "id": "", "style": {"textAlign": "right"}}], "id": "", "style": {"fontWeight": "bold", "paddingBottom": "0.5em", "borderBottom": "1px solid #ccc"}},{"type": "Row", "children": [{"type": "Column", "span": 6, "children": [{"type": "Text", "content": "Service", "variant": "", "id": ""}], "id": "", "style": {"paddingLeft": "0.5em"}},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "1.0", "variant": "", "id": ""}], "id": "", "style": {"textAlign": "right"}},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "$1.00", "variant": "", "id": ""}], "id": "", "style": {"textAlign": "right"}},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "$1.00", "variant": "", "id": ""}], "id": "", "style": {"textAlign": "right", "paddingRight": "0.5em"}}], "id": "item-row-1", "style": {"paddingTop": "0.3em", "paddingBottom": "0.3em", "borderBottom": "0px"}}], "id": "items-table-section-items", "style": {"paddingLeft": "1em", "paddingRight": "1em", "paddingTop": "1em", "paddingBottom": "1em", "border": "1px solid #ccc", "marginBottom": "1em"}}], "id": "invoice-items-std-default"},{"type": "Section", "children": [{"type": "Row", "children": [{"type": "Column", "span": 7, "children": [], "id": ""},{"type": "Column", "span": 2, "children": [{"type": "Text", "content": "Subtotal", "variant": "", "id": ""},{"type": "Text", "content": "Tax", "variant": "", "id": ""},{"type": "Text", "content": "Total", "variant": "", "id": ""}], "id": "", "style": {"textAlign": "right", "paddingRight": "1em"}},{"type": "Column", "span": 3, "children": [{"type": "Text", "content": "$1.00", "variant": "", "id": ""},{"type": "Text", "content": "$0.00", "variant": "", "id": ""},{"type": "Text", "content": "$1.00", "variant": "", "id": "", "style": {"fontWeight": "bold"}}], "id": "", "style": {"textAlign": "right", "paddingRight": "0.5em"}}], "id": ""}], "id": "invoice-totals-std-default", "style": {"marginTop": "1em", "paddingTop": "1em", "paddingBottom": "1em", "borderTop": "1px solid #eee"}},{"type": "Section", "children": [{"type": "Text", "content": "Thank you for your business!", "variant": "", "id": "", "style": {"marginTop": "1em", "paddingLeft": "0.5em"}}], "id": "invoice-notes-std-default", "style": {"marginTop": "2em"}}], "id": "invoice-document-standard-default"} ✓ server/src/test/unit/invoiceTemplates/standardTemplatePoNumber.test.ts (1 test) 1355ms 282 MB heap used ❯ server/src/test/unit/tickets/TicketDetails.emailNotifications.integration.test.ts (1 test | 1 failed) 0ms 292 MB heap used × TicketDetails > includes the TicketEmailNotifications section 0ms → ENOENT: no such file or directory, open '/Users/roberisaacs/alga-psa.worktrees/codex/packages/tickets/src/components/ticket/TicketDetails.tsx' ✓ server/src/test/unit/extensions/uiHooks.test.ts (2 tests) 0ms 294 MB heap used stdout | server/src/test/integration/billing/contractPurchaseOrderSupport.integration.test.ts > Contract Purchase Order Support Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/billing/contractPurchaseOrderSupport.integration.test.ts > Contract Purchase Order Support CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/billing/contractPurchaseOrderSupport.integration.test.ts > Contract Purchase Order Support CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/billing/contractPurchaseOrderSupport.integration.test.ts > Contract Purchase Order Support Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/billing/contractPurchaseOrderSupport.integration.test.ts > Contract Purchase Order Support CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/billing/contractPurchaseOrderSupport.integration.test.ts > Contract Purchase Order Support Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/integration/billing/contractPurchaseOrderSupport.integration.test.ts (5 tests | 5 skipped) 2ms 298 MB heap used ↓ Contract Purchase Order Support > T001: invoices table includes po_number + client_contract_id ↓ Contract Purchase Order Support > T002: invoice creation snapshots client_contracts.po_number onto invoices.po_number ↓ Contract Purchase Order Support > T003: invoice generation blocks when po_required=true and po_number is missing ↓ Contract Purchase Order Support > T004: PO consumption sums finalized invoices and unconsumes when status changes away from finalized ↓ Contract Purchase Order Support > T005: overage calculation uses invoice total_amount and contract po_amount (authorized total spend) stdout | server/src/test/integration/accounting/mappingCrud.integration.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/accounting/mappingCrud.integration.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/accounting/mappingCrud.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/accounting/mappingCrud.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/accounting/mappingCrud.integration.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/accounting/mappingCrud.integration.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/accounting/mappingCrud.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/accounting/mappingCrud.integration.test.ts Retrieved secret 'db_password_server' from configured provider. ✓ packages/billing/src/components/invoice-designer/state/designerStore.presets.test.ts (1 test) 3ms 311 MB heap used ❯ shared/workflow/actions/__tests__/emailWorkflowActions.responseSource.test.ts (6 tests | 5 failed) 17ms 317 MB heap used × createCommentFromEmail response source metadata > T002: persists metadata.responseSource=inbound_email 16ms → trx is not a function × createCommentFromEmail response source metadata > T003: includes normalized provider type when available 0ms → trx is not a function × createCommentFromEmail response source metadata > google inbound flow resolves to inbound_email metadata source (T017) 0ms → trx is not a function × createCommentFromEmail response source metadata > microsoft inbound flow resolves to inbound_email metadata source (T018) 0ms → trx is not a function × createCommentFromEmail response source metadata > imap inbound flow resolves to inbound_email metadata source (T019) 0ms → trx is not a function ✓ createCommentFromEmail response source metadata > T020: keeps comment response-state semantics unchanged (still non-internal) 0ms stdout | server/src/test/integration/multiCurrencyGaps.integration.test.ts > Multi-Currency Gap Tests Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/multiCurrencyGaps.integration.test.ts > Multi-Currency Gap Tests CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/multiCurrencyGaps.integration.test.ts > Multi-Currency Gap Tests CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/multiCurrencyGaps.integration.test.ts > Multi-Currency Gap Tests Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/multiCurrencyGaps.integration.test.ts > Multi-Currency Gap Tests CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/multiCurrencyGaps.integration.test.ts > Multi-Currency Gap Tests Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/integration/multiCurrencyGaps.integration.test.ts (8 tests | 8 skipped) 2ms 279 MB heap used ↓ Multi-Currency Gap Tests > CRITICAL: Prepayment credits should track currency > createPrepaymentInvoice should record currency on the credit transaction ↓ Multi-Currency Gap Tests > CRITICAL: Prepayment credits should track currency > createPrepaymentInvoice should record currency on the credit_tracking entry ↓ Multi-Currency Gap Tests > CRITICAL: Credit application should validate currency > applyCreditToInvoice should reject applying USD credit to EUR invoice ↓ Multi-Currency Gap Tests > HIGH: Credit listing should support currency filtering > listClientCredits should be able to filter credits by currency ↓ Multi-Currency Gap Tests > HIGH: Credit history should support currency filtering > getCreditHistory should return transactions with currency information ↓ Multi-Currency Gap Tests > MEDIUM: Mixed-currency contract creation > should warn when creating contract in different currency than existing active contract ↓ Multi-Currency Gap Tests > VERIFIED: Working currency functionality > billing engine correctly retrieves contract currency via join ↓ Multi-Currency Gap Tests > VERIFIED: Working currency functionality > clients.default_currency_code has NOT NULL constraint stdout | server/src/test/e2e/api/roles.e2e.test.ts > Roles API E2E Tests Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/e2e/api/roles.e2e.test.ts > Roles API E2E Tests CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/e2e/api/roles.e2e.test.ts > Roles API E2E Tests CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/roles.e2e.test.ts > Roles API E2E Tests Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/roles.e2e.test.ts > Roles API E2E Tests CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/roles.e2e.test.ts > Roles API E2E Tests Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/e2e/api/roles.e2e.test.ts (16 tests | 16 skipped) 2ms 191 MB heap used ↓ Roles API E2E Tests > Basic CRUD Operations > should create a new role ↓ Roles API E2E Tests > Basic CRUD Operations > should list roles with pagination ↓ Roles API E2E Tests > Basic CRUD Operations > should get a specific role ↓ Roles API E2E Tests > Basic CRUD Operations > should update a role ↓ Roles API E2E Tests > Basic CRUD Operations > should delete a role ↓ Roles API E2E Tests > Permission Management > should assign permissions to a role ↓ Roles API E2E Tests > Permission Management > should get role permissions ↓ Roles API E2E Tests > Role Templates > should get available role templates ↓ Roles API E2E Tests > Role Cloning > should clone an existing role ↓ Roles API E2E Tests > Bulk Operations > should bulk create roles ↓ Roles API E2E Tests > Error Handling > should return 401 without API key ↓ Roles API E2E Tests > Error Handling > should return 403 without permission ↓ Roles API E2E Tests > Error Handling > should return 400 for invalid data ↓ Roles API E2E Tests > Error Handling > should return 404 for non-existent role ↓ Roles API E2E Tests > Error Handling > should prevent duplicate role names ↓ Roles API E2E Tests > Tenant Isolation > should not access roles from other tenants ✓ packages/billing/src/components/invoice-designer/canvas/DesignCanvas.previewModel.test.ts (5 tests) 1ms 195 MB heap used ✓ packages/types/src/exports.typecheck.test.ts (1 test) 0ms 196 MB heap used ❯ server/src/test/integration/onboardingProgressSubsteps.integration.test.ts (1 test | 1 failed) 1ms 201 MB heap used × getOnboardingProgressAction (substeps) > returns portal + email steps with substeps 1ms → Cannot find package '@alga-psa/onboarding/actions' imported from '/Users/roberisaacs/alga-psa.worktrees/codex/feature-invoice-designer/server/src/test/integration/onboardingProgressSubsteps.integration.test.ts' stdout | server/src/test/integration/appointmentNotifications.integration.test.ts > Appointment Notification System Integration Tests Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/appointmentNotifications.integration.test.ts > Appointment Notification System Integration Tests CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/appointmentNotifications.integration.test.ts > Appointment Notification System Integration Tests CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/appointmentNotifications.integration.test.ts > Appointment Notification System Integration Tests Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/appointmentNotifications.integration.test.ts > Appointment Notification System Integration Tests CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/appointmentNotifications.integration.test.ts > Appointment Notification System Integration Tests Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/integration/appointmentNotifications.integration.test.ts (29 tests | 29 skipped) 3ms 223 MB heap used ↓ Appointment Notification System Integration Tests > Email Notifications > should send appointment request received email to client ↓ Appointment Notification System Integration Tests > Email Notifications > should send new appointment request email to MSP staff ↓ Appointment Notification System Integration Tests > Email Notifications > should send appointment approved email with correct locale ↓ Appointment Notification System Integration Tests > Email Notifications > should send appointment declined email with reason ↓ Appointment Notification System Integration Tests > Email Notifications > should include tenant settings in all emails ↓ Appointment Notification System Integration Tests > Email Notifications > should replace template variables correctly ↓ Appointment Notification System Integration Tests > Internal Notifications > should create notification for client on request submission ↓ Appointment Notification System Integration Tests > Internal Notifications > should create notifications for MSP staff on request submission ↓ Appointment Notification System Integration Tests > Internal Notifications > should create notification for client on approval ↓ Appointment Notification System Integration Tests > Internal Notifications > should create notification for client on decline ↓ Appointment Notification System Integration Tests > Internal Notifications > should include correct link in notifications ↓ Appointment Notification System Integration Tests > Internal Notifications > should populate metadata correctly for staff notifications ↓ Appointment Notification System Integration Tests > Helper Function Integration > should get correct schedule approvers ↓ Appointment Notification System Integration Tests > Helper Function Integration > should get correct tenant settings ↓ Appointment Notification System Integration Tests > Helper Function Integration > should map contact to client user ID correctly ↓ Appointment Notification System Integration Tests > Helper Function Integration > should return null for non-existent contact ↓ Appointment Notification System Integration Tests > Helper Function Integration > should format dates with correct locale ↓ Appointment Notification System Integration Tests > Helper Function Integration > should format times with correct locale ↓ Appointment Notification System Integration Tests > Multi-Language Notification Support > should send email notifications in different languages ↓ Appointment Notification System Integration Tests > Multi-Language Notification Support > should format dates according to locale in notifications ↓ Appointment Notification System Integration Tests > Multi-Language Notification Support > should default to English when locale is not supported ↓ Appointment Notification System Integration Tests > Cancellation Notifications > should send cancellation notification to client ↓ Appointment Notification System Integration Tests > Cancellation Notifications > should handle cancellation of already cancelled request gracefully ↓ Appointment Notification System Integration Tests > Notification Metadata and Navigation > should include actionable metadata in staff notifications ↓ Appointment Notification System Integration Tests > Notification Metadata and Navigation > should include appropriate links for client notifications ↓ Appointment Notification System Integration Tests > Notification Metadata and Navigation > should set correct notification types for different events ↓ Appointment Notification System Integration Tests > Error Handling and Edge Cases > should handle missing email addresses gracefully ↓ Appointment Notification System Integration Tests > Error Handling and Edge Cases > should batch notifications to multiple staff members efficiently ↓ Appointment Notification System Integration Tests > Error Handling and Edge Cases > should include all required data fields in notifications ❯ packages/documents/tests/storageService.workflowEvents.test.ts (2 tests | 1 failed) 2ms 229 MB heap used ✓ StorageService.uploadFile workflow events > publishes FILE_UPLOADED after creating the file record 0ms × StorageService.uploadFile workflow events > publishes DOCUMENT_DELETED after deleting the file record 1ms → expected "spy" to be called with arguments: [ ObjectContaining{…} ] Received: 1st spy call: @@ -1,12 +1,18 @@ [ - ObjectContaining { - "ctx": ObjectContaining { - "tenantId": "tenant-1", + { + "ctx": { + "actor": { + "actorType": "USER", + "actorUserId": "a836a8b5-3df5-47b1-b49b-9a78f2b1a8a0", }, + "occurredAt": "2026-01-24T12:30:00.000Z", + "tenantId": undefined, + }, "eventType": "DOCUMENT_DELETED", - "payload": ObjectContaining { + "idempotencyKey": "document_deleted:14f1fbf4-17d6-4bdc-8d4b-0b2a2ff8f26a:2026-01-24T12:30:00.000Z", + "payload": { "deletedAt": "2026-01-24T12:30:00.000Z", "deletedByUserId": "a836a8b5-3df5-47b1-b49b-9a78f2b1a8a0", "documentId": "14f1fbf4-17d6-4bdc-8d4b-0b2a2ff8f26a", }, }, Number of calls: 1 ✔ T020: ticket-created-hello fixture loads and executes via harness (3.852542ms) ✔ T100: ticket-created-triage-comment fixture loads and executes via harness (1.193708ms) ✔ T101: ticket-created-auto-assign-by-priority fixture loads and executes via harness (1.122709ms) ✔ T102: ticket-created-vip-notify fixture loads and executes via harness (1.090625ms) ✔ T103: ticket-created-outage-escalate fixture loads and executes via harness (0.949917ms) ✔ T104: ticket-created-create-project-task fixture loads and executes via harness (1.035083ms) ✔ T105: ticket-created-assign-trycatch fixture loads and executes via harness (1.134667ms) ✔ T106: ticket-created-notify-multiple fixture loads and executes via harness (1.554667ms) ✔ T107: ticket-created-ignore-system fixture loads and executes via harness (0.582625ms) ✔ T108: ticket-assigned-acknowledge fixture loads and executes via harness (1.149166ms) ✔ T109: ticket-unassigned-return-to-triage fixture loads and executes via harness (0.907625ms) ✔ T110: ticket-status-waiting-on-customer-reminder fixture loads and executes via harness (0.686458ms) ✔ T111: ticket-reopened-notify-tech fixture loads and executes via harness (0.713333ms) ✔ T112: ticket-escalated-crm-note fixture loads and executes via harness (0.87275ms) ✔ T113: ticket-queue-after-hours-email fixture loads and executes via harness (0.759292ms) ✔ T114: ticket-tags-billing-route fixture loads and executes via harness (0.782583ms) stdout | ee/server/src/lib/extensions/__tests__/assets/url.shared.test.ts > buildExtUiSrc > honors public base override [ext-ui][buildExtUiSrc] { extensionId: 'ext-1', mode: 'rust', clientPath: '/', tenantId: 'tenant-123', overrideBase: 'http://localhost:8085', runnerBase: undefined, publicBase: 'http://localhost:8085' } stdout | ee/server/src/lib/extensions/__tests__/assets/url.shared.test.ts > buildExtUiSrc > falls back to /runner when no public base is set [ext-ui][buildExtUiSrc] { extensionId: 'ext-1', mode: 'rust', clientPath: '/', tenantId: undefined, overrideBase: null, runnerBase: undefined, publicBase: '/runner' } stdout | ee/server/src/lib/extensions/__tests__/assets/url.shared.test.ts > buildExtUiSrc > appends tenant when provided [ext-ui][buildExtUiSrc] { extensionId: 'ext-1', mode: 'rust', clientPath: '/', tenantId: 'tenant-123', overrideBase: null, runnerBase: undefined, publicBase: '/runner' } stdout | ee/server/src/lib/extensions/__tests__/assets/url.shared.test.ts > buildExtUiSrc > uses absolute public base when provided [ext-ui][buildExtUiSrc] { extensionId: 'ext-1', mode: 'rust', clientPath: '/settings', tenantId: undefined, overrideBase: null, runnerBase: 'https://runner.dev/alga', publicBase: 'https://runner.dev/alga' } stdout | ee/server/src/lib/extensions/__tests__/assets/url.shared.test.ts > buildExtUiSrc > supports relative public base for gateway proxy [ext-ui][buildExtUiSrc] { extensionId: 'ext-1', mode: 'rust', clientPath: '/', tenantId: undefined, overrideBase: null, runnerBase: '/runner', publicBase: '/runner' } ✓ ee/server/src/lib/extensions/__tests__/assets/url.shared.test.ts (5 tests) 1ms 240 MB heap used ✓ server/src/test/unit/notifications/emailRateLimiting.test.ts (14 tests) 1ms 244 MB heap used stdout | server/src/test/e2e/api/boards.e2e.test.ts > Board API E2E Tests Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/e2e/api/boards.e2e.test.ts > Board API E2E Tests CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/e2e/api/boards.e2e.test.ts > Board API E2E Tests CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/boards.e2e.test.ts > Board API E2E Tests Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/boards.e2e.test.ts > Board API E2E Tests CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/boards.e2e.test.ts > Board API E2E Tests Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/e2e/api/boards.e2e.test.ts (10 tests | 10 skipped) 2ms 200 MB heap used ↓ Board API E2E Tests > Authentication > should require API key ↓ Board API E2E Tests > Authentication > should reject invalid API key ↓ Board API E2E Tests > List Boards (GET /api/v1/boards) > should list active boards by default ↓ Board API E2E Tests > List Boards (GET /api/v1/boards) > should include inactive boards when requested ↓ Board API E2E Tests > List Boards (GET /api/v1/boards) > should support pagination ↓ Board API E2E Tests > List Boards (GET /api/v1/boards) > should support search by name ↓ Board API E2E Tests > List Boards (GET /api/v1/boards) > should sort by display_order by default ↓ Board API E2E Tests > Get Board by ID (GET /api/v1/boards/:id) > should retrieve a board by ID ↓ Board API E2E Tests > Get Board by ID (GET /api/v1/boards/:id) > should return 404 for non-existent board ↓ Board API E2E Tests > Get Board by ID (GET /api/v1/boards/:id) > should return 400 for invalid UUID format ❯ ee/extensions/samples/ui-kit-showcase/test/build.test.ts (1 test | 1 failed) 0ms 202 MB heap used × build output > iframe bundle is generated in ui/dist/iframe 0ms → expected false to be true // Object.is equality stdout | server/src/test/integration/workflowRuntimeV2.control.integration.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/workflowRuntimeV2.control.integration.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/workflowRuntimeV2.control.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/workflowRuntimeV2.control.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/workflowRuntimeV2.control.integration.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/workflowRuntimeV2.control.integration.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/workflowRuntimeV2.control.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/workflowRuntimeV2.control.integration.test.ts Retrieved secret 'db_password_server' from configured provider. ✓ server/src/test/unit/api/chatExecute.route.gating.test.ts (1 test) 4ms 229 MB heap used stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Statistics > should get time entry statistics Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Statistics > should get time entry statistics CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Statistics > should get time entry statistics CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Statistics > should get time entry statistics Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Statistics > should get time entry statistics CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Statistics > should get time entry statistics Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should create a new time entry CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should create a new time entry Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should create a new time entry CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should create a new time entry Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should validate required fields CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should validate required fields Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should validate required fields CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should validate required fields Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should validate time periods overlap CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should validate time periods overlap Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should validate time periods overlap CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should validate time periods overlap Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should compute work_date in user timezone and bucket to the correct period CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should compute work_date in user timezone and bucket to the correct period Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should compute work_date in user timezone and bucket to the correct period CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should compute work_date in user timezone and bucket to the correct period Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should not allow updating approved entries CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should not allow updating approved entries Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should not allow updating approved entries CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should not allow updating approved entries Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should update a time entry CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should update a time entry Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should update a time entry CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should update a time entry Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should return 404 when updating non-existent entry CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should return 404 when updating non-existent entry Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should return 404 when updating non-existent entry CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should return 404 when updating non-existent entry Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should not allow deleting approved entries CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should not allow deleting approved entries Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should not allow deleting approved entries CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should not allow deleting approved entries Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should delete a time entry CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should delete a time entry Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should delete a time entry CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should delete a time entry Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should return 404 when deleting non-existent entry CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should return 404 when deleting non-existent entry Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should return 404 when deleting non-existent entry CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should return 404 when deleting non-existent entry Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should not return time entries from other tenants CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should not return time entries from other tenants Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should not return time entries from other tenants CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should not return time entries from other tenants Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should retrieve a time entry by ID CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should retrieve a time entry by ID Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should retrieve a time entry by ID CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should retrieve a time entry by ID Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should return 404 for non-existent time entry CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should return 404 for non-existent time entry Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should return 404 for non-existent time entry CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should return 404 for non-existent time entry Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Authentication > should reject invalid API key CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Authentication > should reject invalid API key Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Authentication > should reject invalid API key CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Authentication > should reject invalid API key Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Authentication > should require API key for all endpoints CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Authentication > should require API key for all endpoints Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Authentication > should require API key for all endpoints CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Authentication > should require API key for all endpoints Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Templates > should list time entry templates CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Templates > should list time entry templates Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Templates > should list time entry templates CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Templates > should list time entry templates Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Error Handling > should handle invalid date format CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Error Handling > should handle invalid date format Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Error Handling > should handle invalid date format CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Error Handling > should handle invalid date format Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Error Handling > should handle invalid UUID format CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Error Handling > should handle invalid UUID format Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Error Handling > should handle invalid UUID format CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Error Handling > should handle invalid UUID format Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Error Handling > should handle invalid query parameters CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Error Handling > should handle invalid query parameters Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Error Handling > should handle invalid query parameters CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Error Handling > should handle invalid query parameters Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should list time entries with default pagination CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should list time entries with default pagination Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should list time entries with default pagination CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should list time entries with default pagination Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by user CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by user Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by user CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by user Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should support pagination parameters CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should support pagination parameters Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should support pagination parameters CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should support pagination parameters Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by billable status CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by billable status Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by billable status CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by billable status Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should sort by date CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should sort by date Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should sort by date CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should sort by date Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by date range CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by date range Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by date range CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by date range Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Bulk Operations > should bulk delete time entries CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Bulk Operations > should bulk delete time entries Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Bulk Operations > should bulk delete time entries CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Bulk Operations > should bulk delete time entries Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Bulk Operations > should bulk create time entries CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Bulk Operations > should bulk create time entries Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Bulk Operations > should bulk create time entries CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Bulk Operations > should bulk create time entries Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Bulk Operations > should bulk update time entries CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Bulk Operations > should bulk update time entries Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Bulk Operations > should bulk update time entries CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Bulk Operations > should bulk update time entries Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce read permissions for listing CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce read permissions for listing Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce read permissions for listing CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce read permissions for listing Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce update permissions CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce update permissions Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce update permissions CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce update permissions Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce delete permissions CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce delete permissions Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce delete permissions CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce delete permissions Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce create permissions CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce create permissions Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce create permissions CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Permissions > should enforce create permissions Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Time Tracking > should stop a tracking session CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Time Tracking > should stop a tracking session Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Time Tracking > should stop a tracking session CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Time Tracking > should stop a tracking session Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Time Tracking > should start a tracking session CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Time Tracking > should start a tracking session Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Time Tracking > should start a tracking session CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Time Tracking > should start a tracking session Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Multi-tenancy > should isolate time entries by tenant CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Multi-tenancy > should isolate time entries by tenant Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Multi-tenancy > should isolate time entries by tenant CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Multi-tenancy > should isolate time entries by tenant Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Export > should export time entries to JSON CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Export > should export time entries to JSON Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Export > should export time entries to JSON CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Export > should export time entries to JSON Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Export > should export time entries to CSV CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Export > should export time entries to CSV Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Export > should export time entries to CSV CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/time-entries.e2e.test.ts > Time Entries API E2E Tests > Export > should export time entries to CSV Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/e2e/api/time-entries.e2e.test.ts (40 tests | 38 failed | 2 skipped) 41ms 213 MB heap used × Time Entries API E2E Tests > Authentication > should require API key for all endpoints 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Authentication > should reject invalid API key 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should create a new time entry 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should compute work_date in user timezone and bucket to the correct period 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should validate required fields 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Create Time Entry (POST /api/v1/time-entries) > should validate time periods overlap 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should retrieve a time entry by ID 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should return 404 for non-existent time entry 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Get Time Entry (GET /api/v1/time-entries/:id) > should not return time entries from other tenants 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should update a time entry 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should return 404 when updating non-existent entry 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Update Time Entry (PUT /api/v1/time-entries/:id) > should not allow updating approved entries 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should delete a time entry 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should return 404 when deleting non-existent entry 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > CRUD Operations > Delete Time Entry (DELETE /api/v1/time-entries/:id) > should not allow deleting approved entries 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should list time entries with default pagination 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should support pagination parameters 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by date range 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by user 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should filter by billable status 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > List Time Entries (GET /api/v1/time-entries) > should sort by date 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Time Tracking > should start a tracking session 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Time Tracking > should stop a tracking session 1ms → → Cannot read properties of undefined (reading 'cleanup') ↓ Time Entries API E2E Tests > Approval Workflow > should approve time entries ↓ Time Entries API E2E Tests > Approval Workflow > should reject invalid entry IDs for approval × Time Entries API E2E Tests > Export > should export time entries to CSV 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Export > should export time entries to JSON 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Statistics > should get time entry statistics 2ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Templates > should list time entry templates 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Bulk Operations > should bulk create time entries 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Bulk Operations > should bulk update time entries 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Bulk Operations > should bulk delete time entries 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Error Handling > should handle invalid UUID format 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Error Handling > should handle invalid query parameters 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Error Handling > should handle invalid date format 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Permissions > should enforce read permissions for listing 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Permissions > should enforce create permissions 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Permissions > should enforce update permissions 1ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Permissions > should enforce delete permissions 7ms → → Cannot read properties of undefined (reading 'cleanup') × Time Entries API E2E Tests > Multi-tenancy > should isolate time entries by tenant 1ms → → Cannot read properties of undefined (reading 'cleanup') ❯ server/src/lib/eventBus/index.hardTimeout.test.ts (1 test | 1 failed) 4ms 221 MB heap used × EventBus Redis consumer hard-timeout > resets the Redis client if xReadGroup hangs beyond the hard timeout 4ms → Failed to resolve entry for package "@alga-psa/event-schemas". The package may have incorrect main/module/exports specified in its package.json. stdout | ee/server/src/__tests__/integration/ticket-response-state.integration.test.ts > Ticket Response State Integration Tests Database config: { host: 'localhost', port: 5438, database: 'server', user: 'app_user', password: '[32 chars]', ssl: false } ❯ ee/server/src/__tests__/integration/ticket-response-state.integration.test.ts (28 tests | 28 skipped) 2ms 226 MB heap used ↓ Ticket Response State Integration Tests > Database Migration Tests (T001-T004) > T001: ticket_response_state enum type exists with correct values ↓ Ticket Response State Integration Tests > Database Migration Tests (T001-T004) > T002: response_state column exists on tickets table and is nullable ↓ Ticket Response State Integration Tests > Database Migration Tests (T001-T004) > T003: Index exists on (tenant, response_state) ↓ Ticket Response State Integration Tests > Database Migration Tests (T001-T004) > T004: New tickets have null response_state by default ↓ Ticket Response State Integration Tests > Type Definition Tests (T005-T006) > T005-T006: TicketResponseState type exists and allows correct values ↓ Ticket Response State Integration Tests > Comment-Triggered State Changes (T007-T017) > T007: Staff creates client-visible comment → response_state becomes awaiting_client ↓ Ticket Response State Integration Tests > Comment-Triggered State Changes (T007-T017) > T008: Staff creates client-visible comment on ticket already awaiting_client → state unchanged ↓ Ticket Response State Integration Tests > Comment-Triggered State Changes (T007-T017) > T009: Staff creates client-visible comment on ticket awaiting_internal → state becomes awaiting_client ↓ Ticket Response State Integration Tests > Comment-Triggered State Changes (T007-T017) > T010: Client creates comment → response_state becomes awaiting_internal ↓ Ticket Response State Integration Tests > Comment-Triggered State Changes (T007-T017) > T011: Client creates comment on ticket already awaiting_internal → state unchanged ↓ Ticket Response State Integration Tests > Comment-Triggered State Changes (T007-T017) > T012: Client creates comment on ticket awaiting_client → state becomes awaiting_internal ↓ Ticket Response State Integration Tests > Comment-Triggered State Changes (T007-T017) > T013: Staff creates internal note → response_state does not change from null ↓ Ticket Response State Integration Tests > Comment-Triggered State Changes (T007-T017) > T014: Staff creates internal note on awaiting_client ticket → state remains awaiting_client ↓ Ticket Response State Integration Tests > Comment-Triggered State Changes (T007-T017) > T015: Staff creates internal note on awaiting_internal ticket → state remains awaiting_internal ↓ Ticket Response State Integration Tests > Comment-Triggered State Changes (T007-T017) > T016-T017: Comment creation and response state update occur in same transaction ↓ Ticket Response State Integration Tests > Manual Override and Close Behavior (T018-T026) > T018: updateTicket with response_state=awaiting_client updates ticket ↓ Ticket Response State Integration Tests > Manual Override and Close Behavior (T018-T026) > T019: updateTicket with response_state=awaiting_internal updates ticket ↓ Ticket Response State Integration Tests > Manual Override and Close Behavior (T018-T026) > T020: updateTicket with response_state=null clears response state ↓ Ticket Response State Integration Tests > Manual Override and Close Behavior (T018-T026) > T022-T024: Closing ticket clears response_state ↓ Ticket Response State Integration Tests > Manual Override and Close Behavior (T018-T026) > T025: Closing ticket with null response_state keeps response_state null ↓ Ticket Response State Integration Tests > Manual Override and Close Behavior (T018-T026) > T026: Reopening closed ticket does not set response_state ↓ Ticket Response State Integration Tests > Event Publishing Tests (T054-T065, T072, T076) > T054: TICKET_RESPONSE_STATE_CHANGED event type exists ↓ Ticket Response State Integration Tests > Event Publishing Tests (T054-T065, T072, T076) > T055: Event schema validates required fields ↓ Ticket Response State Integration Tests > Event Publishing Tests (T054-T065, T072, T076) > T056-T057: Creating client-visible comment fires TICKET_RESPONSE_STATE_CHANGED event with trigger=comment ↓ Ticket Response State Integration Tests > Event Publishing Tests (T054-T065, T072, T076) > T063-T064: Event includes correct previousState and newState values ↓ Ticket Response State Integration Tests > Event Publishing Tests (T054-T065, T072, T076) > T072: TICKET_COMMENT_ADDED event payload includes author_type ↓ Ticket Response State Integration Tests > Event Publishing Tests (T054-T065, T072, T076) > T076: Internal note does not fire TICKET_RESPONSE_STATE_CHANGED event ↓ Ticket Response State Integration Tests > Tenant Isolation Tests (T073-T075) > T073-T074: Users cannot see or update response_state of tickets in other tenants ❯ server/src/test/integration/ticketEmailDelimiters.test.ts (21 tests | 21 skipped) 54ms 234 MB heap used ↓ sendEventEmail reply markers > adds reply markers when conversation token is provided ↓ sendEventEmail reply markers > generates a conversation token when one is not supplied ↓ sendEventEmail reply markers > includes comment and thread markers for comment notifications ↓ ticket email subscriber reply markers > processes ticket created events with delimiters ↓ ticket email subscriber reply markers > processes ticket updated events with delimiters ↓ ticket email subscriber reply markers > processes ticket comment events with comment markers ↓ ticket email subscriber event publishing > publishes ticket created events and emails the primary contact ↓ ticket email subscriber deduplication > sends only one ticket created email when primary and assigned recipients share address ↓ ticket email subscriber deduplication > sends one internal ticket assigned email when assignee and contact share address ↓ ticket email subscriber deduplication > sends one ticket assigned email when contact and location share address ↓ ticket email subscriber deduplication > sends one ticket assigned email when additional resource shares email with assignee ↓ ticket email subscriber deduplication > sends one ticket comment email when additional resource shares email with assignee ↓ ticket email subscriber notification gating (known gap) > skips ticket created email when tenant notifications are disabled ↓ ticket email subscriber notification gating (known gap) > skips ticket created email when subtype is disabled ↓ ticket email subscriber notification gating (known gap) > skips ticket assigned email when user preference is disabled ↓ ticket email subscriber link routing > uses portal domain for external recipients and MSP URL for internal users ↓ ticket email subscriber link routing > falls back to the client portal path when no custom domain exists ↓ ticket email subscriber rich text formatting > renders rich text comment content as HTML instead of JSON ↓ ticket email subscriber rich text formatting > renders ticket description rich text without leaking JSON ↓ project email subscriber rich text formatting > renders project description rich text in project created emails ↓ project email subscriber rich text formatting > renders project description rich text in project assigned emails stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts > Email Settings OAuth Flow Tests 🏗️ Initializing Email Settings Test Fixture (one-time setup)... 📊 Setting up database and services... 🚀 Initializing E2E Test Context... 🔧 Set E2E environment variables: { DB_HOST: 'localhost', DB_PORT: '5433', DB_NAME_SERVER: 'server_test', DB_USER_ADMIN: 'postgres', PGBOUNCER_HOST: 'localhost', PGBOUNCER_PORT: '6434', REDIS_HOST: 'localhost', REDIS_PORT: '6380', EMAIL_HOST: 'localhost', EMAIL_PORT: '1025' } stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts > Email Settings OAuth Flow Tests CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts > Email Settings OAuth Flow Tests Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts > Email Settings OAuth Flow Tests CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts > Email Settings OAuth Flow Tests Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/email-settings/oauth-flow.test.ts > Email Settings OAuth Flow Tests 🧹 Final test fixture cleanup... ❯ server/src/test/e2e/email-settings/oauth-flow.test.ts (7 tests | 7 skipped) 3ms 248 MB heap used ↓ Email Settings OAuth Flow Tests > Microsoft OAuth Flow > should complete OAuth flow and store tokens ↓ Email Settings OAuth Flow Tests > Microsoft OAuth Flow > should handle OAuth error scenarios ↓ Email Settings OAuth Flow Tests > Microsoft OAuth Flow > should handle Microsoft webhook validation token ↓ Email Settings OAuth Flow Tests > Google OAuth Flow > should complete OAuth flow with Pub/Sub setup ↓ Email Settings OAuth Flow Tests > Google OAuth Flow > should handle expired refresh token ↓ Email Settings OAuth Flow Tests > Token Storage and Encryption > should store tokens securely in database ↓ Email Settings OAuth Flow Tests > State Parameter Validation > should validate state parameter in OAuth callback ✓ packages/billing/src/actions/invoiceTemplatePreviewCacheRemoval.test.ts (2 tests) 0ms 260 MB heap used ✓ server/src/test/unit/api/chatCompletions.route.gating.test.ts (2 tests) 4ms 268 MB heap used ✓ server/src/test/unit/billingPlanSelection.test.ts (5 tests | 1 skipped) 1ms 276 MB heap used ✓ sdk/samples/extension-ui/service-proxy-demo/tests/fetch.test.ts (1 test) 0ms 279 MB heap used stdout | server/src/test/integration/surveyEmailTemplates.integration.test.ts > Survey email templates Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/surveyEmailTemplates.integration.test.ts > Survey email templates CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/surveyEmailTemplates.integration.test.ts > Survey email templates CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/surveyEmailTemplates.integration.test.ts > Survey email templates Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/surveyEmailTemplates.integration.test.ts > Survey email templates CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/surveyEmailTemplates.integration.test.ts > Survey email templates Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/integration/surveyEmailTemplates.integration.test.ts (2 tests | 2 skipped) 1ms 253 MB heap used ↓ Survey email templates > registers system templates for each supported locale ↓ Survey email templates > renders locale-specific content and falls back to English stdout | server/src/test/unit/email/GmailAdapter.listMessagesSince.test.ts Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/email/GmailAdapter.listMessagesSince.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/email/GmailAdapter.listMessagesSince.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/email/GmailAdapter.listMessagesSince.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/email/GmailAdapter.listMessagesSince.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/email/GmailAdapter.listMessagesSince.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/email/GmailAdapter.listMessagesSince.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/email/GmailAdapter.listMessagesSince.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/email/GmailAdapter.listMessagesSince.test.ts > GmailAdapter.listMessagesSince > attempts to recreate Gmail watch when historyId rejection occurs [GOOGLE] Attempting to recreate Gmail watch after history_id invalidation { providerId: 'provider-id', rejectedHistoryId: '31559633' } stdout | server/src/test/unit/email/GmailAdapter.listMessagesSince.test.ts > GmailAdapter.listMessagesSince > attempts to recreate Gmail watch when historyId rejection occurs [GOOGLE] Gmail watch recreated successfully after history_id invalidation stdout | server/src/test/unit/email/GmailAdapter.listMessagesSince.test.ts > GmailAdapter.listMessagesSince > surfaces a dedicated error when Gmail returns historyId not found [GOOGLE] Attempting to recreate Gmail watch after history_id invalidation { providerId: 'provider-id', rejectedHistoryId: '31559633' } ✓ server/src/test/unit/email/GmailAdapter.listMessagesSince.test.ts (2 tests) 2ms 258 MB heap used ✓ server/src/app/api/client-portal/domain-session/route.test.ts (5 tests) 2ms 262 MB heap used ❯ tools/nx-tests/editionSwapping.test.ts (2 tests | 1 failed) 194ms 265 MB heap used × CE/EE build swapping > CE build excludes EE code in module resolution 97ms → expected '/Users/roberisaacs/alga-psa.worktrees…' to be '/Users/roberisaacs/alga-psa.worktrees…' // Object.is equality ✓ CE/EE build swapping > EE build includes EE code in module resolution 97ms ✓ server/src/test/unit/security/managerScopeRegression.test.ts (1 test) 1ms 267 MB heap used ✓ packages/core/src/lib/encryption.test.ts (2 tests) 2ms 270 MB heap used stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created an API key Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created an API key CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created an API key CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created an API key Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created an API key CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created an API key Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should create a complete test environment CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should create a complete test environment Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should create a complete test environment CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should create a complete test environment Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created a user CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created a user Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created a user CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created a user Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have a valid database connection CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have a valid database connection Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have a valid database connection CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have a valid database connection Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created a tenant CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created a tenant Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created a tenant CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Test Environment Setup > should have created a tenant Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should assert error responses CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should assert error responses Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should assert error responses CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should assert error responses Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should build query strings correctly CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should build query strings correctly Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should build query strings correctly CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should build query strings correctly Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should assert successful responses CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should assert successful responses Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should assert successful responses CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Test Helpers > should assert successful responses Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Client > should be able to make requests CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Client > should be able to make requests Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Client > should be able to make requests CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Client > should be able to make requests Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Client > should have API key configured CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Client > should have API key configured Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Client > should have API key configured CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > API Client > should have API key configured Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Contact Test Data Factory > should create multiple contacts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Contact Test Data Factory > should create multiple contacts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Contact Test Data Factory > should create multiple contacts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Contact Test Data Factory > should create multiple contacts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Contact Test Data Factory > should generate random contact data CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Contact Test Data Factory > should generate random contact data Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Contact Test Data Factory > should generate random contact data CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Contact Test Data Factory > should generate random contact data Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Contact Test Data Factory > should create a single contact CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Contact Test Data Factory > should create a single contact Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Contact Test Data Factory > should create a single contact CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/utils/utilities.test.ts > E2E Test Utilities > Contact Test Data Factory > should create a single contact Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/e2e/utils/utilities.test.ts (13 tests | 13 failed) 566ms 295 MB heap used × E2E Test Utilities > Test Environment Setup > should create a complete test environment 54ms → no such database: test_database × E2E Test Utilities > Test Environment Setup > should have a valid database connection 39ms → no such database: test_database × E2E Test Utilities > Test Environment Setup > should have created a tenant 36ms → no such database: test_database × E2E Test Utilities > Test Environment Setup > should have created a user 44ms → no such database: test_database × E2E Test Utilities > Test Environment Setup > should have created an API key 111ms → no such database: test_database × E2E Test Utilities > Contact Test Data Factory > should generate random contact data 37ms → no such database: test_database × E2E Test Utilities > Contact Test Data Factory > should create a single contact 37ms → no such database: test_database × E2E Test Utilities > Contact Test Data Factory > should create multiple contacts 38ms → no such database: test_database × E2E Test Utilities > API Test Helpers > should build query strings correctly 31ms → no such database: test_database × E2E Test Utilities > API Test Helpers > should assert successful responses 29ms → no such database: test_database × E2E Test Utilities > API Test Helpers > should assert error responses 36ms → no such database: test_database × E2E Test Utilities > API Client > should have API key configured 43ms → no such database: test_database × E2E Test Utilities > API Client > should be able to make requests 31ms → no such database: test_database ✓ packages/billing/src/components/invoice-designer/preview/previewSessionState.test.ts (6 tests) 1ms 304 MB heap used ❯ server/src/test/unit/contractLineDisambiguation.test.ts (12 tests | 6 failed) 4ms 310 MB heap used × Contract Line Disambiguation Logic > getEligibleContractLines > should query for eligible contract lines 1ms → knex is not a function × Contract Line Disambiguation Logic > determineDefaultContractLine > should return the only contract line when there is just one eligible contract line 0ms → expected null to be 'contractLine1' // Object.is equality ✓ Contract Line Disambiguation Logic > determineDefaultContractLine > should return null when there are no eligible contract lines 0ms × Contract Line Disambiguation Logic > determineDefaultContractLine > should return the contract line with a bucket overlay when there is only one overlay 0ms → expected null to be 'contractLine2' // Object.is equality ✓ Contract Line Disambiguation Logic > determineDefaultContractLine > should return null when there are multiple eligible contract lines with no clear default 0ms ✓ Contract Line Disambiguation Logic > determineDefaultContractLine > should return null when there are multiple contract lines with bucket overlays 0ms × Contract Line Disambiguation Logic > validateContractLineForService > should return true when the contract line is valid for the service 0ms → expected false to be true // Object.is equality ✓ Contract Line Disambiguation Logic > validateContractLineForService > should return false when the contract line is not valid for the service 0ms × Contract Line Disambiguation Logic > shouldAllocateUnassignedEntry > should return true when this is the only eligible contract line 0ms → expected false to be true // Object.is equality × Contract Line Disambiguation Logic > shouldAllocateUnassignedEntry > should return true when this is the only contract line with a bucket overlay 0ms → expected false to be true // Object.is equality ✓ Contract Line Disambiguation Logic > shouldAllocateUnassignedEntry > should return false when this is not the only eligible contract line and has no bucket overlay 0ms ✓ Contract Line Disambiguation Logic > shouldAllocateUnassignedEntry > should return false when there are multiple contract lines with bucket overlays 0ms ✓ packages/tickets/src/components/ticket/TicketDetails.scheduleDrawer.test.ts (1 test) 0ms 270 MB heap used ✓ packages/types/src/interfaces/ticket.interface.typecheck.test.ts (1 test) 0ms 273 MB heap used stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts Initializing composite secret provider system Building composite secret provider. Read chain: [env, filesystem], Write provider: filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts > Tax Rate Changes Mid-Billing Period CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts > Tax Rate Changes Mid-Billing Period Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts > Tax Rate Changes Mid-Billing Period CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts > Tax Rate Changes Mid-Billing Period Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/infrastructure/billing/tax/taxRateChanges.test.ts (1 test | 1 skipped) 1ms 280 MB heap used ↓ Tax Rate Changes Mid-Billing Period > should apply correct tax rates based on charge dates ✓ packages/billing/src/lib/invoice-template-ast/evaluator.test.ts (13 tests) 4ms 292 MB heap used stdout | server/src/test/unit/billingEngine.test.ts Initializing composite secret provider system Building composite secret provider. Read chain: [env, filesystem], Write provider: filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/billingEngine.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/billingEngine.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billingEngine.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/billingEngine.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/billingEngine.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/billingEngine.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billingEngine.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/accounting/batchLifecycle.integration.test.ts Initializing composite secret provider system Building composite secret provider. Read chain: [env, filesystem], Write provider: filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/accounting/batchLifecycle.integration.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/accounting/batchLifecycle.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/accounting/batchLifecycle.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/accounting/batchLifecycle.integration.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/accounting/batchLifecycle.integration.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/accounting/batchLifecycle.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/accounting/batchLifecycle.integration.test.ts Retrieved secret 'db_password_server' from configured provider. ✓ sdk/extension-runtime/tests/runtime.test.ts (3 tests) 1ms 326 MB heap used ✓ server/src/test/unit/ui/timesheetHeader.test.ts (1 test) 0ms 329 MB heap used ❯ server/src/test/integration/emailAttachmentIngestion.integration.test.ts (6 tests | 6 skipped) 4ms 293 MB heap used ↓ Email attachment ingestion (workflow-worker action override) > skips inline/CID attachments (no documents/files created) ↓ Email attachment ingestion (workflow-worker action override) > rejects attachments >100MB (no documents/files created) ↓ Email attachment ingestion (workflow-worker action override) > is idempotent: duplicate processing does not create duplicate documents/files ↓ Email attachment ingestion (workflow-worker action override) > skips unsupported Microsoft attachment types (records skipped) ↓ Email attachment ingestion (workflow-worker action override) > retries failed processing without duplicating records ↓ Email attachment ingestion (workflow-worker action override) > creates external_files + documents + document_associations with system attribution (Gmail path) ✓ sdk/samples/component/invoicing-demo/tests/handler.test.ts (4 tests) 1ms 297 MB heap used ✓ server/src/test/unit/DocumentationService.test.ts (4 tests) 1ms 300 MB heap used stdout | server/src/test/integration/emailProviderValidation.test.ts Initializing composite secret provider system Building composite secret provider. Read chain: [env, filesystem], Write provider: filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/emailProviderValidation.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/emailProviderValidation.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/emailProviderValidation.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/emailProviderValidation.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/emailProviderValidation.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/emailProviderValidation.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/emailProviderValidation.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/emailProviderValidation.test.ts > Email Provider Validation Tests CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/emailProviderValidation.test.ts > Email Provider Validation Tests Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/emailProviderValidation.test.ts > Email Provider Validation Tests CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/emailProviderValidation.test.ts > Email Provider Validation Tests Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/integration/emailProviderValidation.test.ts (10 tests | 10 skipped) 1ms 312 MB heap used ↓ Email Provider Validation Tests > Google Provider Validation > should return error when missing required Google provider fields ↓ Email Provider Validation Tests > Google Provider Validation > should return error for invalid email format ↓ Email Provider Validation Tests > Google Provider Validation > should return error when provider name is too long ↓ Email Provider Validation Tests > Microsoft Provider Validation > should return error when missing required Microsoft provider fields ↓ Email Provider Validation Tests > Microsoft Provider Validation > should handle missing optional fields gracefully ↓ Email Provider Validation Tests > General Validation > should return error for null or undefined required fields ↓ Email Provider Validation Tests > General Validation > should return error for empty string in required fields ↓ Email Provider Validation Tests > General Validation > should handle special characters in provider names ↓ Email Provider Validation Tests > General Validation > should return meaningful error for duplicate mailbox ↓ Email Provider Validation Tests > Error Message Quality > should provide helpful error messages for common mistakes stdout | server/src/test/infrastructure/projects/projectPermissions.test.ts Initializing composite secret provider system Building composite secret provider. Read chain: [env, filesystem], Write provider: filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/infrastructure/projects/projectPermissions.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/infrastructure/projects/projectPermissions.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/infrastructure/projects/projectPermissions.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/infrastructure/projects/projectPermissions.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/infrastructure/projects/projectPermissions.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/infrastructure/projects/projectPermissions.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/infrastructure/projects/projectPermissions.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/accounting/invoiceSelection.integration.test.ts Initializing composite secret provider system Building composite secret provider. Read chain: [env, filesystem], Write provider: filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/accounting/invoiceSelection.integration.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/accounting/invoiceSelection.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/accounting/invoiceSelection.integration.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/accounting/invoiceSelection.integration.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/accounting/invoiceSelection.integration.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/accounting/invoiceSelection.integration.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/accounting/invoiceSelection.integration.test.ts Retrieved secret 'db_password_server' from configured provider. ✓ server/src/test/unit/SettingsPage.experimentalFeatures.lazy.test.ts (1 test) 855ms 409 MB heap used ✓ SettingsPage > loads Experimental Features tab lazily via next/dynamic 855ms ✓ packages/scheduling/tests/scheduleEntryRecurrence.test.ts (22 tests) 11ms 439 MB heap used ❯ packages/msp-composition/src/scheduling/MspSchedulingProvider.test.tsx (2 tests | 2 failed) 1ms 405 MB heap used × MspSchedulingProvider > provides renderAgentSchedule that returns AgentScheduleView 0ms → document is not defined × MspSchedulingProvider > provides launchTimeEntry that calls launchTimeEntryForWorkItem 1ms → document is not defined stdout | packages/billing/src/actions/renderTemplateOnServer.ast.integration.test.ts > renderTemplateOnServer AST integration > renders template HTML/CSS from canonical AST payload [Server Action] Successfully rendered template: tpl-1 ✓ packages/billing/src/actions/renderTemplateOnServer.ast.integration.test.ts (2 tests) 2ms 414 MB heap used ✓ ee/server/src/__tests__/unit/tenant-creation.test.ts (4 tests) 0ms 425 MB heap used stdout | server/src/test/e2e/api/tickets.e2e.test.ts > Ticket API E2E Tests Initializing composite secret provider system Building composite secret provider. Read chain: [env, filesystem], Write provider: filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/e2e/api/tickets.e2e.test.ts > Ticket API E2E Tests CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/e2e/api/tickets.e2e.test.ts > Ticket API E2E Tests CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/api/tickets.e2e.test.ts > Ticket API E2E Tests Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/api/tickets.e2e.test.ts > Ticket API E2E Tests CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/api/tickets.e2e.test.ts > Ticket API E2E Tests Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/e2e/api/tickets.e2e.test.ts (47 tests | 47 skipped) 79ms 441 MB heap used ↓ Ticket API E2E Tests > Authentication > should require API key for all endpoints ↓ Ticket API E2E Tests > Authentication > should reject invalid API key ↓ Ticket API E2E Tests > CRUD Operations > Create Ticket (POST /api/v1/tickets) > should create a new ticket ↓ Ticket API E2E Tests > CRUD Operations > Create Ticket (POST /api/v1/tickets) > should validate required fields ↓ Ticket API E2E Tests > CRUD Operations > Create Ticket (POST /api/v1/tickets) > should create ticket with all optional fields ↓ Ticket API E2E Tests > CRUD Operations > Get Ticket (GET /api/v1/tickets/:id) > should retrieve a ticket by ID ↓ Ticket API E2E Tests > CRUD Operations > Get Ticket (GET /api/v1/tickets/:id) > should return 404 for non-existent ticket ↓ Ticket API E2E Tests > CRUD Operations > Get Ticket (GET /api/v1/tickets/:id) > should not return tickets from other tenants ↓ Ticket API E2E Tests > CRUD Operations > Update Ticket (PUT /api/v1/tickets/:id) > should update a ticket ↓ Ticket API E2E Tests > CRUD Operations > Update Ticket (PUT /api/v1/tickets/:id) > should return 404 when updating non-existent ticket ↓ Ticket API E2E Tests > CRUD Operations > Update Ticket (PUT /api/v1/tickets/:id) > should validate update data ↓ Ticket API E2E Tests > CRUD Operations > Delete Ticket (DELETE /api/v1/tickets/:id) > should delete a ticket ↓ Ticket API E2E Tests > CRUD Operations > Delete Ticket (DELETE /api/v1/tickets/:id) > should return 404 when deleting non-existent ticket ↓ Ticket API E2E Tests > List Tickets (GET /api/v1/tickets) > should list all tickets with default pagination ↓ Ticket API E2E Tests > List Tickets (GET /api/v1/tickets) > should support pagination parameters ↓ Ticket API E2E Tests > List Tickets (GET /api/v1/tickets) > should filter by client_id ↓ Ticket API E2E Tests > List Tickets (GET /api/v1/tickets) > should filter by status ↓ Ticket API E2E Tests > List Tickets (GET /api/v1/tickets) > should filter by priority ↓ Ticket API E2E Tests > List Tickets (GET /api/v1/tickets) > should filter by assigned user ↓ Ticket API E2E Tests > List Tickets (GET /api/v1/tickets) > should filter overdue tickets ↓ Ticket API E2E Tests > List Tickets (GET /api/v1/tickets) > should sort tickets by created date ↓ Ticket API E2E Tests > Search Tickets (GET /api/v1/tickets/search) > should search tickets by query ↓ Ticket API E2E Tests > Search Tickets (GET /api/v1/tickets/search) > should search in specified fields ↓ Ticket API E2E Tests > Search Tickets (GET /api/v1/tickets/search) > should limit search results ↓ Ticket API E2E Tests > Ticket Comments (POST /api/v1/tickets/:id/comments) > should add a comment to a ticket ↓ Ticket API E2E Tests > Ticket Comments (POST /api/v1/tickets/:id/comments) > should add an internal comment ↓ Ticket API E2E Tests > Ticket Comments (POST /api/v1/tickets/:id/comments) > should list ticket comments ↓ Ticket API E2E Tests > Ticket Comments (POST /api/v1/tickets/:id/comments) > should return 404 when adding comment to non-existent ticket ↓ Ticket API E2E Tests > Ticket Status Updates (PUT /api/v1/tickets/:id/status) > should update ticket status ↓ Ticket API E2E Tests > Ticket Status Updates (PUT /api/v1/tickets/:id/status) > should validate status transitions ↓ Ticket API E2E Tests > Ticket Assignment (PUT /api/v1/tickets/:id/assignment) > should assign ticket to user ↓ Ticket API E2E Tests > Ticket Assignment (PUT /api/v1/tickets/:id/assignment) > should unassign ticket ↓ Ticket API E2E Tests > Ticket Statistics (GET /api/v1/tickets/stats) > should return ticket statistics ↓ Ticket API E2E Tests > Ticket Statistics (GET /api/v1/tickets/stats) > should filter statistics by date range ↓ Ticket API E2E Tests > Ticket Statistics (GET /api/v1/tickets/stats) > should filter statistics by client ↓ Ticket API E2E Tests > Create Ticket from Asset (POST /api/v1/tickets/from-asset) > should create ticket from asset ↓ Ticket API E2E Tests > Error Handling > should handle invalid UUID format ↓ Ticket API E2E Tests > Error Handling > should handle invalid query parameters ↓ Ticket API E2E Tests > Error Handling > should handle missing required fields on create ↓ Ticket API E2E Tests > Error Handling > should handle invalid date formats ↓ Ticket API E2E Tests > Permissions > should enforce read permissions for GET endpoints ↓ Ticket API E2E Tests > Permissions > should enforce write permissions for POST/PUT/DELETE ↓ Ticket API E2E Tests > Permissions > should enforce assignment permissions ↓ Ticket API E2E Tests > Multi-tenancy > should isolate tickets by tenant ↓ Ticket API E2E Tests > Advanced Features > should support bulk operations ↓ Ticket API E2E Tests > Advanced Features > should support ticket templates ↓ Ticket API E2E Tests > Advanced Features > should track ticket history ✓ ee/server/src/lib/extensions/__tests__/gateway/gateway-utils.test.ts (13 tests) 2ms 445 MB heap used ✓ packages/tickets/src/actions/ticketActions.ticketOrigin.test.ts (4 tests) 20ms 455 MB heap used stdout | server/src/test/e2e/email-settings/email-threading.test.ts Initializing composite secret provider system Building composite secret provider. Read chain: [env, filesystem], Write provider: filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/e2e/email-settings/email-threading.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/e2e/email-settings/email-threading.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/email-settings/email-threading.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/email-settings/email-threading.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/email-settings/email-threading.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/email-settings/email-threading.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/email-settings/email-threading.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/e2e/email-settings/email-threading.test.ts > Email Threading Tests 🏗️ Initializing Email Settings Test Fixture (one-time setup)... 📊 Setting up database and services... 🚀 Initializing E2E Test Context... 🔧 Set E2E environment variables: { DB_HOST: 'localhost', DB_PORT: '5433', DB_NAME_SERVER: 'server_test', DB_USER_ADMIN: 'postgres', PGBOUNCER_HOST: 'localhost', PGBOUNCER_PORT: '6434', REDIS_HOST: 'localhost', REDIS_PORT: '6380', EMAIL_HOST: 'localhost', EMAIL_PORT: '1025' } stdout | server/src/test/e2e/email-settings/email-threading.test.ts > Email Threading Tests CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/e2e/email-settings/email-threading.test.ts > Email Threading Tests Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/e2e/email-settings/email-threading.test.ts > Email Threading Tests CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/e2e/email-settings/email-threading.test.ts > Email Threading Tests Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/e2e/email-settings/email-threading.test.ts (3 tests | 3 skipped) 2ms 465 MB heap used ↓ Email Threading Tests > Email to Ticket Flow > should create ticket from initial email ↓ Email Threading Tests > Reply Threading > should add reply as comment to existing ticket ↓ Email Threading Tests > Thread ID Preservation > should maintain thread ID across email exchanges stdout | packages/db/src/lib/tenantContext.test.ts > tenant context > createTenantKnex falls back to AsyncLocalStorage tenant context [db/tenant] Database configuration { client: 'postgres', connection: { host: 'localhost', port: 5432, database: 'db', user: 'user', password: 'pw' }, pool: {} } stdout | packages/db/src/lib/tenantContext.test.ts > tenant context > createTenantKnex uses an explicit tenant id when provided [db/tenant] Database configuration { client: 'postgres', connection: { host: 'localhost', port: 5432, database: 'db', user: 'user', password: 'pw' }, pool: {} } ✓ packages/db/src/lib/tenantContext.test.ts (2 tests) 5ms 471 MB heap used ❯ ee/temporal-workflows/src/activities/__tests__/email-activities.temporal.test.ts (11 tests | 10 failed) 136ms 438 MB heap used × Email Activities - Temporal Unit Tests > Password Generation with Temporal Context > should generate secure passwords with proper entropy 1ms → expected Promise{…} to have property 'length' × Email Activities - Temporal Unit Tests > Password Generation with Temporal Context > should handle various password lengths correctly 0ms → expected Promise{…} to have property 'length' ✓ Email Activities - Temporal Unit Tests > Password Generation with Temporal Context > should ensure consistent randomness across calls 0ms × Email Activities - Temporal Unit Tests > Email Activity Direct Testing > should send welcome email with valid input 0ms → Cannot read properties of undefined (reading 'info') × Email Activities - Temporal Unit Tests > Email Activity Direct Testing > should handle invalid email addresses gracefully 0ms → Cannot read properties of undefined (reading 'info') × Email Activities - Temporal Unit Tests > Email Activity Direct Testing > should handle empty email addresses 0ms → Cannot read properties of undefined (reading 'info') × Email Activities - Temporal Unit Tests > Email Activity Direct Testing > should work with minimal required fields 0ms → Cannot read properties of undefined (reading 'info') × Email Activities - Temporal Unit Tests > Email Template Generation > should generate proper email content structure 0ms → Cannot read properties of undefined (reading 'info') × Email Activities - Temporal Unit Tests > Email Template Generation > should handle template variable substitution 0ms → Cannot read properties of undefined (reading 'info') × Email Activities - Temporal Unit Tests > Error Handling and Resilience > should not throw exceptions on failure 0ms → Cannot read properties of undefined (reading 'info') × Email Activities - Temporal Unit Tests > Error Handling and Resilience > should handle missing required fields gracefully 0ms → Cannot read properties of undefined (reading 'info') ✓ shared/lib/utils/emailFileConversion.test.ts (4 tests) 4ms 446 MB heap used ❯ ee/extensions/samples/ui-kit-showcase/test/theme.test.tsx (3 tests | 3 failed) 1ms 450 MB heap used × theme bridge (postMessage) > applyTheme sets CSS variables on document root 0ms → document is not defined × theme bridge (postMessage) > message handler applies theme from Alga envelope format 0ms → document is not defined × theme bridge (postMessage) > ignores non-Alga messages 0ms → document is not defined stdout | server/src/test/integration/accounting/externalTaxImport.integration.test.ts > External Tax Import Initializing composite secret provider system Building composite secret provider. Read chain: [env, filesystem], Write provider: filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/accounting/externalTaxImport.integration.test.ts > External Tax Import CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/accounting/externalTaxImport.integration.test.ts > External Tax Import CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/accounting/externalTaxImport.integration.test.ts > External Tax Import Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/accounting/externalTaxImport.integration.test.ts > External Tax Import CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/accounting/externalTaxImport.integration.test.ts > External Tax Import Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/integration/accounting/externalTaxImport.integration.test.ts (14 tests | 14 skipped) 2ms 462 MB heap used ↓ External Tax Import > importing tax from external accounting system > should update invoice charges with tax amounts from QuickBooks ↓ External Tax Import > importing tax from external accounting system > should change invoice tax_source from pending_external to external ↓ External Tax Import > importing tax from external accounting system > should create audit record in external_tax_imports table ↓ External Tax Import > importing tax from external accounting system > should update invoice total_amount to include imported tax ↓ External Tax Import > tax allocation across charges > should apply per-line tax amounts from external system ↓ External Tax Import > tax allocation across charges > should handle mix of taxable and non-taxable items ↓ External Tax Import > tax allocation across charges > should handle different tax rates across items ↓ External Tax Import > tax allocation across charges > should distribute proportionally when line matching fails ↓ External Tax Import > tax allocation across charges > should match by charge ID even when external lines are returned out of order ↓ External Tax Import > internal tax calculation is skipped for external delegation > should set tax to zero when invoice has pending_external tax source ↓ External Tax Import > automatic tax import after export > should automatically import tax after exporting invoice with tax delegation ↓ External Tax Import > error handling > should fail if invoice is not pending_external ↓ External Tax Import > error handling > should fail if invoice has no external mapping ↓ External Tax Import > error handling > should fail if external system returns error ✓ server/src/test/unit/internal-notifications/mentionParser.test.ts (28 tests) 2ms 467 MB heap used stdout | server/src/test/integration/googleProviderDatabaseSave.test.ts Initializing composite secret provider system Building composite secret provider. Read chain: [env, filesystem], Write provider: filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/integration/googleProviderDatabaseSave.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/integration/googleProviderDatabaseSave.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/googleProviderDatabaseSave.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/googleProviderDatabaseSave.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/googleProviderDatabaseSave.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/googleProviderDatabaseSave.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/googleProviderDatabaseSave.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/integration/googleProviderDatabaseSave.test.ts > Google Provider Database Save Integration Tests CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/integration/googleProviderDatabaseSave.test.ts > Google Provider Database Save Integration Tests Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/integration/googleProviderDatabaseSave.test.ts > Google Provider Database Save Integration Tests CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/integration/googleProviderDatabaseSave.test.ts > Google Provider Database Save Integration Tests Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/integration/googleProviderDatabaseSave.test.ts (6 tests | 6 skipped) 2ms 479 MB heap used ↓ Google Provider Database Save Integration Tests > Creating Google Provider via Service > should save a complete Google provider configuration to the database ↓ Google Provider Database Save Integration Tests > Creating Google Provider via Service > should handle Gmail-specific email addresses correctly ↓ Google Provider Database Save Integration Tests > Creating Google Provider via Service > should handle Google Workspace custom domain emails ↓ Google Provider Database Save Integration Tests > Creating Google Provider via Service > should save OAuth tokens when provided ↓ Google Provider Database Save Integration Tests > Creating Google Provider via Service > should validate required fields for Google provider ↓ Google Provider Database Save Integration Tests > Creating Google Provider via Service > should properly format and save all Google-specific configuration options ✓ packages/client-portal/src/components/tickets/TicketDetails.originBadge.contract.test.ts (3 tests) 1ms 490 MB heap used stdout | shared/services/email/__tests__/EmailWebhookMaintenanceService.test.ts Initializing composite secret provider system Building composite secret provider. Read chain: [env, filesystem], Write provider: filesystem EnvSecretProvider initialized without prefix stdout | shared/services/email/__tests__/EmailWebhookMaintenanceService.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | shared/services/email/__tests__/EmailWebhookMaintenanceService.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | shared/services/email/__tests__/EmailWebhookMaintenanceService.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | shared/services/email/__tests__/EmailWebhookMaintenanceService.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | shared/services/email/__tests__/EmailWebhookMaintenanceService.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | shared/services/email/__tests__/EmailWebhookMaintenanceService.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | shared/services/email/__tests__/EmailWebhookMaintenanceService.test.ts Retrieved secret 'db_password_server' from configured provider. ❯ shared/services/email/__tests__/EmailWebhookMaintenanceService.test.ts (3 tests | 1 failed) 2ms 506 MB heap used ✓ EmailWebhookMaintenanceService > should find candidates and renew expired subscription 0ms × EmailWebhookMaintenanceService > should recreate subscription if renewal fails with 404 1ms → expected "spy" to be called with arguments: [ 'https://api.example.com/webhook' ] Number of calls: 0 ✓ EmailWebhookMaintenanceService > should handle unexpected errors gracefully 1ms ❯ ee/server/extensions/samples/ui-kit-showcase/test/theme.test.tsx (3 tests | 3 failed) 0ms 461 MB heap used × theme bridge (postMessage) > applyTheme sets CSS variables on document root 0ms → document is not defined × theme bridge (postMessage) > message handler applies theme from Alga envelope format 0ms → document is not defined × theme bridge (postMessage) > ignores non-Alga messages 0ms → document is not defined ✓ packages/projects/tests/packageDependencies.test.ts (1 test) 0ms 465 MB heap used ✓ server/src/test/unit/services/numberingService.test.ts (5 tests) 1ms 470 MB heap used stdout | server/src/test/unit/services/chatCompletionsService.streaming.test.ts > ChatCompletionsService (streaming) > passes stream: true to OpenRouter OpenAI client Initializing composite secret provider system Building composite secret provider. Read chain: [env, filesystem], Write provider: filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/services/chatCompletionsService.streaming.test.ts > ChatCompletionsService (streaming) > passes stream: true to OpenRouter OpenAI client CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/services/chatCompletionsService.streaming.test.ts > ChatCompletionsService (streaming) > passes stream: true to OpenRouter OpenAI client CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/services/chatCompletionsService.streaming.test.ts > ChatCompletionsService (streaming) > passes stream: true to OpenRouter OpenAI client Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/services/chatCompletionsService.streaming.test.ts > ChatCompletionsService (streaming) > passes stream: true to OpenRouter OpenAI client CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/services/chatCompletionsService.streaming.test.ts > ChatCompletionsService (streaming) > passes stream: true to OpenRouter OpenAI client Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/services/chatCompletionsService.streaming.test.ts > ChatCompletionsService (streaming) > passes stream: true to OpenRouter OpenAI client CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/services/chatCompletionsService.streaming.test.ts > ChatCompletionsService (streaming) > passes stream: true to OpenRouter OpenAI client Retrieved secret 'db_password_server' from configured provider. ✓ server/src/test/unit/services/chatCompletionsService.streaming.test.ts (1 test) 93ms 483 MB heap used stdout | server/src/test/unit/email/outboundMessageIdStorage.test.ts > Outbound Message-ID Storage Initializing composite secret provider system Building composite secret provider. Read chain: [env, filesystem], Write provider: filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/email/outboundMessageIdStorage.test.ts > Outbound Message-ID Storage CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/email/outboundMessageIdStorage.test.ts > Outbound Message-ID Storage CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/email/outboundMessageIdStorage.test.ts > Outbound Message-ID Storage Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/email/outboundMessageIdStorage.test.ts > Outbound Message-ID Storage CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/email/outboundMessageIdStorage.test.ts > Outbound Message-ID Storage Retrieved secret 'db_password_server' from configured provider. ❯ server/src/test/unit/email/outboundMessageIdStorage.test.ts (6 tests | 6 skipped) 1ms 493 MB heap used ↓ Outbound Message-ID Storage > Message-ID References Storage > should store outbound Message-ID in ticket email_metadata references array ↓ Outbound Message-ID Storage > Message-ID References Storage > should append multiple Message-IDs to references array ↓ Outbound Message-ID Storage > Message-ID References Storage > should initialize empty references array if email_metadata is null ↓ Outbound Message-ID Storage > Message-ID References Storage > should preserve existing email_metadata fields when adding references ↓ Outbound Message-ID Storage > Message-ID References Storage > should handle Message-ID format variations correctly ↓ Outbound Message-ID Storage > Message-ID Storage Integration > should support full email conversation thread via references ❯ ee/temporal-workflows/src/test-utils/test-connection.test.ts (3 tests | 1 failed) 118ms 499 MB heap used ✓ Temporal Connection Tests > should connect to temporalio/auto-setup Docker container 6ms ✓ Temporal Connection Tests > should create TestWorkflowEnvironment for unit tests 110ms × Temporal Connection Tests > should verify Docker Postgres connection 2ms → ✓ packages/msp-composition/src/packageDependencies.test.ts (1 test) 0ms 503 MB heap used stdout | server/src/test/infrastructure/billing/credits/creditExpirationEffects.test.ts Initializing composite secret provider system Building composite secret provider. Read chain: [env, filesystem], Write provider: filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/infrastructure/billing/credits/creditExpirationEffects.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/infrastructure/billing/credits/creditExpirationEffects.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/infrastructure/billing/credits/creditExpirationEffects.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/infrastructure/billing/credits/creditExpirationEffects.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/infrastructure/billing/credits/creditExpirationEffects.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/infrastructure/billing/credits/creditExpirationEffects.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/infrastructure/billing/credits/creditExpirationEffects.test.ts Retrieved secret 'db_password_server' from configured provider. ✓ server/src/test/unit/email/replyTokenExtraction.test.ts (10 tests) 3ms 519 MB heap used ✓ packages/billing/tests/deleteContractPermissions.test.ts (1 test) 23ms 465 MB heap used ❯ server/src/test/unit/workflow/visualization/astParser.test.ts (1 test | 1 failed) 457ms 651 MB heap used × AST Parser and Analyzer > should parse and analyze the invoice approval workflow 457ms → Could not find source file: /Users/roberisaacs/alga-psa.worktrees/codex/feature-invoice-designer/src/lib/workflow/examples/invoiceApprovalWorkflow.ts ✓ server/src/test/integration/emailProviderIntegration.test.ts (11 tests) 6ms 662 MB heap used ✓ packages/types/src/interfaces/invoice-template-ast-contract.typecheck.test.ts (1 test) 0ms 666 MB heap used ✓ packages/ui/src/context/index.test.ts (1 test) 0ms 671 MB heap used stdout | server/src/test/infrastructure/time-periods/timePeriodsActions.test.ts Initializing composite secret provider system Building composite secret provider. Read chain: [env, filesystem], Write provider: filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/infrastructure/time-periods/timePeriodsActions.test.ts CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/infrastructure/time-periods/timePeriodsActions.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/infrastructure/time-periods/timePeriodsActions.test.ts Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/infrastructure/time-periods/timePeriodsActions.test.ts CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/infrastructure/time-periods/timePeriodsActions.test.ts Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/infrastructure/time-periods/timePeriodsActions.test.ts CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/infrastructure/time-periods/timePeriodsActions.test.ts Retrieved secret 'db_password_server' from configured provider. ❯ server/src/lib/extensions/ui/iframeBridge.test.ts (5 tests | 5 failed) 3ms 673 MB heap used × bootstrapIframe (host bridge) > applies sandbox="allow-scripts" by default when none provided 0ms → window is not defined × bootstrapIframe (host bridge) > throws when allowedOrigin mismatches iframe src origin and RUNNER_PUBLIC_BASE is absolute 0ms → window is not defined × bootstrapIframe (host bridge) > sends bootstrap message with envelope version after load 0ms → window is not defined × bootstrapIframe (host bridge) > adjusts iframe height on resize messages with clamping 0ms → window is not defined × bootstrapIframe (host bridge) > validates contentHash format 1ms → window is not defined ✓ server/src/test/unit/workflowRunDialogEventUtils.test.ts (3 tests) 1ms 681 MB heap used > server@0.16.5 start:express > tsx index.ts ❯ server/src/test/e2e/api/clients.e2e.test.ts (22 tests | 22 skipped) 1007ms 692 MB heap used ↓ Clients API E2E Tests > Authentication > should reject requests without API key ↓ Clients API E2E Tests > Authentication > should reject requests with invalid API key ↓ Clients API E2E Tests > Authentication > should accept requests with valid API key ↓ Clients API E2E Tests > CRUD Operations > should create a client ↓ Clients API E2E Tests > CRUD Operations > should get a client by ID ↓ Clients API E2E Tests > CRUD Operations > should update a client ↓ Clients API E2E Tests > CRUD Operations > should delete a client ↓ Clients API E2E Tests > CRUD Operations > should list clients with pagination ↓ Clients API E2E Tests > Client Locations > should create a client location ↓ Clients API E2E Tests > Client Locations > should get client locations ↓ Clients API E2E Tests > Client Contacts > should get client contacts ↓ Clients API E2E Tests > Client Statistics > should get client statistics ↓ Clients API E2E Tests > Error Handling > should return 404 for non-existent client ↓ Clients API E2E Tests > Error Handling > should return 400 for invalid client data ↓ Clients API E2E Tests > Error Handling > should return 400 for invalid UUID ↓ Clients API E2E Tests > Filtering and Search > should filter clients by active status ↓ Clients API E2E Tests > Filtering and Search > should search clients by name ↓ Clients API E2E Tests > Inactive Client Behavior > should set all contacts and users to inactive when client is set to inactive ↓ Clients API E2E Tests > Inactive Client Behavior > should allow reactivating only the client, leaving contacts inactive ↓ Clients API E2E Tests > Inactive Client Behavior > should allow reactivating client and all contacts/users together ↓ Clients API E2E Tests > Permissions > should enforce read permissions for listing ↓ Clients API E2E Tests > Permissions > should enforce create permissions ✓ packages/scheduling/src/lib/__tests__/capacityThresholdWorkflowEvents.test.ts (3 tests) 1ms 697 MB heap used ❯ ee/temporal-workflows/src/activities/__tests__/portal-domain-reconcile.integration.test.ts (2 tests | 2 failed) 1ms 701 MB heap used × applyPortalDomainResources > routes virtual service traffic to the app once certificate succeeds 0ms → Missing "./admin.js" specifier in "@alga-psa/db" package × applyPortalDomainResources > creates new manifests and prunes legacy virtual services when the domain changes 0ms → Missing "./admin.js" specifier in "@alga-psa/db" package ✓ packages/billing/tests/contractsActivationFlow.test.tsx (2 tests) 356ms 88 MB heap used ❯ server/src/test/unit/Chat.streamingIncrementalState.test.tsx (9 tests | 8 failed) 54ms 278 MB heap used ✓ EE Chat (streaming state) > updates the in-progress assistant message as tokens arrive 30ms × EE Chat (streaming state) > aborts the streaming request when Stop is clicked 3ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
     Contracts  
 
 
 Templates | Client Contracts | Drafts 
 
         
 
   No draft contracts. Start creating a new contract to save as draft.       
           You  
   

 Ping 

                     Alga     

 Hello 

                  Press Ctrl+Enter or ⌘+Enter to send. 

   SEND    
 
  
 
  OK  
 
   
       I am Alga! Your favorite AI assistant. Ask me a question.  
         Press Ctrl+Enter or ⌘+Enter to send. 

   SEND    
 
  
 
  OK  
 
   
       I am Alga! Your favorite AI assistant. Ask me a question.  
         Press Ctrl+Enter or ⌘+Enter to send. 

   SEND    
 
  
 
  OK  
 
   
       I am Alga! Your favorite AI assistant. Ask me a question.  
         Press Ctrl+Enter or ⌘+Enter to send. 

   SEND    
 
  
 
  OK  
 
    × EE Chat (streaming state) > stops updating token display and ends generation state after Stop 3ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
     Contracts  
 
 
 Templates | Client Contracts | Drafts 
 
         
 
   No draft contracts. Start creating a new contract to save as draft.       
           You  
   

 Ping 

                 shows a streaming cursor while receiving tokens 3ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
     Contracts  
 
 
 Templates | Client Contracts | Drafts 
 
         
 
   No draft contracts. Start creating a new contract to save as draft.       
           You  
   

 Ping 

                 removes the streaming cursor when done is received 3ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
     Contracts  
 
 
 Templates | Client Contracts | Drafts 
 
         
 
   No draft contracts. Start creating a new contract to save as draft.       
           You  
   

 Ping 

                 shows the partial response when a network error occurs mid-stream 4ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
     Contracts  
 
 
 Templates | Client Contracts | Drafts 
 
         
 
   No draft contracts. Start creating a new contract to save as draft.       
           You  
   

 Ping 

                     Alga     

 Hello 

                  Press Ctrl+Enter or ⌘+Enter to send. 

   SEND    
 
  
 
  OK  
 
   
       I am Alga! Your favorite AI assistant. Ask me a question.  
         Press Ctrl+Enter or ⌘+Enter to send. 

   SEND    
 
  
 
  OK  
 
    × EE Chat (streaming state) > shows an interruption indicator when the stream ends without done=true 3ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
     Contracts  
 
 
 Templates | Client Contracts | Drafts 
 
         
 
   No draft contracts. Start creating a new contract to save as draft.       
           You  
   

 Ping 

                     Alga     

 Hello 

                  Press Ctrl+Enter or ⌘+Enter to send. 

   SEND    
 
  
 
  OK  
 
   
       I am Alga! Your favorite AI assistant. Ask me a question.  
         Press Ctrl+Enter or ⌘+Enter to send. 

   SEND    
 
  
 
  OK  
 
   
       I am Alga! Your favorite AI assistant. Ask me a question.  
         Press Ctrl+Enter or ⌘+Enter to send. 

   SEND    
 
  
 
  OK  
 
    × EE Chat (streaming state) > persists the assistant message after streaming completes 3ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
     Contracts  
 
 
 Templates | Client Contracts | Drafts 
 
         
 
   No draft contracts. Start creating a new contract to save as draft.       
           You  
   

 Ping 

                 persists assistant content matching the final streamed tokens 3ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
     Contracts  
 
 
 Templates | Client Contracts | Drafts 
 
         
 
   No draft contracts. Start creating a new contract to save as draft.       
           You  
   

 Ping 

                 shows 'AI Assistant' name and description 9ms × ExperimentalFeaturesSettings > defaults AI Assistant toggle to off 3ms → expected 'true' to be 'false' // Object.is equality × ExperimentalFeaturesSettings > renders experimental features warning banner 1005ms → Found multiple elements with the text: Experimental Here are the matching elements: Ignored nodes: comments, script, style  Experimental  Ignored nodes: comments, script, style  Experimental  Ignored nodes: comments, script, style  Experimental  Ignored nodes: comments, script, style  Experimental  Ignored nodes: comments, script, style  Experimental  Ignored nodes: comments, script, style  Experimental  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
     Contracts  
 
 
 Templates | Client Contracts | Drafts 
 
         
 
   No draft contracts. Start creating a new contract to save as draft.       
           You  
   

 Ping 

                 
     Contracts  
 
 
 Templates | Client Contracts | Drafts 
 
         
 
   No draft contracts. Start creating a new contract to save as draft.       
           You  
   

 Ping 

                 calls updateExperimentalFeatures() with current toggle states on save 1009ms → Found multiple elements with the role "button" and name "Save" Here are the matching elements: Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
     Contracts  
 
 
 Templates | Client Contracts | Drafts 
 
         
 
   No draft contracts. Start creating a new contract to save as draft.       
           You  
   

 Ping 

                 
     Contracts  
 
 
 Templates | Client Contracts | Drafts 
 
         
 
   No draft contracts. Start creating a new contract to save as draft.       
           You  
   

 Ping 

                 shows success feedback after saving 1008ms → Found multiple elements with the role "button" and name "Save" Here are the matching elements: Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  Ignored nodes: comments, script, style  Save  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
     Contracts  
 
 
 Templates | Client Contracts | Drafts 
 
         
 
   No draft contracts. Start creating a new contract to save as draft.       
           You  
   

 Ping 

                 
     Contracts  
 
 
 Templates | Client Contracts | Drafts 
 
         
 
   No draft contracts. Start creating a new contract to save as draft.       
           You  
   

 Ping 

                 updates local state when toggled 4ms ✓ ExperimentalFeaturesSettings > loads current settings on mount 3ms × ExperimentalFeaturesSettings > renders list of features with toggles 9ms → expected [ , …(9) ] to have a length of 2 but got 10 × ExperimentalFeaturesSettings > disables AI Assistant toggle when not allowed 4ms → expected 'true' to be 'false' // Object.is equality ✓ packages/billing/src/components/billing-dashboard/InvoiceTemplateEditor.previewWorkspace.test.tsx (11 tests) 131ms 291 MB heap used ❯ server/src/test/unit/RightSidebar.streaming.test.tsx (1 test | 1 failed) 1007ms 289 MB heap used × RightSidebar (streaming) > renders streaming Chat and posts to the streaming completions endpoint 1007ms → Found multiple elements with the placeholder text of: Send a message Here are the matching elements: Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  Ignored nodes: comments, script, style  (If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)). Ignored nodes: comments, script, style  
           You  
   

 Ping 

                     Alga     

 Hello 

                  Press Ctrl+Enter or ⌘+Enter to send. 

   SEND    
 
  
 
  OK  
 
   
  ... Ignored nodes: comments, script, style  
           You  
 
  

 Ping 

                     Alga     

 Hello 

                  Press Ctrl+Enter or ⌘+Enter to send. 

   SEND    
 
  
 
  OK  
 
   
  ... ✓ packages/billing/src/components/invoice-designer/canvas/DesignCanvas.constraintHighlights.test.tsx (2 tests) 22ms 296 MB heap used ✓ packages/projects/tests/projectInfoDrawer.test.tsx (1 test) 27ms 322 MB heap used stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/BillingCyclesDashboardSummary.ui.test.tsx Retrieved secret 'db_password_server' from configured provider. ✓ server/src/test/unit/components/AssetNotesPanel.test.tsx (1 test) 2ms 294 MB heap used ✓ server/src/test/unit/tickets/TicketEmailNotifications.ui.test.tsx (7 tests) 112ms 312 MB heap used stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.poBanner.ui.test.tsx Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.poBanner.ui.test.tsx CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.poBanner.ui.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.poBanner.ui.test.tsx Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.poBanner.ui.test.tsx CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.poBanner.ui.test.tsx Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.poBanner.ui.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.poBanner.ui.test.tsx Retrieved secret 'db_password_server' from configured provider. ✓ packages/billing/src/components/invoice-designer/DesignerShell.constraints.test.tsx (23 tests) 599ms 210 MB heap used ✓ packages/billing/src/components/invoice-designer/canvas/DesignCanvas.previewMode.test.tsx (15 tests) 14ms 226 MB heap used stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx Retrieved secret 'db_password_server' from configured provider. stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx Retrieved secret 'postgres_password' from configured provider. stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | server/src/test/unit/billing/contractPurchaseOrderSupport.ui.test.tsx Retrieved secret 'db_password_server' from configured provider. stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx Initializing secret provider (legacy mode with composite fallback). Using read chain [env, filesystem] with write provider filesystem EnvSecretProvider initialized without prefix stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx CompositeSecretProvider initialized with 2 read providers and 1 write provider stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx Retrieved secret 'db_password_server' from configured provider. stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx CompositeSecretProvider found app secret 'postgres_password' from provider 1 stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx Retrieved secret 'postgres_password' from configured provider. stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx CompositeSecretProvider found app secret 'db_password_server' from provider 1 stdout | packages/tickets/src/components/ticket/__tests__/TicketDetailsCreateTask.test.tsx Retrieved secret 'db_password_server' from configured provider. stdout | ee/server/src/__tests__/integration/extensionProxyFlow.test.ts > Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should handle Gateway errors and return error message to Client iframeBridge: received message { type: 'apiproxy', origin: 'http://localhost:3000' } iframeBridge: handling apiproxy { requestId: 'req-error', route: '/error-route' } stdout | ee/server/src/__tests__/integration/extensionProxyFlow.test.ts > Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should handle Gateway errors and return error message to Client iframeBridge: fetch completed { status: 500, ok: false, url: '/api/ext-proxy/test-extension-id/error-route' } stdout | ee/server/src/__tests__/integration/extensionProxyFlow.test.ts > Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should handle Gateway errors and return error message to Client iframeBridge: posting apiproxy_response { requestId: 'req-error', targetOrigin: '*' } stdout | ee/server/src/__tests__/integration/extensionProxyFlow.test.ts > Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should forward "apiproxy" message to Gateway and return response to Client iframeBridge: received message { type: 'apiproxy', origin: 'http://localhost:3000' } iframeBridge: handling apiproxy { requestId: 'req-123', route: '/tickets' } iframeBridge: posting apiproxy_response { requestId: 'req-123', targetOrigin: '*' } ❯ ee/server/src/__tests__/integration/extensionProxyFlow.test.ts (4 tests | 3 failed) 139ms 242 MB heap used × Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should forward "apiproxy" message to Gateway and return response to Client 57ms → expected "spy" to be called with arguments: [ StringContaining{…}, …(1) ] Number of calls: 0 ✓ Extension Proxy Flow Integration > Host Bridge (Client -> Host) > should handle Gateway errors and return error message to Client 56ms × Extension Proxy Flow Integration > Gateway Handler (Host -> Runner) > should forward request to RunnerBackend and propagate response headers/body 2ms → Failed to resolve import "@alga-psa/db/models/UserSession" from "packages/auth/src/lib/nextAuthOptions.ts". Does the file exist? × Extension Proxy Flow Integration > Gateway Handler (Host -> Runner) > should handle Runner errors gracefully 24ms → Failed to resolve import "@alga-psa/db/models/UserSession" from "packages/auth/src/lib/nextAuthOptions.ts". Does the file exist? ❯ packages/billing/tests/contractWizardResume.test.tsx (14 tests | 14 failed) 30ms 267 MB heap used × ContractWizard resume behavior > starts at Step 1 (Contract Basics) when opened (T033) 2ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 1 shows pre-populated client selection from draft (T034) 14ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 1 shows pre-populated contract name from draft (T035) 1ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 1 shows pre-populated dates from draft (T036) 1ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 2 (Fixed Fee) shows pre-populated services from draft (T037) 1ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 3 (Products) shows pre-populated products from draft (T038) 1ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 4 (Hourly) shows pre-populated hourly services from draft (T039) 1ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 5 (Usage) shows pre-populated usage services from draft (T040) 1ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > step 6 (Review) shows complete draft data for review (T041) 1ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > clicking Save Draft in resumed wizard updates existing draft (T042) 2ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > save draft does not create a duplicate contract (T043) 1ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > save draft preserves the original contract_id (T044) 1ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > completing resumed wizard sets contract status to 'active' (T045) 3ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: × ContractWizard resume behavior > completing resumed wizard sets is_active to true (T046) 1ms → [vitest] No "DialogContent" export is defined on the "@alga-psa/ui/components/Dialog" mock. Did you forget to return it from "vi.mock"? If you need to partially mock a module, you can use "importOriginal" helper inside: ✓ packages/billing/src/components/billing-dashboard/InvoiceTemplateEditor.authoritativeFlow.test.tsx (2 tests) 205ms 265 MB heap used ✓ packages/projects/tests/projectMaterialsDrawer.test.tsx (16 tests) 149ms 280 MB heap used ✓ packages/billing/tests/draftContractsTable.test.tsx (30 tests) 1232ms 360 MB heap used ✓ server/src/test/unit/email/EmailLogsClient.ui.test.tsx (6 tests) 951ms 365 MB heap used ✓ EmailLogsClient > updates results when date range filter changes 309ms ✓ EmailLogsClient > updates results when recipient search changes 304ms ✓ EmailLogsClient > updates results when ticket filter changes 307ms ✓ packages/billing/src/components/invoice-designer/DesignerVisualWorkspace.test.tsx (28 tests) 1537ms 262 MB heap used ✓ DesignerVisualWorkspace > calls paginated invoice search with status=all and query filters 314ms ✓ DesignerVisualWorkspace > renders loading, empty, and error states for existing invoice list 624ms Test Files 527 failed | 74 passed (601) Tests 138 failed | 456 passed | 271 skipped | 1 todo (866) Start at 14:54:45 Duration 25.80s (transform 2.37s, setup 314ms, collect 3.11s, tests 14.90s, environment 233ms, prepare 53ms) (pass). ### 2026-02-12 — T021 implemented - Added `InvoiceTemplateEditor` compiler-cutover wiring test to enforce save-path removal of `extractInvoiceDesignerIr`. - Evidence: `packages/billing/src/components/billing-dashboard/InvoiceTemplateEditor.compilerCutover.test.ts`. Verification: - `NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/components/billing-dashboard/InvoiceTemplateEditor.compilerCutover.test.ts` (pass). ### 2026-02-12 — T022 implemented - Closed save-path regression guard for `generateAssemblyScriptFromIr` usage using the same editor compiler-cutover suite. - Evidence: `packages/billing/src/components/billing-dashboard/InvoiceTemplateEditor.compilerCutover.test.ts`. Verification: - `NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/components/billing-dashboard/InvoiceTemplateEditor.compilerCutover.test.ts` (pass). ### 2026-02-12 — T023 implemented - Marked type-contract coverage for canonical templateAst payloads without legacy compile assumptions as implemented. - Evidence: packages/types/src/interfaces/invoice-template-ast-contract.typecheck.test.ts Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/types/src/interfaces/invoice-template-ast-contract.typecheck.test.ts packages/billing/src/actions/invoiceTemplateAstPersistenceWiring.test.ts packages/billing/src/lib/invoice-template-ast/standardTemplates.test.ts packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts packages/billing/src/actions/invoiceTemplateCompileParity.test.ts' (pass). ### 2026-02-12 — T024 implemented - Marked tenant template save-path AST persistence wiring as implemented. - Evidence: packages/billing/src/actions/invoiceTemplateAstPersistenceWiring.test.ts::uses direct metadata persistence without AssemblyScript compile gating Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/types/src/interfaces/invoice-template-ast-contract.typecheck.test.ts packages/billing/src/actions/invoiceTemplateAstPersistenceWiring.test.ts packages/billing/src/lib/invoice-template-ast/standardTemplates.test.ts packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts packages/billing/src/actions/invoiceTemplateCompileParity.test.ts' (pass). ### 2026-02-12 — T025 implemented - Marked tenant template fetch/select AST payload wiring as implemented. - Evidence: packages/billing/src/actions/invoiceTemplateAstPersistenceWiring.test.ts::includes templateAst in template fetch/select paths Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/types/src/interfaces/invoice-template-ast-contract.typecheck.test.ts packages/billing/src/actions/invoiceTemplateAstPersistenceWiring.test.ts packages/billing/src/lib/invoice-template-ast/standardTemplates.test.ts packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts packages/billing/src/actions/invoiceTemplateCompileParity.test.ts' (pass). ### 2026-02-12 — T026 implemented - Marked standard template AST loadability as implemented. - Evidence: packages/billing/src/lib/invoice-template-ast/standardTemplates.test.ts + invoiceTemplateAstPersistenceWiring.test.ts Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/types/src/interfaces/invoice-template-ast-contract.typecheck.test.ts packages/billing/src/actions/invoiceTemplateAstPersistenceWiring.test.ts packages/billing/src/lib/invoice-template-ast/standardTemplates.test.ts packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts packages/billing/src/actions/invoiceTemplateCompileParity.test.ts' (pass). ### 2026-02-12 — T027 implemented - Marked preview action AST validation+evaluator+renderer integration path as implemented. - Evidence: packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts::executes AST validation + evaluator + renderer path Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/types/src/interfaces/invoice-template-ast-contract.typecheck.test.ts packages/billing/src/actions/invoiceTemplateAstPersistenceWiring.test.ts packages/billing/src/lib/invoice-template-ast/standardTemplates.test.ts packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts packages/billing/src/actions/invoiceTemplateCompileParity.test.ts' (pass). ### 2026-02-12 — T028 implemented - Marked preview action regression guard against AssemblyScript compiler command path as implemented. - Evidence: packages/billing/src/actions/invoiceTemplateCompileParity.test.ts::keeps preview action on AST evaluate/render path only Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/types/src/interfaces/invoice-template-ast-contract.typecheck.test.ts packages/billing/src/actions/invoiceTemplateAstPersistenceWiring.test.ts packages/billing/src/lib/invoice-template-ast/standardTemplates.test.ts packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts packages/billing/src/actions/invoiceTemplateCompileParity.test.ts' (pass). ### 2026-02-12 — T029 implemented - Marked preview action regression guard against Wasm executor references as implemented. - Evidence: packages/billing/src/actions/invoiceTemplateCompileParity.test.ts + invoiceTemplatePreview.integration.test.ts Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/types/src/interfaces/invoice-template-ast-contract.typecheck.test.ts packages/billing/src/actions/invoiceTemplateAstPersistenceWiring.test.ts packages/billing/src/lib/invoice-template-ast/standardTemplates.test.ts packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts packages/billing/src/actions/invoiceTemplateCompileParity.test.ts' (pass). ### 2026-02-12 — T030 implemented - Marked sample-source preview continuity after AST pipeline swap as implemented. - Evidence: packages/billing/src/components/invoice-designer/DesignerVisualWorkspace.test.tsx::updates sample scenario selection while in Sample source mode Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/components/invoice-designer/DesignerVisualWorkspace.test.tsx packages/billing/src/components/invoice-designer/preview/previewStatus.test.ts packages/billing/src/components/invoice-designer/preview/previewSessionState.test.ts packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts' (pass). ### 2026-02-12 — T031 implemented - Marked existing-invoice preview continuity after AST pipeline swap as implemented. - Evidence: packages/billing/src/components/invoice-designer/DesignerVisualWorkspace.test.tsx::loads selected existing invoice detail and maps it for preview Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/components/invoice-designer/DesignerVisualWorkspace.test.tsx packages/billing/src/components/invoice-designer/preview/previewStatus.test.ts packages/billing/src/components/invoice-designer/preview/previewSessionState.test.ts packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts' (pass). ### 2026-02-12 — T032 implemented - Marked shape/render/verify status UI mapping coverage as implemented. - Evidence: packages/billing/src/components/invoice-designer/preview/previewSessionState.test.ts + previewStatus.test.ts + DesignerVisualWorkspace.test.tsx Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/components/invoice-designer/DesignerVisualWorkspace.test.tsx packages/billing/src/components/invoice-designer/preview/previewStatus.test.ts packages/billing/src/components/invoice-designer/preview/previewSessionState.test.ts packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts' (pass). ### 2026-02-12 — T033 implemented - Marked structured AST validation error surfacing in preview as implemented. - Evidence: packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts::surfaces structured schema diagnostics Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/components/invoice-designer/DesignerVisualWorkspace.test.tsx packages/billing/src/components/invoice-designer/preview/previewStatus.test.ts packages/billing/src/components/invoice-designer/preview/previewSessionState.test.ts packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts' (pass). ### 2026-02-12 — T034 implemented - Marked structured evaluator/strategy error surfacing in preview as implemented. - Evidence: packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts::surfaces structured evaluator diagnostics + rejects non-allowlisted strategy ids Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/components/invoice-designer/DesignerVisualWorkspace.test.tsx packages/billing/src/components/invoice-designer/preview/previewStatus.test.ts packages/billing/src/components/invoice-designer/preview/previewSessionState.test.ts packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts' (pass). ### 2026-02-12 — T035 implemented - Marked invoice PDF path shared AST evaluator/renderer helper wiring as implemented. - Evidence: packages/billing/src/actions/invoicePdfGenerationAstWiring.test.ts::uses shared AST evaluator and renderer helpers Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoicePdfGenerationAstWiring.test.ts packages/billing/src/actions/renderTemplateOnServer.ast.integration.test.ts packages/billing/src/actions/invoicePreviewPdfParity.integration.test.ts packages/billing/src/actions/invoiceTemplatePreviewCacheRemoval.test.ts packages/billing/src/actions/invoiceLegacyCompilerRemoval.test.ts packages/billing/src/actions/invoiceTemplateCompileParity.test.ts packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts' (pass). ### 2026-02-12 — T036 implemented - Marked PDF invoice path regression guard against executeWasmTemplate usage as implemented. - Evidence: packages/billing/src/actions/invoicePdfGenerationAstWiring.test.ts::no longer depends on wasm execution helpers Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoicePdfGenerationAstWiring.test.ts packages/billing/src/actions/renderTemplateOnServer.ast.integration.test.ts packages/billing/src/actions/invoicePreviewPdfParity.integration.test.ts packages/billing/src/actions/invoiceTemplatePreviewCacheRemoval.test.ts packages/billing/src/actions/invoiceLegacyCompilerRemoval.test.ts packages/billing/src/actions/invoiceTemplateCompileParity.test.ts packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts' (pass). ### 2026-02-12 — T037 implemented - Marked preview/PDF semantic parity integration coverage as implemented. - Evidence: packages/billing/src/actions/invoicePreviewPdfParity.integration.test.ts Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoicePdfGenerationAstWiring.test.ts packages/billing/src/actions/renderTemplateOnServer.ast.integration.test.ts packages/billing/src/actions/invoicePreviewPdfParity.integration.test.ts packages/billing/src/actions/invoiceTemplatePreviewCacheRemoval.test.ts packages/billing/src/actions/invoiceLegacyCompilerRemoval.test.ts packages/billing/src/actions/invoiceTemplateCompileParity.test.ts packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts' (pass). ### 2026-02-12 — T038 implemented - Marked preview compile cache removal and unreferenced wiring as implemented. - Evidence: packages/billing/src/actions/invoiceTemplatePreviewCacheRemoval.test.ts Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoicePdfGenerationAstWiring.test.ts packages/billing/src/actions/renderTemplateOnServer.ast.integration.test.ts packages/billing/src/actions/invoicePreviewPdfParity.integration.test.ts packages/billing/src/actions/invoiceTemplatePreviewCacheRemoval.test.ts packages/billing/src/actions/invoiceLegacyCompilerRemoval.test.ts packages/billing/src/actions/invoiceTemplateCompileParity.test.ts packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts' (pass). ### 2026-02-12 — T039 implemented - Marked deleted compiler/executor files absence and import graph guard as implemented. - Evidence: packages/billing/src/actions/invoiceLegacyCompilerRemoval.test.ts Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoicePdfGenerationAstWiring.test.ts packages/billing/src/actions/renderTemplateOnServer.ast.integration.test.ts packages/billing/src/actions/invoicePreviewPdfParity.integration.test.ts packages/billing/src/actions/invoiceTemplatePreviewCacheRemoval.test.ts packages/billing/src/actions/invoiceLegacyCompilerRemoval.test.ts packages/billing/src/actions/invoiceTemplateCompileParity.test.ts packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts' (pass). ### 2026-02-12 — T040 implemented - Marked post-cutover build/test viability without AssemblyScript compile helper module as implemented. - Evidence: packages/billing/src/actions/invoiceTemplateCompileParity.test.ts + invoiceLegacyCompilerRemoval.test.ts + passing suite Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoicePdfGenerationAstWiring.test.ts packages/billing/src/actions/renderTemplateOnServer.ast.integration.test.ts packages/billing/src/actions/invoicePreviewPdfParity.integration.test.ts packages/billing/src/actions/invoiceTemplatePreviewCacheRemoval.test.ts packages/billing/src/actions/invoiceLegacyCompilerRemoval.test.ts packages/billing/src/actions/invoiceTemplateCompileParity.test.ts packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts' (pass). ### 2026-02-12 — T041 implemented - Added explicit save-path regression guard test ensuring AST template saves do not invoke `compileAndSaveTemplate`. - Evidence: `packages/billing/src/actions/invoiceTemplateSaveRuntimeWasmRemoval.test.ts`. Verification: - `NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoiceTemplateSaveRuntimeWasmRemoval.test.ts` (pass). ### 2026-02-12 — T042 implemented - Closed persistence/runtime Wasm artifact removal coverage using save/runtime regression guards. - Evidence: `packages/billing/src/actions/invoiceTemplateSaveRuntimeWasmRemoval.test.ts` (wasmBinary drop + no runtime Wasm requirement). Verification: - `NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoiceTemplateSaveRuntimeWasmRemoval.test.ts` (pass). ### 2026-02-12 — T043 implemented - Marked runtime render path guard against dependency as implemented. - Evidence: packages/billing/src/actions/invoicePdfGenerationAstWiring.test.ts::keeps preview and PDF paths on evaluator/renderer modules Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoicePdfGenerationAstWiring.test.ts packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts' (pass). ### 2026-02-12 — T044 implemented - Marked compatibility behavior where legacy columns coexist but AST stays canonical as implemented. - Evidence: packages/billing/src/actions/invoicePdfGenerationAstWiring.test.ts::treats templateAst as canonical even when legacy columns exist Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoicePdfGenerationAstWiring.test.ts packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts' (pass). ### 2026-02-12 — T045 implemented - Marked runtime rejection of non-allowlisted strategy IDs as implemented. - Evidence: packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts::rejects non-allowlisted strategy ids at runtime Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoicePdfGenerationAstWiring.test.ts packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts' (pass). ### 2026-02-12 — T046 implemented - Marked unit coverage for explicit transform composition order semantics as implemented. - Evidence: packages/billing/src/lib/invoice-template-ast/evaluator.test.ts::applies transform composition in declared order Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/lib/invoice-template-ast/evaluator.test.ts' (pass). ### 2026-02-12 — T047 implemented - Marked unit coverage for empty/edge invoice-item arrays in grouping/totals paths as implemented. - Evidence: packages/billing/src/lib/invoice-template-ast/evaluator.test.ts::handles empty invoice-item collections for grouping and totals composition Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/lib/invoice-template-ast/evaluator.test.ts' (pass). ### 2026-02-12 — T048 implemented - Marked integration coverage for preview pipeline using AST sample fixtures as implemented. - Evidence: packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts packages/billing/src/actions/invoiceTemplatePreview.inv005.sanity.test.ts packages/billing/src/actions/renderTemplateOnServer.ast.integration.test.ts packages/billing/src/actions/invoicePreviewPdfParity.integration.test.ts' (pass). ### 2026-02-12 — T049 implemented - Marked integration coverage for preview pipeline with existing-invoice-style query payload mapping as implemented. - Evidence: packages/billing/src/actions/invoiceTemplatePreview.inv005.sanity.test.ts Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts packages/billing/src/actions/invoiceTemplatePreview.inv005.sanity.test.ts packages/billing/src/actions/renderTemplateOnServer.ast.integration.test.ts packages/billing/src/actions/invoicePreviewPdfParity.integration.test.ts' (pass). ### 2026-02-12 — T050 implemented - Marked integration coverage for PDF generation pipeline with AST template fixture as implemented. - Evidence: packages/billing/src/actions/renderTemplateOnServer.ast.integration.test.ts Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts packages/billing/src/actions/invoiceTemplatePreview.inv005.sanity.test.ts packages/billing/src/actions/renderTemplateOnServer.ast.integration.test.ts packages/billing/src/actions/invoicePreviewPdfParity.integration.test.ts' (pass). ### 2026-02-12 — T051 implemented - Marked parity test coverage for totals value equivalence between preview and PDF paths as implemented. - Evidence: packages/billing/src/actions/invoicePreviewPdfParity.integration.test.ts (Grand Total assertion) Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts packages/billing/src/actions/invoiceTemplatePreview.inv005.sanity.test.ts packages/billing/src/actions/renderTemplateOnServer.ast.integration.test.ts packages/billing/src/actions/invoicePreviewPdfParity.integration.test.ts' (pass). ### 2026-02-12 — T052 implemented - Marked parity test coverage for grouped line-item ordering equivalence between preview and PDF paths as implemented. - Evidence: packages/billing/src/actions/invoicePreviewPdfParity.integration.test.ts (Products/Services ordering assertion) Verification: - 'NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoiceTemplatePreview.integration.test.ts packages/billing/src/actions/invoiceTemplatePreview.inv005.sanity.test.ts packages/billing/src/actions/renderTemplateOnServer.ast.integration.test.ts packages/billing/src/actions/invoicePreviewPdfParity.integration.test.ts' (pass). ### 2026-02-12 — T053 implemented - Added docs architecture regression tests to assert the billing invoice-template docs describe AST model, evaluator/renderer pipeline, and strategy allowlist mechanism. - Evidence: `packages/billing/src/actions/invoiceTemplateDocsArchitecture.test.ts`. Verification: - `NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoiceTemplateDocsArchitecture.test.ts` (pass). ### 2026-02-12 — T054 implemented - Closed documentation removal-note coverage using docs architecture regression tests that assert compiler/Wasm deletion details are documented. - Evidence: `packages/billing/src/actions/invoiceTemplateDocsArchitecture.test.ts` (removed modules + preview cache removal assertions). Verification: - `NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoiceTemplateDocsArchitecture.test.ts` (pass). ### 2026-02-12 — T055 implemented - Added end-to-end-style author flow integration test covering: design workspace preview -> AST save -> server/PDF render. - Evidence: `packages/billing/src/actions/invoiceTemplateAuthorFlow.e2e.test.ts`. Verification: - `NODE_ENV=test pnpm vitest --coverage.enabled=false packages/billing/src/actions/invoiceTemplateAuthorFlow.e2e.test.ts` (pass).