Skip to content

Workflows list v2 phase 1: backend slim list (PR 1) #162

Description

@Silthus

Goal

Build PR 1 of map #160: the backend slim list for workflows and email templates. It is additive. Users see no change. MCP workflows-list gains fields and filters.

Contract: the spec, section "PR 1: backend slim list". The spec wins over this summary wherever they differ.

  • Branch: workflows-list-v2/slim-list (from origin/master)
  • PR title: feat(workflows): add slim summary list for workflows and email templates
  • Terminal: a babysat draft PR on PostHog/posthog, per the map's Notes. Never mark it ready, enqueue or merge.
  • PR 2 (frontend search bar) stacks on this PR with gh stack.
  • Skills: /tdd, /improving-drf-endpoints, /implementing-mcp-tools, /writing-tests, /writing-dataclasses, /writing-code-comments, /writing-pr-descriptions, /reviewing-with-coderabbit, /running-ci-preflight, /babysit-pr.
  • test-new-events-schema label: not needed (no event ingestion or event reads).

Acceptance criteria

  1. GET /api/projects/:id/hog_flows/summaries/ (operation hog_flows_summaries_list) returns paginated HogFlowListRow rows with exactly the fields in the spec: id, name, description, status, type, origin_product, trigger_type, has_draft, channels, dispatches, email_steps, created_by, created_at, updated_at, user_access_level, last_7_days. email_steps[] carries action_id, name, subject, from_addresses, from_name, from_integration_ids, template_uuid.
  2. GET /api/projects/:id/messaging_templates/summaries/ (operation messaging_templates_summaries_list) returns MessageTemplateListRow rows: id, name, description, type, subject, from_addresses, created_by, created_at, updated_at.
  3. Neither row carries actions, edges, draft, inputs, secrets, the trigger config, or any email body (html, text, design, preheader).
  4. Pagination: default 500, max 1000, order -updated_at, -id.
  5. row.type comes from one helper shared with workflow_type_q. trigger_type reads the trigger action, with the legacy trigger column as fallback.
  6. From addresses resolve through one team-scoped Integration query per request: override first, then each rotation integration, then a legacy string from.
  7. last_7_days comes from one fetch_app_metric_totals_by_source call per request, and is null on every row (HTTP 200) when ClickHouse fails. Only summaries returns it.
  8. The summaries action applies filter_queryset_by_access_level explicitly, because _filter_queryset_by_access_level only runs for list. summaries is a declared read action on both viewsets, so a personal API key with hog_flow:read can call it.
  9. Server filters on both list and summaries: status and created_by take comma lists; new trigger_type and channel; exclude_status, exclude_type, exclude_trigger_type, exclude_created_by, exclude_channel. OR within a param, AND across, unknown values give 400. search, trigger, type, origin_product, broadcast_eligible, id, created_at, updated_at keep working as today. No string-built SQL: allowlisted enums or bound parameters only.
  10. Only the two summaries paths are on GZIP_RESPONSE_ALLOW_LIST. The full hog_flows/ list is not.
  11. MCP workflows-list keeps its operation. HogFlowSummarySerializer gains type, trigger_type, has_draft, channels, email_steps, and still omits actions, edges and draft. The tool description in products/workflows/mcp/tools.yaml names the new filters and fields.
  12. hogli build:openapi is run, and the regenerated frontend and MCP code is committed. Every new field and parameter has help_text or a description.
  13. The query count is constant in the row count. A row for a workflow with a 20 KB email body is under 1.5 KB.
  14. products/workflows/CONTRIBUTING.md describes the new endpoint and filters.

Test-first plan (outside-in)

Start with a failing API test for the summaries row shape, then the filters, then work inward to the pure summary function. The spec's test table lists every test and the regression it catches. In short:

  1. test_hog_flow_summaries.py: exact row JSON for a mixed fixture (email override sender, email with sender rotation, SMS, Slack, webhook).
  2. Secret and body strings never appear in summaries or in the MCP list.
  3. Row size under 1.5 KB with a 20 KB body.
  4. assertNumQueries equal at 2 and 20 rows, on both endpoints.
  5. type parity with ?type=; trigger_type follows the trigger action.
  6. Sender resolution cases, including another team's integration id.
  7. last_7_days from a mocked totals function; null and 200 when it raises.
  8. An inaccessible workflow is absent from summaries and from its totals; another team's rows are absent.
  9. Pagination cap and stability.
  10. Parameterized filter block over list and summaries (multi-value, every exclude_*, 400s, existing params unchanged).
  11. gzip on summaries, and none on hog_flows/.
  12. MCP list gains the fields and still has no graph.
  13. Email template summaries: shape, deleted and other-team rows excluded, no content, more than 100 templates page correctly.

Invented data only (example.com addresses, made-up names).

Proof bundle

  • The red run of the first API tests, then green.
  • hogli test output for the new and touched test files, and hogli ci:preflight --strict passing.
  • semgrep --config .semgrep/rules/security/ . clean on the diff.
  • An OpenAPI diff summary: the new operations, the new parameters on hog_flows_list.
  • A local timing of summaries for 1,000 generated workflows with one 20 KB email step each, with and without gzip (invented fixture, local numbers only).
  • The reviews the map requires: CodeRabbit, then adversarial, code-quality and logic/safety reviews, each by a fresh Opus sub-agent. Then /babysit-pr until CI is green and every comment is addressed.

Out of scope

Server filters for sends, from, owner, health and kind; a stored list_summary column; the metrics/global meaning fix; any frontend change; phases 2 to 6.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions