Skip to content

Conversation

@kartikaysaxena
Copy link
Contributor

@kartikaysaxena kartikaysaxena commented Jun 21, 2025

Related: #2396

This PR adds support for relation-level deprecation in schemas.

  • Relations can now be annotated with a @deprecated(...) directive to indicate they are deprecated.
  • When a relationship is written to a deprecated relation:
    • A warning or error is generated, depending on the specified deprecation level.
    • In the current implementation, writes fail when an error deprecation is configured.
  • Deprecation is associated with the immediately following relation in the definition.
  • A flag is to be passed to enable this feature, namely --enable-experimental-relationship-deprecation along with use directive.

Example:

use deprecation

definition user {}

definition resource {
  @deprecated(warn)
  relation viewer: user

  @deprecated(error)
  relation admin: user
}

Note

Each relation has an enum DeprecationType assigned to them, if unspecified it defaults to DEPRECATED_TYPE_UNSPECIFIED

@kartikaysaxena kartikaysaxena requested a review from a team as a code owner June 21, 2025 12:48
@github-actions github-actions bot added area/schema Affects the Schema Language area/api v1 Affects the v1 API area/tooling Affects the dev or user toolchain (e.g. tests, ci, build tools) labels Jun 21, 2025
@codecov
Copy link

codecov bot commented Jun 21, 2025

Codecov Report

Attention: Patch coverage is 71.70418% with 88 lines in your changes missing coverage. Please review.

Project coverage is 77.39%. Comparing base (f05b700) to head (f436b79).

Files with missing lines Patch % Lines
pkg/schemadsl/parser/parser.go 58.98% 23 Missing and 9 partials ⚠️
pkg/schemadsl/compiler/translator.go 72.92% 18 Missing and 8 partials ⚠️
internal/services/v1/relationships.go 59.65% 20 Missing and 3 partials ⚠️
internal/services/shared/errors.go 75.00% 3 Missing ⚠️
pkg/namespace/builder.go 83.34% 2 Missing and 1 partial ⚠️
pkg/cmd/testserver/testserver.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2465      +/-   ##
==========================================
- Coverage   77.45%   77.39%   -0.06%     
==========================================
  Files         417      417              
  Lines       51091    51394     +303     
==========================================
+ Hits        39569    39769     +200     
- Misses       9032     9110      +78     
- Partials     2490     2515      +25     

☔ 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.

Copy link
Contributor

@tstirrat15 tstirrat15 left a comment

Choose a reason for hiding this comment

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

Left a couple of comments.

I'm also wondering about the behavior of these annotations more generally - what happens if you put this annotation on a permission instead of a relation? Should it have an effect?

Copy link
Contributor

Choose a reason for hiding this comment

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

A general note on the approach: to the degree that we can, we want to avoid breaking folks' existing schemas. See what we did with expiration for an example of how we've worked around it with use directives - if we add this feature, it'll be with one of those use directives.

Copy link
Contributor

Choose a reason for hiding this comment

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

We also need the composableschemadsl package to be updated accordingly.

