Commit Graph

73971 Commits

Author SHA1 Message Date
Fredrik Adelöw a3d55d7a0e cleanup(catalog-backend): fix blank lines and unsafe ticket fetching in tests
Remove extra blank lines left behind when the stitcher field was
removed from engine test constructors. Extract getStitchTicket helper
to assert the queue entry exists instead of using optional chaining
that could silently pass undefined.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-22 16:49:36 +02:00
Fredrik Adelöw 5b348f3ac1 refactor(catalog-backend): make stitchTicket required in performStitching
Now that immediate mode is removed, the stitch ticket is always
provided by the deferred worker. Remove the optional marker and all
the conditional guards that checked for its presence.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-22 16:34:06 +02:00
Fredrik Adelöw 9f85367cdc fix(catalog-backend): deduplicate entity IDs when marking for stitching after deletion
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-22 14:40:30 +02:00
Fredrik Adelöw f1d243293b test(catalog-backend): await engine start/stop in integration test harness
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-22 11:42:42 +02:00
Fredrik Adelöw eac181f1b5 fix(catalog-backend): fix immediate mode logging on repeated calls
A second call with mode='immediate' would incorrectly log "Unknown
strategy mode" because the deprecation flag was already set.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-21 22:38:04 +02:00
Fredrik Adelöw e335055c40 fix(catalog-backend): use hash check for stitch ticket guard instead of unreliable row counts
INSERT return values differ across database engines (row IDs, row
counts, or empty arrays), making them unsuitable for detecting blocked
upserts. Use a post-write hash verification instead, which works
reliably on all engines.

Adds test coverage for stale ticket rejection across all supported
database engines (MySQL 8, PostgreSQL 14/18, SQLite 3).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-21 18:07:12 +02:00
Fredrik Adelöw 8d38538a82 fix(catalog-backend): fix tsc error — Knex insert returns number[], not number
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-21 18:02:09 +02:00
Fredrik Adelöw e864f77e35 fix(catalog-backend): make stitch ticket guard atomic on PostgreSQL and SQLite
On PostgreSQL and SQLite, the stitch ticket check is now part of the
upsert WHERE clause, eliminating the TOCTOU window between the check
and the write. MySQL does not support ON CONFLICT ... DO UPDATE ... WHERE,
so it retains the separate SELECT with a negligible race window.

