Skip to content

ENG-3270: Add target_system_steward_ids column to StagedResource#7912

Merged
dsill-ethyca merged 8 commits intomainfrom
ENG-3270-staged-resource-steward
Apr 15, 2026
Merged

ENG-3270: Add target_system_steward_ids column to StagedResource#7912
dsill-ethyca merged 8 commits intomainfrom
ENG-3270-staged-resource-steward

Conversation

@dsill-ethyca
Copy link
Copy Markdown
Contributor

@dsill-ethyca dsill-ethyca commented Apr 14, 2026

Ticket ENG-3270

Description Of Changes

Adds a nullable target_system_steward_ids column (ARRAY(String)) to StagedResource for per-resource steward assignment. This is the OSS data model foundation for the fidesplus per-resource steward feature.

Semantics:

  • None (default) — steward assignment not set; fidesplus uses monitor-level fallback on promotion
  • [] (empty list) — explicitly no stewards; fidesplus skips monitor fallback
  • ["user_id_1", ...] — explicit steward assignment

This follows the same nullable-vs-empty convention as user_assigned_data_uses.

Naming decision: target_system_steward_ids was chosen over steward_ids or user_assigned_steward_ids to make it explicit that these are stewards for the target system this resource will become upon promotion, not stewards of the staged resource itself.

Code Changes

  • src/fides/api/models/detection_discovery/core.py — Added target_system_steward_ids column to StagedResource
  • src/fides/api/alembic/migrations/versions/xx_..._add_target_system_steward_ids_to_stagedresource.py — Alembic migration adding the column

Steps to Confirm

  1. Run the migration:

    nox -s dev -- shell
    cd src/fides/api/alembic && alembic upgrade head

    Expected: Migration applies cleanly.

  2. Verify column exists:

    SELECT column_name, data_type FROM information_schema.columns
    WHERE table_name = 'stagedresource' AND column_name = 'target_system_steward_ids';

    Expected: target_system_steward_ids | ARRAY

Pre-Merge Checklist

  • All CI Pipelines Succeeded
  • Documentation:
    • No documentation needed (internal column, no API changes in OSS)
  • Issue Requirements are Met
  • Update CHANGELOG.md
    • Add a high-risk This issue suggests changes that have a high-probability of breaking existing code label if high-risk

Dependent PR: fidesplus#3409 depends on this PR being merged first.

🤖 Generated with Claude Code

Add nullable ARRAY(String) column for per-resource steward assignment.
None = use monitor fallback on promotion, [] = explicitly no stewards.
Includes alembic migration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Apr 14, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Actions Updated (UTC)
fides-plus-nightly Ignored Ignored Preview Apr 15, 2026 7:21pm
fides-privacy-center Ignored Ignored Apr 15, 2026 7:21pm

Request Review

dsill-ethyca and others added 2 commits April 14, 2026 11:36
The steward_ids migration pointed to c5d6e7f8a9b0 which already had
a child (1724da7ee981), creating multiple heads. Repoint to b3c8d5e7f2a1
which is the actual chain tip after merging main.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 14, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.06%. Comparing base (330f838) to head (ec0e78c).
⚠️ Report is 15 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #7912   +/-   ##
=======================================
  Coverage   85.06%   85.06%           
=======================================
  Files         629      629           
  Lines       40855    40860    +5     
  Branches     4748     4748           
=======================================
+ Hits        34753    34758    +5     
  Misses       5029     5029           
  Partials     1073     1073           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

dsill-ethyca and others added 2 commits April 14, 2026 12:32
Required for fides scan dataset db check to pass with 100% coverage.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@dsill-ethyca dsill-ethyca marked this pull request as ready for review April 14, 2026 19:56
@dsill-ethyca dsill-ethyca requested a review from a team as a code owner April 14, 2026 19:56
@dsill-ethyca dsill-ethyca requested review from johnewart and removed request for a team April 14, 2026 19:56
Copy link
Copy Markdown
Contributor

@claude claude Bot left a comment

Choose a reason for hiding this comment

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

Code Review: Add steward_ids column to StagedResource

Scope: SQLAlchemy model change + Alembic migration. Two files of substance; the changelog and db_dataset.yml additions are trivial.

Migration chain

I traced the full April migration chain to verify down_revision:

d4e5f6a7b8c9 → 22cf8ccaec40 → 6a42f48c23dd → b9c4d5e6f7a8
  → c5d6e7f8a9b0 → 1724da7ee981 → b3c8d5e7f2a1  ← (current head)
                                                       ↑
                                         a42ef09a3dfe  (this PR)

b3c8d5e7f2a1 (add_google_workspace_connectiontype) is the true leaf — nothing else names it as a down_revision. The migration in this PR correctly extends from it. No multi-head issue.

Findings

Suggestion — server_default=None is a no-op (inline comment on line 687)

This is consistent with the existing user_assigned_data_uses pattern but doesn't add meaningful information. Low priority; noted for awareness.

Suggestion — missing test for None vs [] semantic (inline comment on line 681)

The comment documents a behavioural contract that fidesplus will depend on. An existing test covers this for user_assigned_data_uses; a parallel test for steward_ids would protect the contract from silent regressions.

