Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@
"stylelint": "stylelint \"src/**/*.{css,postcss,svelte}\"",
"stylelint:fix": "stylelint --fix \"src/**/*.{css,postcss,svelte}\"",
"generate:locales": "esno scripts/generate-locales.ts",
"workflows": "esno scripts/workflows.ts",
"e2e-workflows": "esno scripts/e2e-workflows.ts",
"payload-coverage-workflow": "esno scripts/payload-coverage-workflow.ts",
"audit:tailwind": "esno scripts/audit-tailwind-colors",
"audit:holocene-props": "esno scripts/generate-holocene-props.ts",
"validate:versions": "./scripts/validate-versions.sh"
Expand Down Expand Up @@ -145,13 +146,13 @@
"@sveltejs/adapter-vercel": "^6.3.2",
"@sveltejs/kit": "2.57.1",
"@sveltejs/vite-plugin-svelte": "^6.2.4",
"@temporalio/activity": "1.15.0",
"@temporalio/client": "1.15.0",
"@temporalio/common": "1.15.0",
"@temporalio/proto": "1.15.0",
"@temporalio/testing": "1.15.0",
"@temporalio/worker": "1.15.0",
"@temporalio/workflow": "1.15.0",
"@temporalio/activity": "1.16.0",
"@temporalio/client": "1.16.0",
"@temporalio/common": "1.16.0",
"@temporalio/proto": "1.16.0",
"@temporalio/testing": "1.16.0",
"@temporalio/worker": "1.16.0",
"@temporalio/workflow": "1.16.0",
"@types/base-64": "^1.0.0",
"@types/cors": "^2.8.13",
"@types/express": "^4.17.17",
Expand Down
148 changes: 74 additions & 74 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

File renamed without changes.
13 changes: 13 additions & 0 deletions scripts/payload-coverage-workflow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { connect, startPayloadCoverageWorkflow } from '../temporal/client';
import { runWorkerUntil } from '../temporal/workers';

async function main() {
const client = await connect();
const result = startPayloadCoverageWorkflow(client);
await runWorkerUntil(result);
}

main().catch((error) => {
console.error(error);
process.exit(1);
});
2 changes: 1 addition & 1 deletion src/lib/pages/workflow-query.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@
<Option {value} {description}>{value}</Option>
{/each}
</Select>
<div class="flex flex-col gap-1">
<div data-testid="query-input" class="flex flex-col gap-1">
<PayloadInput bind:input label={translate('workflows.query-arg')} />
</div>
<div class="flex w-full flex-wrap items-end justify-end gap-4">
Expand Down
86 changes: 86 additions & 0 deletions temporal/PAYLOAD_COVERAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# PayloadCoverageWorkflow β€” Design Notes

## Context

The `<Payload>` component in `src/lib/components/payload/payload.svelte` decodes and renders Temporal Payloads from event history. To test all display/decode paths in the UI, we need a Temporal workflow that exercises every event type that produces a Payload field. The workflow is added to the existing `temporal/` directory which already has a worker, client, codec, and 4 existing workflows.

## Files

- `temporal/activities/complex.ts` β€” new activity with rich input/output types
- `temporal/activities/index.ts` β€” exports the new `complex` activity
- `temporal/workflows.ts` β€” adds `PayloadCoverageChildWorkflow` and `PayloadCoverageWorkflow`
- `temporal/client.ts` β€” adds `startPayloadCoverageWorkflow` helper for easy testing

## Payload-Producing Event Types Covered

| Event / Location | Payload Field |
| ------------------------------------------- | -------------------------------------------------------------------------- |
| `WorkflowExecutionStarted` | `input` β€” rich object with all JSON primitive types; `memo` β€” set at start |
| `ActivityTaskScheduled` | `input` β€” complex object with nested arrays/objects |
| `ActivityTaskCompleted` | `result` β€” complex return object |
| `ActivityTaskFailed` | `failure.details` β€” from deliberately failing activity variant |
| `ActivityTaskScheduled` (local) | inside `MarkerRecorded` details |
| `ActivityTaskCompleted` (local) | inside `MarkerRecorded` details |
| `WorkflowExecutionSignaled` | `input` β€” two signals with typed payloads |
| `WorkflowExecutionUpdateAccepted/Completed` | `input` / `result` |
| `UpsertWorkflowSearchAttributes` | search attribute value Payloads |
| `StartChildWorkflowExecutionInitiated` | `input` |
| `ChildWorkflowExecutionCompleted` | `result` |
| `WorkflowExecutionCompleted` | `result` β€” aggregate result object |
| Query `get-status` | runtime query response (visible in UI query tab) |
| Query `get-field` | parameterized query response |

## Workflow Behavior

- **Starts and runs activities/child workflow immediately** β€” all Payload events are created on start
- **Waits up to 5 minutes** for signals/queries/updates via `condition` β€” gives time for manual UI testing
- **Auto-completes** after the timeout, so you also see `WorkflowExecutionCompleted` with result payload
- **Failing activity** is wrapped in try/catch β€” workflow continues after `ActivityTaskFailed` is recorded

## Running It

```bash
# Register custom search attributes (one-time, local dev server)
temporal operator search-attribute create --name CustomKeywordField --type Keyword
temporal operator search-attribute create --name CustomIntField --type Int
```

Then call `startPayloadCoverageWorkflow(client)` from `client.ts`. The workflow starts at ID `payload-coverage-workflow`.

## Interacting During the 5-Minute Window

**Send a signal:**

```bash
temporal workflow signal \
--workflow-id payload-coverage-workflow \
--name add-data \
--input '{"key":"testKey","value":{"nested":true}}'

temporal workflow signal \
--workflow-id payload-coverage-workflow \
--name trigger \
--input '["tagA","tagB"]'
```

**Send an update:**

```bash
temporal workflow update \
--workflow-id payload-coverage-workflow \
--name process-update \
--input '{"operation":"transform","payload":{"x":1,"y":2}}'
```

**Run a query:**

```bash
temporal workflow query \
--workflow-id payload-coverage-workflow \
--type get-status

temporal workflow query \
--workflow-id payload-coverage-workflow \
--type get-field \
--input '"stringField"'
```
Loading
Loading