Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat(www): FlowsPanel UI — SDK migration, codegen bump, execution tables, icon fixes#95

Closed
pyramation wants to merge 215 commits into
main from
feat/flows-panel-ui
Closed

feat(www): FlowsPanel UI — SDK migration, codegen bump, execution tables, icon fixes #95
pyramation wants to merge 215 commits into
main from
feat/flows-panel-ui

Conversation

@pyramation

@pyramation pyramation commented Jun 12, 2026
edited by devin-ai-integration Bot
Loading

Copy link
Copy Markdown
Contributor

Summary

Migrates FlowsPanel from raw fetch/gqlFetch calls to the generated GraphQL SDK, bumps codegen to 4.47.10 (partition key fix for ORM update/delete), and regenerates all SDK packages.

Key changes:

  1. Codegen bump to 4.47.10 — ORM update()/delete() methods now include databaseId in the where type for partitioned tables. Hooks mutation variables also include extra keys.

  2. FlowsPanel SDK migration — removed rawMutation() workaround entirely. All mutations go through typed ORM methods:

    // Before (raw fetch):
    await rawMutation(`mutation($input: UpdatePlatformFunctionGraphRefInput!) { ... }`,
     { input: { id, databaseId, platformFunctionGraphRefPatch: { commitId } } })
    // After (ORM):
    await orm().platformFunctionGraphRef.update({
     where: { id, databaseId: DATABASE_ID },
     data: { commitId },
     select: { id: true },
    }).unwrap()
  3. SDK regenerated — all 3 packages (ORM, CLI, hooks) regenerated with execution tables (node_states, executions, execution_outputs) exposed as GraphQL types.

  4. Icon fixtoggle-left mapped to FiToggleLeft in NodeIcon (was rendering as text for boolean nodes).

  5. Error visibility — panels now show error messages instead of infinite spinners when GraphQL queries fail.

Depends on upstream constructive PR #1296 for the hooks codegen fix.

Link to Devin session: https://app.devin.ai/sessions/b2291a8e333e445aa125a2efd1996206
Requested by: @pyramation

pyramation added 30 commits June 8, 2026 00:50
Sliced from constructive-db's monolithic constructive module using:
 pnpm run slice:constructive -- --renumber-alterations --strip-cross-package-deps