Overall

The implementation is clean and minimal. The column type, nullability, and DDL are all correct. The comment explaining the None/[] distinction is appreciated. Both findings are non-blocking; the test gap is the more important of the two.

🔬 Codegraph: connected (46690 nodes)


💡 Write /code-review in a comment to re-run this review.

steward_ids = Column(
ARRAY(String),
nullable=True,
server_default=None,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

src/fides/api/models/detection_discovery/core.py:687

server_default=None is a no-op in SQLAlchemy — it means "emit no server-side default clause in DDL," which is already the behaviour when the parameter is omitted entirely. It doesn't communicate anything to the database that nullable=True doesn't already express.

This mirrors the identical pattern on user_assigned_data_uses, so it's consistent with local convention. If the intent is documentation-as-code (making the absence of a server default explicit), a brief inline comment would be clearer than the no-op keyword argument. Either way, not blocking — just worth being intentional.

# frontend to show a sparkle icon only for system-generated descriptions.
user_assigned_description = Column(String, nullable=True)

# Nullable to distinguish "not set" (None, use monitor fallback on promotion)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

src/fides/api/models/detection_discovery/core.py:681

The comment documents a three-way semantic (None = not set / use monitor fallback, [] = explicitly empty / skip fallback, [ids] = assigned stewards) that is a behavioural contract downstream code in fidesplus will rely on. There's already a test_empty_user_assigned_data_uses test in tests/ops/models/detection_discovery/test_core.py that verifies the equivalent contract for user_assigned_data_uses.

Consider adding a parallel test for steward_ids that asserts:

  1. A freshly created StagedResource has steward_ids is None (not []).
  2. Explicitly setting steward_ids = [] round-trips as an empty list, not NULL.

This would guard against future migrations or ORM changes accidentally collapsing the None/[] distinction.

@dsill-ethyca dsill-ethyca requested review from adamsachs and removed request for johnewart April 15, 2026 14:48
Copy link
Copy Markdown
Contributor

@adamsachs adamsachs left a comment

Choose a reason for hiding this comment

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

lgtm, i think the nullable approach is sound here 👍

i think the only thing to note is that at some point we'll want resource-level 'stewardship', i.e. assigning certain users to act on certain StagedResources. at that point, it may become a bit ambiguous whether steward_ids refers to those 'stewards' or the stewards created on promotion.

maybe we can just add in a comment here on the model generally to make it clear that these are stewards to be assigned on promotion? (not sure exactly the right way to phrase that...)

@dsill-ethyca
Copy link
Copy Markdown
Contributor Author

@adamsachs I think at the level of assigining permissions to specific users as stewards of the resource itself we may want to use a join table strategy similar to systemmanager for Systems, that way the users in such a relationship with the stagedresource will be FK'd to a User

For the sake of clarity here we could prefer to name this column something like promotable_steward_ids. I'm open to feedback on the actual prefix, but something in the name itself that notes "Stewards of the eventual System this thing is promoted to" rather than "Stewards of this thing"

@adamsachs
Copy link
Copy Markdown
Contributor

@adamsachs I think at the level of assigining permissions to specific users as stewards of the resource itself we may want to use a join table strategy similar to systemmanager for Systems, that way the users in such a relationship with the stagedresource will be FK'd to a User

For the sake of clarity here we could prefer to name this column something like promotable_steward_ids. I'm open to feedback on the actual prefix, but something in the name itself that notes "Stewards of the eventual System this thing is promoted to" rather than "Stewards of this thing"

yup, generally aligned on this vision. i think it's a good instinct to try to clarify this in the column name - the column name itself isn't that hard to adjust, but these names have a tendency to permeate up through the API and into the FE codebase too, so getting some clarity in the name could help reduce the need for a large-scale 'migration' down the road...

can't say i love promotable_steward_ids but i also can't say a good alternative immediately coming to mind 🤔

@dsill-ethyca
Copy link
Copy Markdown
Contributor Author

After discussion, we've settled on target_system_steward_ids as the column name.

Rationale: While user_assigned_steward_ids would match the existing user_assigned_* convention, the team felt that explicitly encoding "target system" in the name provides more clarity — these are stewards for the system this resource will become upon promotion, not stewards of the staged resource itself. This reduces ambiguity as the concept permeates into the API and frontend.

Renaming commit incoming for both this PR and the dependent fidesplus PR (#3409).

@dsill-ethyca dsill-ethyca changed the title ENG-3270: Add steward_ids column to StagedResource ENG-3270: Add target_system_steward_ids column to StagedResource Apr 15, 2026
Clarifies that these are stewards for the target system the staged
resource will become upon promotion, not stewards of the staged
resource itself. Name chosen to reduce ambiguity as it permeates
through the API and frontend.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@dsill-ethyca dsill-ethyca added this pull request to the merge queue Apr 15, 2026
Merged via the queue into main with commit c6fe17d Apr 15, 2026
69 checks passed
@dsill-ethyca dsill-ethyca deleted the ENG-3270-staged-resource-steward branch April 15, 2026 19:40
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