ARCHITECT.LOGConnect
System Architecture2025

Internal Ops Automation System

A Playwright-driven internal operations automation system that processes triage and ticket workflows via a layered, typed architecture exposed through a streaming Express REST API and an AI intent router with a React control panel.

System snapshot

Layered, typed Playwright automation with streaming SSE and optional AI tool routing

Domain layer: immutable state machines, transition rules, and guard functions (typed AssertionError)

Adapter layer: Playwright selectors/actions/assertions/verifications organized by triage/tickets/status

Workflow orchestration: workflow functions that navigate, assert readiness, execute actions, and return WorkflowResult envelopes

Infrastructure runtime: browser lifecycle, session persistence, human-in-the-loop authentication gate, retry + error normalization, logging sinks

API server: Express controllers/services with SSE endpoints for /api/workflows/run and /api/ai/intent

AI intent layer + frontend: Vercel AI SDK tool generation + toolChoice routing, paired with a React/Vite control panel

Design focus

  • Typed error taxonomy (ActionError, AssertionError, VerificationError) normalized by the runner
  • State machine enforcement via codified immutable transitions and pre-action guards
  • Verify-before and verify-after state collection to avoid partial/corrupted progress
  • Browser lifecycle isolation (one browser instance per workflow invocation) to prevent cross-run contamination
  • Streaming-first operation (event-by-event SSE) to power real-time UI and downstream consumption

Context

The Architectural Challenge

Internal operations tooling often relies on humans repeatedly performing three tasks: processing triage queues, progressing tickets through state transitions, and verifying session health on a recurring basis. This system automates that manual loop with headless browser workflows that can be triggered on demand through CLI runners, REST endpoints, streaming API calls, or natural language prompts. A human-in-the-loop gate is retained for authentication: when no valid session exists, the system opens a headed browser, waits for a human login, persists session state, and then continues headlessly.

Project parameters

Domain
AI
Type
System
Complexity Level
Advanced

Technology stack

Node.jsTypeScriptPlaywright 1.57tsxExpress 4corsVercel AI SDK (ai)@ai-sdk/openaiOpenAI (gpt-4o-mini)Vitest 4@vitest/browser-playwright@vitest/coverage-v8React 19Vite 7Tailwind CSS 4shadcn/uiReact Router 7lucide-reactGitHub ActionsPlaywright test runner

Core Innovation

The key architectural distinction is the adapter pattern that cleanly separates Playwright locator/action logic from domain rules and workflow orchestration. Domain guards and transition rules are pure TypeScript and can be tested without a browser, while adapters encapsulate selectors, actions, assertions, and verifications around the UI. Workflow orchestration then composes adapters into end-to-end deterministic processes that return typed, serializable result envelopes. The AI tool layer reuses the same service functions as the REST API—so AI-routed calls and direct REST calls share the execution path instead of duplicating logic.

Implementation

Implementation Details

Workflow execution is structured as a layered pipeline. In the REST execution path, a POST to /api/workflows/run reaches a controller that streams events using Vercel AI SDK’s pipeDataStreamToResponse. It registers a logging sink for streaming logs, then calls runWorkflow(name, input), which delegates to executeWorkflow(workflow, options). executeWorkflow spins up a browser (per invocation), optionally authenticates via the human-in-the-loop gate, runs the workflow function, and normalizes outcomes into a typed WorkflowResult containing SUCCESS/FAILED/SKIPPED plus artifact data.

In the CLI execution path, npx tsx src/runners/<name>.ts invokes executeWorkflow directly, using HEADED and WORKFLOW_RETRIES from env; it logs to stdout and sets process.exitCode = 1 on failure.

AI intent routing works by converting registered workflow functions into AI SDK tools with JSON Schema parameter validation. The intent endpoint maps a natural language prompt to tool selection using generateText with toolChoice: auto; the selected tool executes the corresponding service function and returns the result in the stream alongside tool-call metadata. If the model does not select a tool, the system falls back to keyword-based inference.

Authentication uses a session-state file persisted to storage/sessions/internal-ops.json. On executeWorkflow calls with requiresAuth: true, authentication navigates to the dashboard. If the heading indicates the user is logged in, it proceeds immediately. Otherwise it navigates to /login, detects the login heading, and blocks on page.waitForURL until the dashboard URL pattern is matched; it then persists session state for subsequent runs.

Testing is layered as well: unit tests cover domain guards, state constants, and filter functions; integration tests cover adapter functions (selectors, actions, assertions, verifications) using Vitest with mock page objects; Playwright tests in tests/example.spec.ts act as a baseline runner check against the Playwright docs site.

Latency profile

Browser-bound execution (Playwright navigation + element waits)

Workflow execution time is dominated by Playwright navigation, waitForLoadState("networkidle"), and element interaction waits (up to 5s per item action). A triage process run over 10 items typically takes 30–90 seconds end-to-end depending on the hosted application’s response time. API server overhead is negligible because streaming begins within milliseconds of workflow start.

System focus

Correctness over throughput (single-run determinism + verifiability)

The system is designed for reliable, verifiable single-pass execution rather than high-concurrency throughput. It uses one browser instance per workflow invocation, sequential item processing within each workflow, and explicit before/after state verification to prioritize correctness. Concurrent multi-workflow execution is explicitly not currently modeled.

Outcomes

Outcomes & Future Iterations

Each workflow run produces verifiable, artifact-carrying results that are serializable and streamable. A successful triage process returns the IDs of matched, acted-on, and final-state items; a session health check returns the user ID and email; and a ticket inspect run returns buckets of IDs per state. These typed outcomes are designed to be consumed by the React frontend, CI pipelines, or downstream integrations.

Why this matters

Although Playwright is commonly used for testing, this system demonstrates using it as an operations automation runtime with production-grade reliability patterns: typed contracts, state machine enforcement, layered error handling, session management, retry logic, and a human-in-the-loop escape hatch. The same architecture is applicable to any browser-based scenario where the target application lacks a direct API but must still be automated with verifiable outcomes and controlled execution semantics.