SQLite misreports affected rows for blocked upserts, so a post-write
hash verification is used there instead of the row count.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-21 17:59:31 +02:00
Fredrik Adelöw 5e6af9b7f6 fix(catalog-backend): fix stitcher error message and warn on unknown strategy mode
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-21 17:59:31 +02:00
Fredrik Adelöw b8731fc82b Remove unused DbRefreshStateRow import and logger declaration
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-21 17:59:31 +02:00
Fredrik Adelöw 7bab21f1ef Remove redundant entity existence check in performStitching
The initial SELECT entity_id FROM refresh_state check is redundant —
the processedResult query in the Promise.all already handles the
missing-entity case. This saves one database round trip per stitch.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-21 17:59:31 +02:00
Fredrik Adelöw bcbc92d2ad Bump changeset to minor for config schema change
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-21 17:59:30 +02:00
Fredrik Adelöw 4282877ba9 Restore log-once guard for immediate mode deprecation warning
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-21 17:59:30 +02:00
Fredrik Adelöw ed2a9fe492 Replace placeholder final_entities insert with upsert
Now that immediate mode is removed, the two-step pattern of inserting a
placeholder row and then updating it is unnecessary. Replace with a
single upsert that creates or updates the final_entities row in one
operation, removing a round-trip and simplifying the flow.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-21 17:59:30 +02:00
Fredrik Adelöw 640f6b37a3 Fix literal control chars in scriptProtocolPattern regex
The conflict resolution replaced unicode escapes with literal control
character bytes, causing GitHub to render the file as binary.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-21 17:59:30 +02:00
Fredrik Adelöw d0d1b9b5b9 Run prettier on files with formatting issues
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-21 17:59:30 +02:00
Fredrik Adelöw dc7678cdcc fix(catalog-backend): remove immediate mode stitching
Remove the immediate stitching strategy from the catalog-backend plugin.
All stitching now uses the deferred mode exclusively, which processes
entities asynchronously via a worker queue. This simplifies the stitching
subsystem by removing dead-weight code paths and the strategy parameter
threading, and fixes a bug where deleteWithEagerPruningOfChildren
hardcoded immediate-mode semantics regardless of configured mode.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-21 17:59:30 +02:00
Fredrik Adelöw 74c5fbbafd Merge pull request #34324 from backstage/freben/fix-entity-list-triple-fetch
fix(catalog-react): eliminate redundant entity list fetches during filter initialization
2026-05-21 16:48:32 +02:00
Fredrik Adelöw 5dbbb15574 Merge pull request #34323 from backstage/freben/split-query-entities-count
fix(catalog-backend): split queryEntities list and count queries
2026-05-21 15:56:09 +02:00
Fredrik Adelöw 35c473d736 Merge pull request #34273 from backstage/freben/catalog-db-perf-skill
catalog-backend: add query performance battery and baseline
2026-05-21 15:55:30 +02:00
Fredrik Adelöw 392c1b2851 refactor(catalog-react): drop useCallback on refresh — useDebounce uses a ref internally
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-21 10:18:24 +02:00
Fredrik Adelöw 77e7ad4c7d fix(catalog-react): clear fetch dedup ref on failure instead of reverting to previous params
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-21 10:12:51 +02:00
Fredrik Adelöw 720fb542d9 cleanup(catalog-react): remove dead appliedCursor field, fix cursor-mode guard, inline getPaginationMode
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-21 09:55:57 +02:00
Fredrik Adelöw 9e880b70fd Deduplicate adjustedFilters computation
Move the adjustedFilters useMemo above refresh and reuse it in both
the fetch callback and the frontend filtering memo.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 22:42:49 +02:00
Fredrik Adelöw ffa59be219 Revert lastFetchParamsRef on failed fetch to allow retries
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 20:24:34 +02:00
Fredrik Adelöw 779749fbd7 Guard against empty-filter fetch on mount and premature URL sync
The lastFetchParamsRef starts as undefined, so the initial debounce
would have fetched with an empty filter (returning every entity in
the catalog). Guard against this by skipping the fetch when no filter
components have registered yet.

