Andrey Antukh bcac14a4a8
🐛 Skip circular library links on binfile import (#12062)
* 🐛 Skip circular library links on binfile import

File import recreated circular library references that the
link-file-to-library command already rejects. The v3 importer
now skips manifest relations that would close a cycle, or link
a file to itself, and logs each skipped link. Closes #12052.

AI-assisted-by: muse-spark-1.3-contributor-free

🐛 Address review findings on circular import guard

F1 extracts the cycle check into bfc/library-link-status and reuses
it in link-file-to-library and v3 import, keeping UI errors intact.

F3 orders get-files-rels and manifest relations so the first edge
wins deterministically, and documents it.

F2 adds a three-node transitive cycle test; F4 asserts file_library_sync
has no orphan rows for skipped links and matches rels otherwise.

AI-assisted-by: muse-spark-1.3-contributor

🐛 Pass team-id in binfile v3 circular library tests

The four circular library relation tests (import-skips-circular,
import-skips-transitive-cycle, import-skips-self-referencing,
import-keeps-acyclic) called v3/import-files! without ::bfc/team-id.
resolve-and-link-libraries asserts (uuid? team-id), so with
enable-backend-asserts the tests errored instead of running.

Add (assoc ::bfc/team-id (:default-team-id profile)) to each test,
mirroring the production RPC import path and the earlier fix in
a36193e54b for the other binfile v3 import tests.

Verified: 1338 tests, 6910 assertions, 0 failures.

AI-assisted-by: mistral-large-4

* 🐛 Guard the v1 import and restore the RPC check order

The version 1 importer recreated the circular library references that
the version 3 importer already skips, and a user reaches it through
`import-binfile` and the import job. It now asks
`bfc/library-link-status` before inserting each relation, so a self
link or an edge that would close a cycle is skipped and logged, and it
processes the relations in sorted order like v3 does. Closes #12052.

The version 2 importer stays out on purpose: only the developer REPL
reaches it, and a note in the code records the gap.

`link-file-to-library` keeps the shared helper but restores the order
of the base commit: the self link guard, then the edition permission
and team ownership checks, and only then the cycle check. A caller
without permission gets `not-found` again instead of the circular
error, and a rejected request no longer runs the recursive library
query first.

Tests: a v1 import that recreates a cycle, the self link error of the
command, and the permission check running before the cycle check.

AI-assisted-by: deepseek-v4.1-flash

* 🐛 Tolerate repeated file entries in the v1 binfile import

The v1 exporter unioned the requested files with their libraries
without deduplicating, so a package exported from a file inside a
library cycle (see #12052) lists that file twice in the metadata. The
v1 import created one file per entry, so the second insert hit the
primary key of `file` and aborted the whole import with "file already
exists".

The importer now reads the pair of objects of every entry to keep the
stream in sync but imports the first occurrence only, warns about the
repeats, and answers with one id per imported file.

The v1 export keeps its behavior: it has no caller in the product, and
only the tests and the developer REPL use it.

Tests: a package with a repeated entry, built with the v1 export from
a cyclic library pair, imports the file once and leaves no duplicated
rows.

AI-assisted-by: deepseek-v4.1-flash
2026-11-11 13:02:57 +01:00
..
2026-09-09 17:58:09 +02:00
2026-09-29 09:07:34 +02:00
2026-09-09 17:58:09 +02:00