Package includes:
- constructive_infra_public schema, types, and all tables
- constructive_infra_private schema and trigger functions
- 254 changes, 764 files
Standalone: requires only plpgsql, pgpm-inflection, pgpm-stamps
No RLS policies, no grants, no job triggers
...mignore)
The slicer now generates a complete pgpm module with:
- package.json with @pgpm/* dependencies mapped from .control requires
- Makefile with PGXS include
- .npmignore excluding test files
This fixes 'No package.json found' error when running pgpm install.
...ema stripping
- Add missing deploy dependencies (type, constraint→column, FK→pkey)
- Plan is now topologically sorted for correct deploy order
- Remove metaschema partition registrations (INSERT INTO metaschema_public.*)
 that require the closed-source MetaSchema system
- Successfully tested: pgpm deploy --yes --createdb --database testinfra
...tion
Separate pgpm module that registers the constructive-infra function tables
as a MetaSchema function_module. This allows querying MetaSchema to
discover the infra function tables (definitions, invocations, execution_logs,
secret_definitions).
Dependencies:
 - constructive-infra (the raw DDL)
 - @pgpm/metaschema-modules (function_module table)
 - @pgpm/services (service registration layer)
The registration INSERT provides explicit schema/table names for the
platform-scoped infra tables, letting the MetaSchema trigger system
handle ID resolution and API routing.
Adds a CI workflow that runs 'pgpm test-packages --full-cycle' on every
PR that touches pgpm/ files. This validates the full deploy/verify/revert/deploy
cycle for constructive-infra against a real postgres-plus:18 instance.
constructive-infra-services is excluded since it requires the full
MetaSchema system (closed-source triggers) to deploy.
Also fixes the function_requirement type revert SQL which was missing
the TYPE keyword (DROP → DROP TYPE).
- job/compute-worker: platform-aware worker that discovers functions from
 constructive_infra_public.platform_function_definitions (TTL-cached),
 tracks invocations in platform_function_invocations, dispatches via HTTP
- job/compute-service: orchestrator (callback server + ComputeWorker +
 Scheduler), mirrors job/service patterns
- scripts/setup-platform-db.sh: Tier 1 setup (pgpm deploy + seed)
- scripts/dev-compute.ts: dev launcher for compute-service + functions
- scripts/seed-functions.sql: registers send-email + send-verification-link
- docker-compose.yml: adds platform-setup service (Tier 2)
- k8s/overlays/local-simple/compute-service.yaml: K8s manifest (Tier 3)
- Makefile: adds setup-platform, dev-compute targets + tier documentation
- .agents/skills/dev-tiers: skill for the 3-tier dev model
- .agents/skills/compute-worker: skill for the compute-worker system
- pgpm/constructive-infra: adds @pgpm/database-jobs dependency
...error)
pgpm deploy requires module dependencies to be pre-installed via
'pgpm install' before deployment. Without this, packages like
@pgpm/database-jobs fail with 'extension not available'.
Adds pgpm install to:
- scripts/setup-platform-db.sh (Tier 1)
- docker-compose.yml platform-setup service (Tier 2)
- .github/workflows/pgpm-test.yaml (CI)
- make status: shows Docker containers, PG connection, databases with
 infra schema, Node/pnpm/pgpm versions, and build state
- make verify-platform: checks DB exists, infra + jobs schemas deployed,
 tables present, functions seeded — exits non-zero with fix instructions
 if anything is wrong
Dan committed all extension deps (database-jobs, metaschema-modules,
services, etc.) directly into extensions/. pgpm install is no longer
needed before deploy. Also restores pgpm volume to :ro in Docker
Compose and mounts extensions/ for the platform-setup service.
Built-in function definitions (send-email, send-verification-link) are
now deployed as a pgpm fixture inside constructive-infra. The fixture
uses the standard deploy/revert/verify pattern following the inflection
module's fixtures convention.
- deploy: INSERT ON CONFLICT DO NOTHING
- revert: DELETE WHERE is_built_in AND scope='platform'
- verify: SELECT 1 from seed row
Removes manual psql seed step from setup script, docker-compose, and
verify-platform fix instructions. pgpm deploy now handles everything.
Moves the built-in function seed data (send-email, send-verification-link)
from constructive-infra into its own pgpm package: constructive-infra-seed.
This keeps constructive-infra as pure DDL (schemas, tables, triggers) and
the seed data as a separate deployable unit. The seed package depends on
constructive-infra via the .control file requires.
Both packages pass pgpm test-packages --full-cycle.
compute-service discovers functions from the database, so it doesn't
need direct workspace deps on send-email-fn or send-verification-link-fn
(which are generated packages in generated/ and not in the workspace).
...nfigs
- New fixture: seed_built_in_secrets seeds MAILGUN_* and SMTP_* into
 platform_secret_definitions (with well-known default database_id)
- Function definitions now include required_secrets and required_configs
 arrays (function_requirement[] type) linking functions to their deps
- All SQL files now use proper pgpm format: BEGIN/COMMIT wrappers,
 '-- Deploy:' header style with '-- made with <3 @ constructive.io'
- New script: load-platform-env.sh reads .env, cross-references against
 DB function requirements, reports satisfied vs missing keys
- .env.example updated with SMTP/Mailpit + dry-run toggle sections
- Makefile: added 'make check-env' target
Procedural lifecycle targets:
 make up # prereqs → docker → bootstrap → deploy → seed → verify
 make up DB_NAME=mydb # same with custom DB
 make down # stop docker compose + pgpm docker stop
 DROP=1 make down DB_NAME=mydb # also drop the DB
 make up:email-job # start mailpit + compute-service (SMTP mode)
 make down:email-job # stop mailpit + compute-service
email-job-up verifies platform is up first, starts mailpit, loads
.env (with sane SMTP defaults), then launches compute-service.
status now shows mailpit container state.
...rrides
- Skip python-example and other non-node-graphql functions from startup
- Print a clear port/service summary table before launching processes
- Respect SEND_EMAIL_DRY_RUN, SEND_VERIFICATION_LINK_DRY_RUN,
 EMAIL_SEND_USE_SMTP, and SMTP_FROM from environment (was hardcoded)
- www/: Vite + React + Express app with 6 tabs (Functions, Secrets, Jobs,
 Invocations, Commands, Terminal)
- Express backend: REST API for DB queries + WebSocket terminal via child_process
- Secrets & Namespaces tab: shows seeded secret definitions and default namespace
- Seed: add default platform namespace, link functions to namespace_id
- Function API: parse composite-type arrays into proper JSON
- Makefile: add make up:www target
- scripts/www-up.sh: checks platform, installs deps, starts Vite + Express
...ster management
- Install commander and kubernetesjs packages in www/
- Add K8s proxy endpoint (/api/k8s/*) in Express server
- Add K8s tab with Pods/Deployments/Services views per namespace
- Namespace selector defaults to constructive-functions
- Graceful error when kubectl proxy not running
... tab
- ansiToHtml() converts ANSI escape sequences into colored <span> elements
- Remove max-h-60 so output expands naturally with content
- Exit code shown in a separate footer bar
- Strip remaining escape sequences that don't match known codes
Step 4b cross-references loaded env vars against platform_function_definitions
required_secrets/required_configs. Warns about missing secrets but doesn't block
(defaults still work for Mailpit/SMTP mode). Suggests 'make check-env' for details.
- Reads .env file and merges with process.env + dev defaults
- Queries platform_function_definitions for required_secrets/required_configs
- Reports per-function coverage at startup (✓ all set / くろまる N missing)
- Priority: .env > process.env > hardcoded defaults
- Graceful fallback if DB query fails (schema not deployed)
Both tables are PARTITION BY RANGE(created_at) but had no partitions,
causing 'no partition of relation found for row' on INSERT.
Adds DEFAULT partition for each so rows land somewhere until
time-based partitions are created.
Secrets tab now shows:
- Function coverage badges (e.g. send-email 5/8)
- All required secrets/configs from DB + .env merged
- Editable input fields with eye/reveal toggle for sensitive keys
- 'Save to .env' button writes grouped .env file to project root
- Shows which functions require each secret
- File status indicator (.env exists / will be created)
Backend adds:
- GET /api/env — reads .env and returns parsed vars
- POST /api/env — merges values + writes grouped .env file
Each function card now has a 'Trigger' button that opens an inline
payload editor with sensible defaults (send-email gets to/subject/html,
send-verification-link gets to/type/link). Submitting creates a job in
app_jobs.jobs and shows success/error inline — no need to switch tabs.
Replace declare -A (bash 4+) with newline-separated string + grep.
Replace read -ra with portable IFS-based for loops.
Replace ((...)) arithmetic with $((...)) POSIX form.
macOS ships bash 3.2 — these scripts now work on both.
Jobs created from the UI or without a database_id context now fall
back to 00000000-0000-0000-0000-000000000000 (the well-known default
used by the seed). Fixes NOT NULL violation on platform_function_invocations.
...ents
- Add .agents/skills/fbp/SKILL.md mapping FBP NodeDefinitions to platform functions
- Add docs/spec/fbp-integration.md research doc with full mapping spec
- Add Flows tab with React Flow: drag-and-drop function nodes, edge creation,
 localStorage persistence, sidebar palette, and minimap
- Enhance FunctionsPanel trigger success message with Invocations tab link
- Install @xyflow/react for the flow graph canvas
...tion
- Add platform_secret_values table (pgpm migration: deploy/revert/verify)
 Columns: id, secret_name, configured_value, database_id, created_at, updated_at
 Unique constraint on (secret_name, database_id)
- Backend API (www/server/index.ts):
 GET /api/secret-values — read configured values from DB
 POST /api/secret-values — write configured values to DB
 POST /api/secrets/sync-from-db — DB values -> .env
 POST /api/secrets/sync-to-db — .env values -> DB
 POST /api/env now also syncs to DB on save (best-effort)
- Frontend (SecretsPanel.tsx):
 Add 'Sync from DB' and 'Sync to DB' buttons
 DB status indicator in header
- Refactor scripts/dev-compute.ts:
 Secrets pipeline: .env > DB > hardcoded defaults
 Per-function env injection (only needed secrets/configs)
 Fail fast on missing required secrets, warn on optional
- Add make secrets:sync (bidirectional sync script)
- Add scripts/secrets-sync.sh for CLI-based sync
@devin-ai-integration devin-ai-integration Bot changed the title (削除) feat(www): FlowsPanel UI — graph execution fixes, node palette, visual polish (削除ここまで) (追記) feat: cumulative integration — Phase 1+2 schema, compute worker, UI, pgpm fixes (追記ここまで) Jun 13, 2026
pyramation added 25 commits June 13, 2026 12:30
tick_execution was building the job payload with only
{execution_id, node_name, node_type, inputs} — missing props.
Inline nodes like const/string need props to emit their value
(e.g. props.value = 'dan@constructive.io'). Without props,
const/string returned {value: ''} (empty string), causing
downstream send-email to fail with 'Missing required field to'.
Also adds props to the GraphNodePayload TypeScript interface.
...t definitions
Before dispatching a graph node job (HTTP or inline), check the
assembled inputs against the function's declared input ports from
platform_function_definitions. Validates:
- required ports are present (non-optional ports must have a value)
- port types match (string/number/boolean checked, json/any pass-through)
Produces clear errors like:
 send-email[send-email2]: input validation failed — input 'html' expects string but got object
Also adds inputs, outputs, payload_schema to the discovery query
and PlatformFunctionDefinition interface.
The payload_schema column only exists on the old constructive_infra
schema, not on the deployed constructive_compute schema. Selecting
it breaks function discovery at startup.
... (store_id, name)
Same pattern as the store lookup above: SELECT existing graph by
(store_id, name) before INSERT. Re-importing a graph with the same
name returns the existing graph_id instead of hitting
idx_platform_function_graphs_unique_name.
...execution
The merkle tree path for each node is now stored alongside node_name
in execution_node_states, and included in the job payload as node_path.
This enables the execution overlay UI to show the full hierarchy path
for subnet drill-down and breadcrumb navigation.
tick_execution captures path from get_all() and passes it through:
- node_states INSERT includes node_path column
- job payload includes node_path array
- GraphNodePayload interface updated with optional node_path field
...invocation detail panel
Adds a toggleable execution overlay to the FlowsPanel that provides
real-time visual feedback during graph execution:
GraphNode: colored glow + border per execution state
 - pending (gray), queued (purple, animated dashes), running (yellow pulse),
 completed (green), failed (red)
 - duration badge on completed/failed nodes
GraphEdge: animated marching dashes while source node is computing,
 solid green once delivered, red on failure
FlowsPanel:
 - Eye/EyeOff toggle to enable/disable overlay independently
 - Enhanced polling returns invocation details (duration, error, result, payload)
 - Clickable node list in sidebar with per-node duration
 - Node detail panel: shows task type, status, duration, input payload,
 result, and error stack for any node
 - Clear button to dismiss execution state
Architecture: NodeExecutionInfo flows via a separate React context
(NodeStatesContext) so the overlay is fully decoupled from the
graph editing state. When overlay is off, GraphEditor renders
identically to before.
Remove the 4 execution tree tables (platform_execution_tree_object,
store, commit, ref) and execution_store_id column from the local pgpm
slice. These are not needed for the real-time execution overlay UI
which only requires node_states + execution_outputs.
Matches the upstream change in constructive-db PR #1625.
- Remove deploy/revert/verify dirs for all 4 execution_tree tables
- Remove execution_store_id column from platform_function_graph_executions
- Remove execution_tree entries from pgpm.plan
- Remove partition declarations from create_default_partitions.sql
- Regenerate sql/ packages
Native/inline functions (const/string, math/add, etc.) are internal
graph building blocks and should not appear in the trigger list.
Only functions with a serviceUrl (HTTP-dispatched cloud functions)
are shown.
...oggle icon
- FunctionsPanel: only show functions with a serviceUrl (cloud/HTTP
 functions). Native/inline functions are internal graph building blocks.
- NodeIcon: fix SVG path for 'toggle' icon — use explicit arc flag
 separators so the boolean node renders correctly in the graph canvas.
- Set graph_execution_id on invocation rows when dispatching graph nodes
- Add /api/execution/:id/node-states REST endpoint for direct node_states query
- Rewrite pollExecutionStatus to query node_states table (primary) + invocations (supplement)
- Add 'queued' state to NodeState type so animated dashed borders render correctly
- Edges now animate (marching dashes) while source node is running/queued
...raphQL
- Remove REST /api/execution/:id/node-states endpoint from www/server
- Update pollExecutionStatus to query node_states via GraphQL SDK
 (table is now in constructive_compute_public, exposed by PostGraphile)
- Update compute-worker markNodeRunning to use public schema
- Update functions-test graph.ts and worker.ts table references
- Keep function calls (complete_node, fail_node) in private schema
Move platform_function_graph_executions, execution_node_states, and
execution_outputs table directories from constructive_compute_private
to constructive_compute_public. Update all SQL references in
procedures (tick_execution, complete_node, fail_node) to point to
public schema tables. Functions themselves remain in private schema.
Regenerated sql/constructive-compute--0.0.1.sql via pgpm package.
...declaration
pgpm deploy resolves dependencies in plan order. The execution tables depend on
constructive_compute_public/schema which was declared later in the plan file.
Moved execution table entries to appear after the schema declaration.
...on tables
The execution tables moved from constructive_compute_private to
constructive_compute_public, but the default partition declarations
in constructive-infra-seed still referenced the old private schema.
Remove all inline GraphQL query strings and the gqlFetch helper.
All data operations now use compute.getClient() ORM methods:
- loadGraphFromStore: findMany on refs/commits/objects
- loadGraphFromImport: findMany on graphs + query.platformReadFunctionGraph
- saveGraphToStore: create object/commit, findMany + update/create ref
- createStore/deleteStore: create/delete on store model
- importAndExecuteGraph: mutation.platformImportGraphJson/platformStartExecution
- pollExecutionStatus: findMany on node_states + invocations
Adds native string and boolean constant nodes to coreDefinitions so they
always appear in the flow graph sidebar palette with correct icons:
- string: icon='type' (FiType)
- boolean: icon='toggle' (FiToggleLeft)
Previously these only existed in MOCK_FUNCTIONS and would disappear
when real platform functions loaded from the database.
...or logging
- Add ALTER DEFAULT PRIVILEGES for authenticated (SELECT, INSERT, UPDATE, DELETE)
 and anonymous (SELECT only) on constructive_compute_public and
 constructive_platform_function_graph_public schemas
- Update standalone_schema_access.sql to grant anonymous role USAGE + SELECT on
 all public schemas (for unauthenticated GraphQL requests)
- Add console.error logging to pollExecutionStatus catch blocks so GraphQL
 failures are visible in browser dev tools instead of silently swallowed
- Regenerate sql/ packages for constructive-compute, constructive-platform-
 function-graph, and constructive-infra-seed
Anonymous grants are pointless — standalone mode sets anon_role='authenticated'
so all requests (even unauthenticated) use the authenticated role. Only the
authenticated DEFAULT PRIVILEGES are needed.
The boolean node definition uses icon name 'toggle-left' but the map only
had 'toggle'. Both now resolve to FiToggleLeft.
- FunctionsPanel: show error message when query fails instead of
 infinite spinner
- FlowsPanel: show Create Store button even when stores query errors
 (previously hidden forever if storesLoading stayed true)
The GraphQL schema requires databaseId at the input level for update and
delete mutations on partitioned tables, but the ORM codegen omits it from
the variables. Use raw mutations for ref update and store delete to pass
databaseId explicitly.
The ORM client object returned by getClient() doesn't expose execute().
Use fetch('/graphql/compute') directly for partitioned table mutations
that need databaseId in the input.
... key fix
- Bumps @constructive-io/graphql-codegen from ^4.47.7 to ^4.47.10
- Regenerated ORM: update/delete methods now include databaseId in where type
- Regenerated hooks: update/delete mutation hooks include databaseId in variables
- Regenerated CLI: commands for new execution tables
- FlowsPanel: removed rawMutation() workaround, uses proper ORM methods
 orm().platformFunctionGraphRef.update({ where: { id, databaseId }, data })
 orm().platformFunctionGraphStore.delete({ where: { id }, select })
@devin-ai-integration devin-ai-integration Bot changed the title (削除) feat: cumulative integration — Phase 1+2 schema, compute worker, UI, pgpm fixes (削除ここまで) (追記) feat(www): FlowsPanel UI — SDK migration, codegen bump, execution tables, icon fixes (追記ここまで) Jun 14, 2026

Copy link
Copy Markdown

Superseded — already merged into develop via #104

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

Reviewers

No reviews

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

1 participant

AltStyle によって変換されたページ (->オリジナル) /