Also skip the URL sync effect until at least one filter has been set,
to avoid briefly clearing filter query params from the URL bar before
filter components initialize.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 17:57:33 +02:00
Fredrik Adelöw 4694eb16e3 Revert EntityKindPicker ref — provider dedup handles it
The label is read by CatalogTable for the table title (e.g. "All
Components (42)"), so suppressing the label update would cause a
visible regression. The provider's ref-based fetch dedup already
prevents the redundant API call when only the label changes, so
the second updateFilters call is harmless.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 17:37:35 +02:00
Fredrik Adelöw 7c205457b6 Add changeset for entity list triple-fetch fix
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 17:31:38 +02:00
Fredrik Adelöw a103f0e604 test(catalog-react): add regression test for entity list fetch dedup
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 17:30:49 +02:00
Fredrik Adelöw 4222c73fd3 fix(catalog-react): eliminate redundant fetches in useEntityListProvider
Replace useAsyncFn + outputState comparison with ref-based fetch dedup
and generation counter. Split entity filtering into a synchronous
useMemo so frontend-only filter changes are instant.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 17:29:44 +02:00
Fredrik Adelöw dfb920fb6e fix(catalog-react): prevent EntityKindPicker from double-firing updateFilters on label change
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 17:28:00 +02:00
Fredrik Adelöw 2c4b4912c2 Add whereNotNull to count query sort-field EXISTS
The list CTE's INNER JOIN on search already excludes entities whose
sort-field value is NULL (truncated long values stored as NULL by
buildEntitySearch). Add the same whereNotNull to the count query's
EXISTS so totalItems matches the reachable set. Matters for fields
like metadata.description where ~128K entities have NULL values.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 16:59:39 +02:00
Fredrik Adelöw 02a6410992 Extract shared applyPredicates helper to deduplicate filter logic
The list CTE and count query both need the same filter, query, and
full-text-search predicates. Extract them into a shared
applyPredicates closure so they can't drift apart. Move the count
query construction next to the CTE for readability.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 16:35:41 +02:00
Fredrik Adelöw 59fef3e80b Add patch entry for #34323, remove shipped patches
Remove pr-33721, pr-34001, pr-34004 — all shipped in v1.51.0.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 16:31:30 +02:00
Fredrik Adelöw 0119806204 Update changeset to document totalItems semantic fix
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 16:29:17 +02:00
Fredrik Adelöw 4829e8961e fix(catalog-backend): split queryEntities list and count queries
The filtered CTE was referenced twice (count + data), preventing
Postgres 12+ from inlining it. This forced full materialization of
the filtered set before LIMIT could short-circuit. Split into two
separate queries run via Promise.all so the list CTE is only
referenced once and the planner can short-circuit on LIMIT.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 15:48:22 +02:00
Fredrik Adelöw 813608335f Merge pull request #34321 from backstage/freben/enter-prerelease-mode
Enter changeset prerelease mode
2026-05-20 11:21:53 +02:00
Fredrik Adelöw 34d86b8fe3 Enter changeset prerelease mode with tag "next"
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 11:10:47 +02:00
Fredrik Adelöw cd8e20d7bb Merge pull request #34314 from backstage/freben/stitch-claim-transaction
Fix stitch queue race: wrap claim in transaction
2026-05-20 10:33:53 +02:00
Fredrik Adelöw 1d10fc41e8 Update changeset and PR description to cover both fix sites
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 09:59:37 +02:00
Fredrik Adelöw dd52890773 Use ternary with await for consistent style and better stack traces
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 09:49:08 +02:00
Fredrik Adelöw 139a784ad4 Skip transaction wrapping when locking is not used
Only wrap the SELECT+UPDATE in a transaction for MySQL/PostgreSQL
where FOR UPDATE SKIP LOCKED is actually used. For sqlite3 the
transaction adds unnecessary BEGIN/COMMIT overhead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 09:44:31 +02:00
Fredrik Adelöw afc872aac6 Fix implicit any types on transaction callback parameters
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 08:06:37 +02:00
Fredrik Adelöw 6713e9fe72 Apply same transaction fix to getProcessableEntities
Same FOR UPDATE SKIP LOCKED race: the processing loop's claim query
had the SELECT and UPDATE as separate auto-committed statements.
The existing caller already wraps in a transaction, but this makes
the function self-protecting if called without one.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-20 00:09:16 +02:00
Fredrik Adelöw f328b6f37e Merge pull request #34316 from backstage/freben/fix-empty-each-tests
fix: correct postgres env var casing in deploy_packages workflow
2026-05-19 23:34:19 +02:00
Fredrik Adelöw 8abfa78e4c Revert eachSupportedId guard — env var fix is sufficient
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-19 23:23:37 +02:00
Fredrik Adelöw 2c53691962 Fix postgres env var casing in deploy_packages workflow
The env vars used lowercase postgres18/postgres14 instead of uppercase
POSTGRES18/POSTGRES14, which didn't match the names expected by
TestDatabases. This caused all postgres-only test suites to see no
available databases and crash.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-19 23:21:47 +02:00
Patrik Oldsberg 6733eb1823 Merge pull request #34313 from backstage/worktree-v1.51-release-notes
Add v1.51.0 release notes
2026-05-19 23:21:12 +02:00
Fredrik Adelöw 03f0f3f953 Add changeset
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-19 23:19:18 +02:00
Fredrik Adelöw 1cbc3241a1 fix(backend-test-utils): prevent suite crash when no databases are available
When eachSupportedId() returned an empty array, describe.each([]) would
throw and crash the entire test suite. Return a placeholder ID instead,
so individual tests fail with a clear error rather than preventing the
entire suite from running.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
2026-05-19 23:19:07 +02:00