Switch filter query builders from IN (subquery) to EXISTS (correlated
subquery) patterns. This enables PostgreSQL semi-join optimizations
(stops at first match) and replaces NOT IN with NOT EXISTS (faster,
no NULL-semantics pitfalls).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Style the name column with monospace text and widen it slightly. Add a
neutral background badge style to type labels in the value column.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Use a fixed pixel width for the name column instead of a fractional
unit, preventing it from growing too wide with longer property names.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Combine the description and type columns into a single "Value" column
that shows the type, description, and nested content inline. This
avoids the broken layout where expanded rows were rendered as siblings
below the table, decoupled from their row context.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Consolidate the per-property tables into a single table with one header
row, eliminating the repeated table headers for each property. Give the
description column 3x the width of name/type columns so longer
descriptions get more room.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Restructure schema rendering so each property row is wrapped in its own
table, enabling inline expansion of nested schemas. Remove the title
column since it duplicated the name. Make subschema sections (oneOf etc.)
collapsible behind toggle buttons instead of rendering them expanded.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
The search field was being rendered in two separate conditional branches
(empty state vs list state), causing React to remount it when toggling
between them and losing focus. Restructure to a CSS grid layout where
the search field is always in a stable tree position.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Add `alignItems="start"` to the top-level Flex container so the sidebar
and detail panels align to the top rather than stretching to equal height.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Converts createBinRunner from spawnSync to async spawn, and processes
all CLI packages concurrently with a shared p-limit limiter bounded
by CPU count. Reduces wall-clock time from ~50s to ~12s.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Always show descriptions in the action list regardless of selection
state, use MarkdownContent for the detail description, fix the
isRowHeader error by always marking the first column, and move schema
expansion content outside of the table to avoid broken nesting and
scroll-jump issues. Subschemas (anyOf/oneOf) now render at full width
inside a Flex column layout.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Replace accordion groups with plain titled sections for action
input/output/examples, and switch to a sidebar layout where the
action list remains visible when viewing action details.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Extracts method/url directly from the input instead of constructing
a new Request in the catch block, which could fail if the body was
already consumed. Also adds a test with Request object input.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Replace all @material-ui imports in RenderSchema with @backstage/ui
equivalents (TableRoot, TableHeader, TableBody, Row, Column, Cell,
CellText, Button, Text, Flex, Tooltip). Simplify SchemaRenderContext
by removing the classes and headings fields that were only needed
for @material-ui styling.
Redesign the ActionsPage to use a List with selectable rows instead
of a Table with a separate detail Card. When an action is selected,
all descriptions are hidden from the list and the action detail is
shown below with input/output schemas and examples in accordions.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Replace the unpaginated action list with a paginated table showing 20
items per page, giving users a clear count and navigation controls.
Consolidate the two-column layout into a single column with the
description shown as subtitle text in each row.
Revamp the action detail view using Backstage UI Card and Accordion
components for a structured, collapsible layout of input/output schemas
and usage examples.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
* workflows: add Discord notification for ready PRs
Adds a new workflow that posts to Discord whenever a pull request is
opened as non-draft or marked as ready for review. Uses jq to safely
construct the JSON payload and sends it via curl to a webhook URL
stored in repository secrets.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
* workflows: harden Discord webhook notification
Add early guard for missing webhook secret, disable Discord mention
parsing to prevent abuse via PR titles/bodies, and check the HTTP
response to surface webhook failures.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
* workflows: upgrade github-script to v8 and truncate embed title
Align actions/github-script pin with the rest of the repo (v8.0.0)
and truncate the Discord embed title to the 256-character limit to
prevent webhook failures on long PR titles.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
---------
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Page components without props don't need to be exported from the
package API surface. Import directly from the component file in
the alpha entry points instead.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Replace the accordion-based actions list with a Table component from
@backstage/ui, providing aligned columns for action name and description
with click-to-expand detail view.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Replace the table-based actions page with an accordion layout using
@backstage/ui components. Each action is listed as an expandable
accordion, letting users browse the full list while expanding
individual actions to see their schema details inline. This avoids
the need to scroll between a table and a detail section.
The search field is kept for filtering actions by name or description.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Move NfsDefaultImportPage out of the public API and export it as
DefaultImportPage from the alpha entry point instead.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Replace the third-party Discord notification action with inline
`actions/github-script@v8` steps that post to the Discord webhook
directly using fetch. This removes a third-party action dependency
and adds explicit error handling for missing secrets and failed
webhook requests.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Replace dual TParams/TParamKeys type parameters with a single TParamKey,
removing unnecessary complexity while preserving runtime behavior.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
The auditor's severity log level mappings previously used a `zod/v3`
`z.record()` schema with manual fallbacks for defaults and relied on
casting into Zod error internals (`.received`, `.options`) that changed
between v3 and v4. This replaces it with a `z.object()` schema using
`.default()` so that Zod owns the default values and type inference,
and derives the valid values and received input without reaching into
undocumented error properties.
This does not migrate all `zod/v3` imports in the package, as the
remaining usages are tied to public API types (e.g. `AnyZodObject`
from `@backstage/backend-plugin-api`).
Signed-off-by: Jon Koops <jonkoops@gmail.com>