Comment on lines 159 to 160
if l.acceptString("deprecated") {
l.emit(TokenTypeKeyword)
Copy link
Contributor

Choose a reason for hiding this comment

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

This isn't something that should live in the lexer - it should live in the parser.

Or at least my sense is that an @ should be a marker, and then the token after it should be a keyword, rather than the entire thing being marked as a keyword.

It's also going to relate to what I said above about the use directive.

Copy link
Contributor

Choose a reason for hiding this comment

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

it might be worth looking at #202, which implemented generic decorators (but we didn't have a use case so never merged it)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

reworked the approach a little bit including the use directive just like how it was done for expiration feature, adding more comments for better review.

@github-actions github-actions bot added the area/cli Affects the command line label Jun 27, 2025
@kartikaysaxena kartikaysaxena force-pushed the support-relation-deprecation branch from c9af820 to 4ad2bdc Compare June 27, 2025 19:25
@josephschorr
Copy link
Member

I wonder if we want to allow the deprecated annotation on each subject type vs the relation as a whole; I could see benefits to either. @ecordell thoughts?

@kartikaysaxena
Copy link
Contributor Author

we may also support something like

use deprecation

definition user {}

definition resource {
  relation viewer: user
  relation admin: user
}

@deprecated(warn, user, "<comments about deprecation>")
@deprecated(error, admin, "<comments about deprecation>")

which can include both subjects and relations, this way deprecation can be more flexible and granular also including the comments about the deprecation.

Any thoughts @josephschorr @ecordell @tstirrat15 ?

@josephschorr
Copy link
Member

This is also missing changes to the schema generator package and associated tests

@kartikaysaxena kartikaysaxena force-pushed the support-relation-deprecation branch from bb9ec3a to 5c08a5d Compare July 8, 2025 00:17
@kartikaysaxena
Copy link
Contributor Author

This is also missing changes to the schema generator package and associated tests

Updated the generator to accommodate deprecation and added some tests. I know you all are a bit busy, so feel free to take a look whenever you get the chance, thanks!

@kartikaysaxena kartikaysaxena force-pushed the support-relation-deprecation branch 2 times, most recently from 01cf430 to 4599651 Compare July 10, 2025 14:46
@github-actions github-actions bot added area/datastore Affects the storage system area/dependencies Affects dependencies area/dispatch Affects dispatching of requests and removed area/datastore Affects the storage system area/dependencies Affects dependencies area/dispatch Affects dispatching of requests labels Jul 10, 2025
@kartikaysaxena kartikaysaxena force-pushed the support-relation-deprecation branch from 0f6aa4c to 063ecb4 Compare July 10, 2025 18:33
@github-actions github-actions bot added area/datastore Affects the storage system area/dependencies Affects dependencies area/dispatch Affects dispatching of requests labels Jul 10, 2025
@vroldanbet
Copy link
Contributor

I like it; let's add it and have it returned

Is the @ necessary at all?

Signed-off-by: Kartikay <[email protected]>
 Please enter the commit message for your changes. Lines starting
Signed-off-by: Kartikay <[email protected]>
@kartikaysaxena kartikaysaxena force-pushed the support-relation-deprecation branch from 234989c to 5c2c076 Compare July 20, 2025 15:52
@github-actions github-actions bot added area/datastore Affects the storage system area/dependencies Affects dependencies area/dispatch Affects dispatching of requests labels Jul 20, 2025
@kartikaysaxena kartikaysaxena changed the title feat: support relation deprecation feat: support relation and object deprecation Jul 20, 2025
@github-actions github-actions bot removed area/datastore Affects the storage system area/dependencies Affects dependencies area/dispatch Affects dispatching of requests labels Jul 20, 2025
Signed-off-by: Kartikay <[email protected]>
@kartikaysaxena kartikaysaxena force-pushed the support-relation-deprecation branch from 0455584 to bb9f5b7 Compare July 20, 2025 16:28
@github-actions github-actions bot added area/datastore Affects the storage system area/dependencies Affects dependencies area/dispatch Affects dispatching of requests labels Jul 20, 2025
@github-actions github-actions bot removed area/datastore Affects the storage system area/dependencies Affects dependencies area/dispatch Affects dispatching of requests labels Jul 20, 2025
@kartikaysaxena kartikaysaxena force-pushed the support-relation-deprecation branch from ead2bda to 0bd6021 Compare July 20, 2025 16:41
Signed-off-by: Kartikay <[email protected]>
@kartikaysaxena kartikaysaxena force-pushed the support-relation-deprecation branch from 0bd6021 to f436b79 Compare July 20, 2025 16:49
@kartikaysaxena
Copy link
Contributor Author

kartikaysaxena commented Jul 20, 2025

requesting for initial review, the deprecation support now looks like

use deprecation

definition user {}
definition superuser {}
definition anotheruser {}

definition platform {
	relation admin: user
	relation editor: superuser

	@deprecated(warn, “rel viewer is deprecated”)
	relation viewer: anotheruser
}

@deprecated(error, user, “user object is deprecated”)
@deprecated(warn, platform#editor, “this to deprecate a relation under a namespace”)

This adds support for deprecating relation inside a definition namespace for marking the immediate next relation as deprecated, for outside a namespace a relation can be marked deprecated as @deprecated(warn, platform#editor, “this to deprecate a relation under a namespace”) and an object by simply changing the relation with the object, example platform#editor -> user will mark user as deprecated, it works if the object is either defined as a subject or a resource in a WriteRelationship call.

(also would migrate this pr to a new branch if this branch looks messy after too many rebases)

@josephschorr
Copy link
Member

requesting for initial review, the deprecation support now looks like

use deprecation

definition user {}
definition superuser {}
definition anotheruser {}

definition platform {
	relation admin: user
	relation editor: superuser

	@deprecated(warn, “rel viewer is deprecated”)
	relation viewer: anotheruser
}

@deprecated(error, user, “user object is deprecated”)
@deprecated(warn, platform#editor, “this to deprecate a relation under a namespace”)

This adds support for deprecating relation inside a definition namespace for marking the immediate next relation as deprecated, for outside a namespace a relation can be marked deprecated as @deprecated(warn, platform#editor, “this to deprecate a relation under a namespace”) and an object by simply changing the relation with the object, example platform#editor -> user will mark user as deprecated, it works if the object is either defined as a subject or a resource in a WriteRelationship call.

(also would migrate this pr to a new branch if this branch looks messy after too many rebases)

Sorry @kartikaysaxena, this is my bad at not being explicit: I liked the idea of being able to mark definitions as deprecated, but they should be done so by decorating the definition, not as a distinct line item:

@deprecated(error, “user object is deprecated”)
definition platform { ... }

@kartikaysaxena
Copy link
Contributor Author

kartikaysaxena commented Jul 21, 2025

requesting for initial review, the deprecation support now looks like

use deprecation

definition user {}
definition superuser {}
definition anotheruser {}

definition platform {
	relation admin: user
	relation editor: superuser

	@deprecated(warn, “rel viewer is deprecated”)
	relation viewer: anotheruser
}

@deprecated(error, user, “user object is deprecated”)
@deprecated(warn, platform#editor, “this to deprecate a relation under a namespace”)

This adds support for deprecating relation inside a definition namespace for marking the immediate next relation as deprecated, for outside a namespace a relation can be marked deprecated as @deprecated(warn, platform#editor, “this to deprecate a relation under a namespace”) and an object by simply changing the relation with the object, example platform#editor -> user will mark user as deprecated, it works if the object is either defined as a subject or a resource in a WriteRelationship call.
(also would migrate this pr to a new branch if this branch looks messy after too many rebases)

Sorry @kartikaysaxena, this is my bad at not being explicit: I liked the idea of being able to mark definitions as deprecated, but they should be done so by decorating the definition, not as a distinct line item:

@deprecated(error, “user object is deprecated”)
definition platform { ... }

understood, this is implemented and superseded by #2504, mind taking a look?

@github-actions github-actions bot locked and limited conversation to collaborators Jul 21, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area/api v1 Affects the v1 API area/cli Affects the command line area/schema Affects the Schema Language area/tooling Affects the dev or user toolchain (e.g. tests, ci, build tools)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants