Skip to content

feat(frontend): let an admin decide what a migration copy asks - #15623

Open
ogabrielluiz wants to merge 1 commit into
feat/migration-page-copy-storesfrom
feat/migration-page-copy-decisions
Open

ogabrielluiz wants to merge 1 commit into
feat/migration-page-copy-storesfrom
feat/migration-page-copy-decisions

Conversation

@ogabrielluiz

Copy link
Copy Markdown
Contributor

Stacked on the PR below it. The three copy steps of Settings > Migration can now be told what to do about what a copy could not do by itself. From the API PRs further down the stack it needs POST and DELETE /api/v1/migration/decisions, and the decision the record gives each failed item and what the database copy asked, with the run it belongs to and whether it is in effect.

What it adds

A decision is a checkbox. Ticking it records the decision, and unticking takes it back. The box is ticked while the server holds the decision as made, and under it the step says who decided and when.

The server says which decision answers what. Each failed item in the record carries the decision that fits its code, or none, and so does what the database copy asked. While a decision is in effect the server also says who made it and when: an option once it is recorded, an acceptance when it was recorded for the copy on record. The page offers that decision, ticks it and names who made it from what the server says, and sends it back as it came. It keeps no table of its own from codes to decisions, and it does not look a decision up in the record. It has a label for each of the five decisions the server knows today, and it offers none it has no label for.

The database copy stops when rows point at items that were deleted. The step explains it, lists the rows by table, and offers "Leave these rows out and copy the rest". Once the copy is done, its row says how many rows were left out.

A decision that names no item is an option for the whole step, like the new ranking of knowledge bases. It is asked once, below the list, however many items wait for it. An option changes the next copy only, so the step says to copy again.

A decision that names an item accepts that item as the copy left it: a knowledge base left behind, the bucket's file kept, a file with nothing to copy. It settles at once, and the step can read done with nothing run again.

An acceptance names the run whose list the item is in, as the server gave it. If another copy was made since, in another tab or by another admin, the server refuses the choice. The step then reads the state again and says in one line that the copy was made again and that the list is the new copy's. Taking an acceptance back follows the same rule.

An item is accepted in the copy that left it, so after a test run the step offers options only. When more items failed than the record keeps, the server offers no acceptance, and the step says why. An option for the whole step stays on offer there. A copy that is out of date asks nothing.

The check of the first step may have asked about the same loss, and the admin may have accepted it there. That acceptance is not carried over, because a decision is consent for one copy. So that the second ask makes sense, the step says above the list that accepting a finding in "Check this instance" lets the move go on, and that each item this copy left is accepted here by name, for this copy only. The checkbox for a file with nothing to copy reads "Move without this file".

Try it

The decision that needs no special data is the missing file. Delete an uploaded file from the instance's disk, accept the finding in the first step, and go on to "Copy files". The step lists the file and says why it asks again. Tick "Move without this file" and the step reads done. Untick it and the step waits again.

The other decisions need an instance that has rows pointing at a deleted trace, a knowledge base whose vectors are not unit length, a knowledge base in a store this version cannot open, or a file whose name the bucket already holds with other content.

How it was tested

Jest has 15 new tests. They cover the rows the database copy would leave out, a copy that asked with no decision on offer, a decision in effect and its withdrawal, an option that several items share, which items get a checkbox and which do not, the request each checkbox sends, a test run, a list that is too long to accept from, a decision the page has no label for, the line that says why a copy asks again, the run each choice names, a choice the server refused, and a choice for a list that another copy replaced, with the state read again. The records in these tests carry the decisions a server would send. Jest sends no request. I planted 43 one-line defects in this PR's code, one at a time, and a Jest test fails for each. The whole Jest suite of the frontend passes with this PR.

tests/core/features/migration-copy.spec.ts gains a walk in a browser against a real backend, a real PostgreSQL database and a real S3 bucket. It removes the bytes of a file it uploaded, copies the files, reads why the step asks again, accepts the file on the page, takes that back and accepts it again, and sees the step follow each time. It skips unless MIGRATION_E2E_DATABASE_URL and MIGRATION_E2E_S3_BUCKET are set, so it does not run in CI. A copy needs changes paused, which refuses every change to the instance, so the walk cannot share the CI backend with other specs.

By hand, I made every decision on the page against a real backend whose instance was seeded to need them: two rows pointing at a deleted trace, a knowledge base with vectors that are not unit length, one in a store that cannot be opened, a file the bucket held with other content, and a file with no bytes. The server offered the option for the rows and for the ranking, and an acceptance for the other three. Each acceptance went back with the run it was given, and each option with none. The database copy was refused, then copied 61 rows and left 2 out. After its test run the knowledge base step offered the ranking option only. Its copy ended with 2 of 3 copied, and the step read done once the third was left behind. The file copy read done as soon as both files were accepted, blocked again when one acceptance was taken back, and done again when it was restored.

npm run check:i18n passes with the 13 new strings in all 8 locales. Biome is clean on the touched files, and the type check shows no new error.

A copy can stop to ask. The server says which decision answers each
failed item and what the database copy asked, and whether that decision
is in effect. The page offers it as a checkbox, ticks it from what the
server says, and sends it back as it came. The page has words for five
of them: leaving out rows that point at deleted items, accepting a new
ranking, leaving a knowledge base behind, keeping the bucket's file,
and moving without a file that has nothing to copy. It offers none it
has no words for.

A decision that names no item is an option for the whole step. It is
asked once, however many items wait for it, and it changes the next
copy, so the step says to copy again. A decision that names an item
accepts it at once, and unticking takes it back. Under a ticked box the
step says who decided and when, from what the server sends with the
decision.

An acceptance names the run whose list the item is in, as the server
gave it. When another copy was made since, the server refuses the
choice. The step reads the state again and says in one line that the
copy was made again and that the list is the new copy's.

An item is accepted in the copy that left it, so a test run offers
options only. When more items failed than the record keeps, the server
offers no acceptance, and the step says why. A copy that is out of date
asks nothing.

The check of the first step may have asked about the same loss. An
acceptance there lets the move go on. The step says so above the list,
and that each item a copy left is accepted by name, for that copy only.
@coderabbitai

coderabbitai Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (1)
  • release-.*

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: langflow-ai/langflow/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 2b90d00f-29f8-4a8e-9bef-9570c1d74abf

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the enhancement New feature or request label Oct 7, 2026
@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

✅ Test Coverage Advisor

No source changes detected without accompanying tests. Thanks for keeping coverage up! 🎉

Advisory check only — never blocks merge.

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Frontend Unit Test Coverage Report

Coverage Summary

Lines Statements Branches Functions
Coverage: 59%
59.35% (97567/164371) 74.09% (15233/20560) 54.65% (2417/4422)

Unit Test Results

Tests Skipped Failures Errors Time
7403 0 💤 0 ❌ 0 🔥 16m 50s ⏱️

This branch has not been deployed

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

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant