Skip to content

feat: tprm exports#3891

Open
Mohamed-Hacene wants to merge 9 commits intomainfrom
feat/tprm-exports
Open

feat: tprm exports#3891
Mohamed-Hacene wants to merge 9 commits intomainfrom
feat/tprm-exports

Conversation

@Mohamed-Hacene
Copy link
Copy Markdown
Collaborator

@Mohamed-Hacene Mohamed-Hacene commented Apr 9, 2026

Summary by CodeRabbit

  • New Features

    • Ecosystem export: new UI option to download Entities, Solutions and Contracts as a multi-sheet XLSX; download is date-stamped and respects user access.
  • Localization

    • Added "exportEcosystem" translation key across supported languages for the new export label.
  • Bug Fix / Import Improvement

    • Contract import now accepts multiple solution references (newline/pipe/comma) and links all resolved solutions; records with missing refs are marked failed.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 9, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • ✅ Review completed - (🔄 Check again to review again)
📝 Walkthrough

Walkthrough

Adds export support: three TPRM viewsets gain ExportMixin and export_config; EntityViewSet adds collection GET action export_ecosystem returning a three-sheet XLSX. Frontend adds an ecosystem export link and a SvelteKit proxy route that downloads the backend XLSX with a dated filename.

Changes

Cohort / File(s) Summary
Backend: TPRM views
backend/tprm/views.py
Added ExportMixin to EntityViewSet, SolutionViewSet, ContractViewSet; added per-viewset export_config; implemented collection action EntityViewSet.export_ecosystem to collect access-scoped Entities/Solutions/Contracts, assemble ordered rows, escape formulas, and return an in-memory multi-sheet XLSX response.
Backend: Data import
backend/data_wizard/views.py
Changed contract import to treat solution_ref_id as multi-valued (split on newline/pipe/comma), resolve multiple Solution refs, mark missing refs as failures, and set the contract's many-to-many solutions relation on create/update.
Frontend: Routes & proxy
frontend/src/routes/(app)/(internal)/[model=urlmodel]/+page.svelte, frontend/src/routes/(app)/(internal)/[model=urlmodel]/export/ecosystem/+server.ts
Expanded export UI visibility to include entities, solutions, contracts; added conditional /export/ecosystem/ link for entities. Added SvelteKit GET handler that proxies ${BASE_API_URL}/entities/export_ecosystem/, validates response, and returns XLSX binary with a dated tprm-ecosystem-YYYY-MM-DD.xlsx download filename.
Frontend: Localization
frontend/messages/*.json (multiple locales)
Added exportEcosystem translation key across many locales and adjusted trailing commas/JSON punctuation where needed to insert the new key. Mostly single-key additions and minor JSON formatting fixes.

Sequence Diagram

sequenceDiagram
    actor User as "User"
    participant Frontend as "Frontend UI"
    participant Proxy as "SvelteKit Route"
    participant Backend as "Backend API\n(EntityViewSet.export_ecosystem)"
    participant DB as "Database"

    User->>Frontend: Click "ecosystem export"
    Frontend->>Proxy: GET /[model]/export/ecosystem/
    Proxy->>Backend: GET /entities/export_ecosystem/
    Backend->>DB: Query Entities, Solutions, Contracts (access-scoped, with select_related/prefetch)
    DB-->>Backend: Return rows
    Backend->>Backend: Build 3-sheet Excel (Entities, Solutions, Contracts) in-memory
    Backend-->>Proxy: Return XLSX binary
    Proxy->>Proxy: Set Content-Disposition with dated filename
    Proxy-->>Frontend: XLSX response (binary)
    Frontend-->>User: Browser downloads file
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐇 I nibbled rows and stitched three sheets with care,

Names, refs, and contracts bundled neatly there.
I dodged wild formulas and wrapped each cell tight,
Sent the ecosystem off, gleaming and light.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: tprm exports' directly and concisely summarizes the main objective: adding export functionality to TPRM (Threat and Risk Management) modules.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/tprm-exports

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 and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@backend/tprm/views.py`:
- Around line 646-716: The exported XLSX writes raw text that may begin with
Excel formula characters; to fix, reuse the ExportMixin._resolve_field_value()
escaping logic (or replicate its check for leading =,+,-,@ and prefix with a
safe escape) when building the rows for entities_rows, solutions_rows and
contracts_rows: pass every user-controlled string field (ref_id, name,
description, mission, domain, legal identifiers lei/euid/vat/duns,
provider_entity_ref_id, solution_ref_id, status and any other string fields you
add) through that escape routine before adding them to the dicts so no cell is
interpreted as a live formula.
- Around line 1178-1183: The export currently collapses Contract.solutions by
using the "solution_ref_id" field with format=lambda qs: qs.first().ref_id which
loses all but the first linked solution; change the export to preserve all
associations by either (A) emitting one export row per contract/solution pair
(adjust the export iterator that builds rows for contracts to loop over
contract.solutions and yield separate rows) or (B) serialize all linked ref_ids
in the "solution_ref_id" field (replace the format lambda with one that returns
a deterministic serialized list e.g. comma- or JSON-array of
qs.values_list('ref_id', flat=True)) and ensure the importer can parse that
format; update the matching ecosystem export code that uses the same pattern to
the same approach so round-trips are lossless.
- Around line 627-644: The Solution queryset is not being IAM-filtered: call
RoleAssignment.get_accessible_object_ids(Folder.get_root_folder(), request.user,
Solution) to obtain visible_solution_ids, then replace the current solutions =
Solution.objects.filter(provider_entity__id__in=viewable_entity_ids) with a
queryset filtered by id__in=visible_solution_ids; additionally, when building
contract rows only include contract.solutions entries whose IDs are in
visible_solution_ids (i.e., intersect contract.solutions.all() with
visible_solution_ids) so contract.solutions cannot expose unauthorized Solution
rows or solution_ref_id values.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5c9cf15b-4b07-4d4d-9177-5f4b549e7fa1

📥 Commits

Reviewing files that changed from the base of the PR and between 0fd83c3 and 1ea59e6.

📒 Files selected for processing (4)
  • backend/tprm/views.py
  • frontend/messages/en.json
  • frontend/src/routes/(app)/(internal)/[model=urlmodel]/+page.svelte
  • frontend/src/routes/(app)/(internal)/[model=urlmodel]/export/ecosystem/+server.ts

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 14

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
frontend/messages/zh.json (1)

1-3210: ⚠️ Potential issue | 🟡 Minor

Prettier is still failing for this file in CI.

Frontend linters report style issues here; please run Prettier on this file (or the repo) before merge.

pnpm exec prettier --write frontend/messages/zh.json
# or
pnpm exec prettier --write .
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/messages/zh.json` around lines 1 - 3210, Prettier formatting errors
in frontend/messages/zh.json are causing CI to fail; run Prettier on that file
(e.g. pnpm exec prettier --write frontend/messages/zh.json or pnpm exec prettier
--write .), review and commit the resulting changes, then push so CI picks up
the formatted file and the lint step passes.
frontend/messages/tr.json (1)

1-1911: ⚠️ Potential issue | 🟠 Major

Resolve Prettier issues in this file before merge.

CI reports style violations for this file. Please run Prettier and commit the result (including proper EOF newline) so the frontend linter check passes.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/messages/tr.json` around lines 1 - 1911, The file contains Prettier
formatting violations reported by CI; run your project's Prettier configuration
(e.g., npx prettier --write) on frontend/messages/tr.json, fix style
(indentation, trailing commas, quotes) and ensure a final newline at EOF, then
commit the formatted file so the frontend linter passes; reference this specific
resource (frontend/messages/tr.json) when making the change.
🧹 Nitpick comments (2)
frontend/messages/el.json (1)

1861-1861: Consider title-case consistency for the new menu/action label.

"εξαγωγή οικοσυστήματος (XLSX)" could be aligned with other action labels as "Εξαγωγή οικοσυστήματος (XLSX)".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/messages/el.json` at line 1861, The label for the i18n key
exportEcosystem uses sentence-case ("εξαγωγή οικοσυστήματος (XLSX)") and should
be changed to title-case to match other action labels; update the value of
exportEcosystem to "Εξαγωγή οικοσυστήματος (XLSX)" so the initial letter is
capitalized, preserving the parenthetical "(XLSX)" exactly as before.
frontend/messages/sv.json (1)

1164-1164: Polish the new Swedish label casing for consistency.

At Line 1164, ekosystemexport (XLSX) starts lowercase while neighboring action labels are typically sentence-cased. Consider Ekosystemexport (XLSX) (or approved translator wording).

💬 Suggested text tweak
-	"exportEcosystem": "ekosystemexport (XLSX)"
+	"exportEcosystem": "Ekosystemexport (XLSX)"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/messages/sv.json` at line 1164, Update the Swedish label value for
the "exportEcosystem" key to match sentence-casing used by neighboring action
labels: change "ekosystemexport (XLSX)" to "Ekosystemexport (XLSX)" (or apply
the approved translator wording) so the key "exportEcosystem" uses consistent
capitalization.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/messages/ar.json`:
- Around line 1141-1142: The JSON message entry "exportEcosystem" in ar.json is
failing Prettier/style checks; run the project's Prettier formatter (e.g., pnpm
exec prettier --write frontend/messages/ar.json) to normalize formatting, ensure
the file ends with a single newline (EOF newline), and commit the updated
ar.json so CI passes; target the "exportEcosystem" key to locate the offending
file/entry.

In `@frontend/messages/da.json`:
- Around line 1454-1456: The file frontend/messages/da.json is failing
Prettier/style checks due to formatting (likely trailing newline or JSON
formatting); run Prettier on this file (or project) and re-commit so keys like
"syncToReferenceControl" and "exportEcosystem" are formatted correctly and the
expected EOF newline is restored around the end of the file; ensure the JSON
remains valid after formatting and re-run CI linting before pushing.

In `@frontend/messages/de.json`:
- Line 3057: The file is missing a final newline which trips the formatter/CI;
open the file and add a single trailing newline at the end of the file (ensure
the EOF character is a newline) so the formatter/Prettier checks pass.

In `@frontend/messages/el.json`:
- Around line 1861-1862: The file ends without a trailing newline (key
"exportEcosystem": "εξαγωγή οικοσυστήματος (XLSX)"); add a single newline
character at the end of frontend/messages/el.json so the file ends with a final
blank line to satisfy Prettier EOF formatting checks.

In `@frontend/messages/hi.json`:
- Around line 1142-1143: The hi.json file has a Prettier/style failure for the
translation key "exportEcosystem"; fix it by formatting
frontend/messages/hi.json with your project's Prettier config (for example run
the project's Prettier command to rewrite the file) and re-commit the formatted
file so CI formatting checks pass.

In `@frontend/messages/id.json`:
- Line 1359: Run Prettier to fix formatting issues reported by CI: execute the
formatter (pnpm exec prettier --write .) to reformat the project files including
the JSON translations, then stage and commit the changes so the lint/format
checks pass; ensure you run the same command locally and push the formatted
result to unblock CI.

In `@frontend/messages/it.json`:
- Line 2406: The new locale key "exportEcosystem" has a lowercase label
"esportazione dell'ecosistema (XLSX)" which is inconsistent with nearby UI
labels; update the string value for "exportEcosystem" to use consistent
capitalization (e.g., "Esportazione dell'ecosistema (XLSX)") so it matches the
casing style of other entries in the locale file and the UI.
- Around line 2405-2407: Prettier formatting is failing for the JSON file: run
Prettier (or your project's format script) on the file and commit the formatted
output so CI passes; specifically ensure the JSON containing the keys
"syncToReferenceControl" and "exportEcosystem" is normalized (correct
indentation, trailing newline, and spacing) and that the updated file is added
to the commit before pushing.

In `@frontend/messages/ko.json`:
- Line 3866: Prettier is failing for the Korean locale JSON (ko.json) due to
formatting issues; run Prettier/your project's formatter on the ko.json file to
reformat it and commit the changes so the linter passes, ensuring the JSON is
valid (no trailing commas, proper indentation and a single closing brace "}"
correctly placed) and that the file passes CI formatting checks.

In `@frontend/messages/lt.json`:
- Around line 4150-4152: The JSON file frontend/messages/lt.json has Prettier
style violations (trailing/newline formatting) that block CI; run Prettier over
this file (or your repo) to reformat it and ensure the file ends with a single
newline, then re-commit—verify keys like "soaSelectRiskDescription" and
"exportEcosystem" remain unchanged after formatting.

In `@frontend/messages/pl.json`:
- Around line 1702-1709: The JSON blocks containing the "declarations" and
"selectors" entries (e.g., keys "declarations", "selectors" and the plural
variables "count" and "countPlural") are misformatted per Prettier; run the
project's Prettier formatter on frontend/messages/pl.json (or run the configured
formatting script/IDE formatter) to normalize whitespace and line breaks for the
affected blocks (also fix similar blocks around lines referenced: 1719-1725,
1735-1741, 1751-1757, 1881-1888), then re-commit the reformatted file so CI
linting passes.

In `@frontend/messages/sv.json`:
- Line 1165: Prettier is failing on frontend/messages/sv.json due to EOF
formatting (missing trailing newline); run Prettier (or your project's format
command) on frontend/messages/sv.json to reformat the file and add the required
trailing newline, then stage and commit the updated file so the CI Prettier
check passes.

In `@frontend/messages/tr.json`:
- Around line 1909-1910: The label for the key "exportEcosystem" is a noun
phrase and lowercased; change it to an imperative, action-style Turkish string
and capitalize the first letter to match other labels (for example: "Ekosistemi
dışa aktar (XLSX)"), keeping the "(XLSX)" suffix intact so the key
exportEcosystem becomes a concise command.

In `@frontend/messages/ur.json`:
- Around line 1141-1142: The file ends without a trailing newline causing
Prettier to fail; open the JSON resource containing the "exportEcosystem" key
and ensure the file terminates with a single newline character (add a trailing
'\n' after the last line: the "exportEcosystem": "ماحول کی برآمدگی (XLSX)"
entry) so formatting checks pass.

---

Outside diff comments:
In `@frontend/messages/tr.json`:
- Around line 1-1911: The file contains Prettier formatting violations reported
by CI; run your project's Prettier configuration (e.g., npx prettier --write) on
frontend/messages/tr.json, fix style (indentation, trailing commas, quotes) and
ensure a final newline at EOF, then commit the formatted file so the frontend
linter passes; reference this specific resource (frontend/messages/tr.json) when
making the change.

In `@frontend/messages/zh.json`:
- Around line 1-3210: Prettier formatting errors in frontend/messages/zh.json
are causing CI to fail; run Prettier on that file (e.g. pnpm exec prettier
--write frontend/messages/zh.json or pnpm exec prettier --write .), review and
commit the resulting changes, then push so CI picks up the formatted file and
the lint step passes.

---

Nitpick comments:
In `@frontend/messages/el.json`:
- Line 1861: The label for the i18n key exportEcosystem uses sentence-case
("εξαγωγή οικοσυστήματος (XLSX)") and should be changed to title-case to match
other action labels; update the value of exportEcosystem to "Εξαγωγή
οικοσυστήματος (XLSX)" so the initial letter is capitalized, preserving the
parenthetical "(XLSX)" exactly as before.

In `@frontend/messages/sv.json`:
- Line 1164: Update the Swedish label value for the "exportEcosystem" key to
match sentence-casing used by neighboring action labels: change "ekosystemexport
(XLSX)" to "Ekosystemexport (XLSX)" (or apply the approved translator wording)
so the key "exportEcosystem" uses consistent capitalization.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9bd25e02-afc9-46fc-99f6-aa9202359414

📥 Commits

Reviewing files that changed from the base of the PR and between 1ea59e6 and 0808033.

📒 Files selected for processing (23)
  • backend/tprm/views.py
  • frontend/messages/ar.json
  • frontend/messages/cs.json
  • frontend/messages/da.json
  • frontend/messages/de.json
  • frontend/messages/el.json
  • frontend/messages/es.json
  • frontend/messages/fr.json
  • frontend/messages/hi.json
  • frontend/messages/hr.json
  • frontend/messages/hu.json
  • frontend/messages/id.json
  • frontend/messages/it.json
  • frontend/messages/ko.json
  • frontend/messages/lt.json
  • frontend/messages/nl.json
  • frontend/messages/pl.json
  • frontend/messages/ro.json
  • frontend/messages/sv.json
  • frontend/messages/tr.json
  • frontend/messages/uk.json
  • frontend/messages/ur.json
  • frontend/messages/zh.json
✅ Files skipped from review due to trivial changes (8)
  • frontend/messages/ro.json
  • frontend/messages/hu.json
  • frontend/messages/hr.json
  • frontend/messages/nl.json
  • frontend/messages/uk.json
  • frontend/messages/fr.json
  • frontend/messages/cs.json
  • frontend/messages/es.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/tprm/views.py

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
backend/tprm/views.py (1)

1-1: ⚠️ Potential issue | 🟡 Minor

Fix ruff formatting to pass CI.

The pipeline indicates ruff format --check . failed with this file needing reformatting. Run ruff format backend/tprm/views.py locally and commit the formatted output.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/tprm/views.py` at line 1, Run the ruff formatter on the file
backend/tprm/views.py and commit the changes so CI passes; specifically run
`ruff format backend/tprm/views.py` (or `ruff format .`) locally, review and
stage the updated file (which will adjust imports/whitespace per ruff rules for
the module that currently contains the `import re` line), then push the
formatted file so `ruff format --check .` succeeds in CI.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/messages/es.json`:
- Line 3170: The message key "exportEcosystem" currently uses a lower-case noun
phrase; change its Spanish value to an action-style, capitalized label to match
other UI export buttons (e.g., replace "exportación de ecosistema (XLSX)" with
"Exportar ecosistema (XLSX)") so the label is verb-based and consistent with
other export actions.

In `@frontend/messages/id.json`:
- Line 1331: The new i18n label key "exportEcosystem" uses lowercase text;
update its value to sentence-case to match other action labels by changing
"ekspor ekosistem (XLSX)" to "Ekspor ekosistem (XLSX)" so the first character is
capitalized while preserving the rest and the file's formatting.

---

Outside diff comments:
In `@backend/tprm/views.py`:
- Line 1: Run the ruff formatter on the file backend/tprm/views.py and commit
the changes so CI passes; specifically run `ruff format backend/tprm/views.py`
(or `ruff format .`) locally, review and stage the updated file (which will
adjust imports/whitespace per ruff rules for the module that currently contains
the `import re` line), then push the formatted file so `ruff format --check .`
succeeds in CI.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7749fdea-c5c2-491c-be6f-af5dddc2847d

📥 Commits

Reviewing files that changed from the base of the PR and between 0808033 and 56c3903.

📒 Files selected for processing (22)
  • backend/tprm/views.py
  • frontend/messages/ar.json
  • frontend/messages/cs.json
  • frontend/messages/da.json
  • frontend/messages/de.json
  • frontend/messages/el.json
  • frontend/messages/es.json
  • frontend/messages/hi.json
  • frontend/messages/hr.json
  • frontend/messages/hu.json
  • frontend/messages/id.json
  • frontend/messages/it.json
  • frontend/messages/ko.json
  • frontend/messages/lt.json
  • frontend/messages/nl.json
  • frontend/messages/pl.json
  • frontend/messages/ro.json
  • frontend/messages/sv.json
  • frontend/messages/tr.json
  • frontend/messages/uk.json
  • frontend/messages/ur.json
  • frontend/messages/zh.json
✅ Files skipped from review due to trivial changes (10)
  • frontend/messages/hu.json
  • frontend/messages/ur.json
  • frontend/messages/de.json
  • frontend/messages/da.json
  • frontend/messages/ar.json
  • frontend/messages/uk.json
  • frontend/messages/ko.json
  • frontend/messages/hr.json
  • frontend/messages/zh.json
  • frontend/messages/el.json
🚧 Files skipped from review as they are similar to previous changes (7)
  • frontend/messages/cs.json
  • frontend/messages/hi.json
  • frontend/messages/sv.json
  • frontend/messages/lt.json
  • frontend/messages/tr.json
  • frontend/messages/pl.json
  • frontend/messages/it.json

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
backend/tprm/views.py (1)

1205-1225: ⚠️ Potential issue | 🔴 Critical

IAM-filter contract.solutions in the generic export endpoints.

ExportMixin._get_export_queryset() only scopes Contract IDs. With the current static prefetch_related=["solutions"] and these formatters, export_csv/export_xlsx will still serialize linked solutions the caller cannot view.

🔒 Suggested fix
     export_config = {
         "filename": "contracts_export",
         "fields": {
             ...
         },
         "select_related": ["folder", "provider_entity"],
-        "prefetch_related": ["solutions"],
         "wrap_columns": ["name", "description"],
     }
+
+    def _get_export_queryset(self):
+        queryset = super()._get_export_queryset()
+        (viewable_solution_ids, _, _) = RoleAssignment.get_accessible_object_ids(
+            Folder.get_root_folder(), self.request.user, Solution
+        )
+        return queryset.prefetch_related(
+            Prefetch(
+                "solutions",
+                queryset=Solution.objects.filter(id__in=viewable_solution_ids),
+            )
+        )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/tprm/views.py` around lines 1205 - 1225, The export currently uses a
static prefetch_related=["solutions"] and format lambdas
("solution_ref_id"/"solution") which will include all linked Solution objects
even if the caller lacks IAM access; replace the static prefetch with a Prefetch
that uses a queryset filtered by the same IAM rules as export (e.g.,
Prefetch("solutions", queryset=self._get_filtered_solutions_qs(request)) ), and
implement a helper on the view (e.g., _get_filtered_solutions_qs or reuse an
existing IAM helper) that returns only Solutions the requester can view; keep
the existing format lambdas but iterate over the prefetched, IAM-filtered
related set so exported solution names/ref_ids are limited to authorized items.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@backend/data_wizard/views.py`:
- Around line 3518-3531: The parsing code for solution_ref_id
(solution_ref_id_raw -> loop that appends to solution_ids using
solution_ref_map) currently only logs missing refs and silently drops them;
instead detect unresolved refs during that loop and surface them to the caller
by collecting the missing ref strings and failing the row import (e.g., append a
validation error for this record or raise a descriptive exception including
ref_id and the missing solution refs) so the API returns a clear error rather
than persisting an incomplete contract.solutions set; update the parsing block
to gather unresolved refs and return/raise a validation error referencing ref_id
and the missing solution_ref_id values.

In `@backend/tprm/views.py`:
- Around line 701-724: The export currently builds newline-delimited
solution_ref_id/solution from contract_solutions which breaks the importer;
change both export paths (the block building contracts_rows and the similar
block at lines ~1205-1215) to emit a single value by selecting the first linked
solution if present: use contract_solutions = list(contract.solutions.all())
then set solution_ref_id to esc(contract_solutions[0].ref_id) if
contract_solutions and contract_solutions[0].ref_id else "" and likewise set
solution to esc(contract_solutions[0].name) if present, ensuring provider fields
remain unchanged.

---

Duplicate comments:
In `@backend/tprm/views.py`:
- Around line 1205-1225: The export currently uses a static
prefetch_related=["solutions"] and format lambdas ("solution_ref_id"/"solution")
which will include all linked Solution objects even if the caller lacks IAM
access; replace the static prefetch with a Prefetch that uses a queryset
filtered by the same IAM rules as export (e.g., Prefetch("solutions",
queryset=self._get_filtered_solutions_qs(request)) ), and implement a helper on
the view (e.g., _get_filtered_solutions_qs or reuse an existing IAM helper) that
returns only Solutions the requester can view; keep the existing format lambdas
but iterate over the prefetched, IAM-filtered related set so exported solution
names/ref_ids are limited to authorized items.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cb20f8d3-2e0c-4302-8030-41371a34b253

📥 Commits

Reviewing files that changed from the base of the PR and between 56c3903 and 1039803.

📒 Files selected for processing (2)
  • backend/data_wizard/views.py
  • backend/tprm/views.py

Copy link
Copy Markdown
Collaborator

@eric-intuitem eric-intuitem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants