Skip to content

Make default link types required - #1101

Open
martastain wants to merge 6 commits into
developfrom
144-reserved-link-types
Open

martastain wants to merge 6 commits into
developfrom
144-reserved-link-types

Conversation

@martastain

Copy link
Copy Markdown
Member

This pull request introduces logic to ensure that all required default link types are present when loading or deploying a project. The main focus is on improving data integrity by automatically adding any missing default link types to a project's configuration, both during project loading and deployment. The changes also improve logging for better traceability.

Ensuring presence of default link types:

  • Added a new function ensure_required_project_link_types in project.py to check and create any missing default link types for a project during the loading process. This function is called in the _load method of ProjectEntity to guarantee required link types exist.
  • Updated deploy_project.py to iterate through default_link_types and append any missing ones to the project's anatomy during deployment, with debug logging for visibility.

@martastain martastain self-assigned this Aug 31, 2026
@martastain martastain linked an issue Aug 31, 2026 that may be closed by this pull request
@martastain martastain added the type: enhancement Improvement of existing functionality or minor addition label Aug 31, 2026
@martastain
martastain marked this pull request as ready for review September 9, 2026 10:16
@martastain
martastain requested a review from BigRoy September 9, 2026 10:16
@tatiana-ynput tatiana-ynput added the sponsored This is directly sponsored by a client or community member label Sep 11, 2026
@kalisp

kalisp commented Sep 11, 2026

Copy link
Copy Markdown
Member

How this could be actually tested? Trying to restore dump with missing link types?

@martastain

Copy link
Copy Markdown
Member Author

You could just delete some link types in develop and then switch to this branch... it should be repopulated 🤞

@BigRoy

BigRoy commented Sep 14, 2026

Copy link
Copy Markdown
Member

When should this trigger and recreate them?

I I delete Link Types from anatomy from a project, then restarting server - it doesn't recreate them.

Doesn't seem to work for me @martastain

@martastain
martastain requested a balanced review from Copilot September 17, 2026 14:02

Copilot AI left a comment

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@martastain

Copy link
Copy Markdown
Member Author

Fixed the check when cache is used

@martastain

Copy link
Copy Markdown
Member Author

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

🖕

Copilot AI left a comment

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.

🟡 Changes recommended

Cached loading can bypass validation, and conflict handling can cache a link type that is not present in the database.

Get a fresh assessment by requesting another Copilot review.

Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 2
  • Review effort level: Lite

Comment thread ayon_server/entities/project.py Outdated
Comment on lines +165 to +167
if await ensure_required_project_link_types(
project_name, payload["link_types"]
):
@martastain
martastain requested a review from kalisp September 17, 2026 14:19

Copilot AI left a comment

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.

🟡 Changes recommended

Conflict handling and cache invalidation leave required link types vulnerable to errors or stale data.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (3)

ayon_server/entities/project.py:108

  • When the canonical name is already occupied by a different link type, this branch only logs and continues, so the project still lacks the required default link type despite this function's guarantee. This collision needs to be surfaced or reconciled rather than silently returning an invalid configuration.
                logger.warning(
                    f"Cannot create required link type {candidate.name} in "
                    f"project {project_name}: name is taken by a conflicting "
                    "link type"
                )

ayon_server/entities/project.py:111

  • If the insert was skipped because an equal row already exists, appending candidate discards that row's stored data in the payload. A stale project-data cache can hit this path after a link-type update, causing customized color/style values to be replaced by defaults until the cache is rebuilt; append the fetched existing row instead.
        link_types.append(candidate.dict())

ayon_server/entities/project.py:190

  • The backfill is also skipped for a warm project-data cache because this call checks only the cached list, not the database. Since link-type PUT/DELETE handlers do not invalidate project-data, deleting a default leaves the row absent while _load returns the stale cached entry; invalidate this cache on mutations or re-read link types before accepting the cache.
                if await ensure_required_project_link_types(
                    project_name, payload["link_types"]
                ):
  • Files reviewed: 5/5 changed files
  • Comments generated: 2
  • Review effort level: Lite

Comment thread ayon_server/entities/project.py Outdated
Comment thread ayon_server/helpers/anatomy.py

Copilot AI left a comment

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.

🔵 Needs a closer look

Conflict handling can omit an existing required type, and transactional backfills may publish uncommitted data to Redis.

Review details

Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

ayon_server/entities/project.py:311

  • This backfill can run inside an existing Postgres.transaction() for for_update=True loads, but _load writes project-data before that transaction commits. If the caller rolls back without reaching ProjectEntity.save()'s cache cleanup, the cache will claim these defaults exist while the database does not; later cache hits then skip the backfill. Avoid publishing this payload until commit, or skip caching transactional loads.

ayon_server/entities/project.py:101

  • The conflict lookup returns only one row for an OR predicate. Because name and the identity triple are separate unique constraints, the database can contain one row matching candidate.name and another matching the candidate identity; fetchrow may return the former, so this branch omits the required identity even though it already exists. Query the constraints separately (or inspect all matches) and prefer the row matching the identity before declaring the default unavailable.
            conflicting = await Postgres.fetchrow(
                f"""
                SELECT name, link_type, input_type, output_type, data
                FROM project_{project_name}.link_types
                WHERE name = $1
  • Files reviewed: 6/6 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@BigRoy BigRoy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It seems to work now - whenever I try to remove the existing links, it seems to save with success, but upon refresh they are back. That does make it a bit confusing possibly, because it doesn't tell you in frontend that you can't seem to delete them?

Which makes me think, should we also show these entries differently in anatomy? And, could we?

These are the links it seems to enforce:
image

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

Labels

sponsored This is directly sponsored by a client or community member type: enhancement Improvement of existing functionality or minor addition

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reserved link types

5 participants