feat(server): entitlement based model (#14996)

#### PR Dependency Tree


* **PR #14996** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Admin mutations to grant/revoke commercial entitlements.
  * New Doc comment-update permission.
  * Realtime user/workspace quota-state endpoints and live-update rooms.

* **Bug Fixes**
  * More accurate readable-doc filtering and permission evaluation.

* **Refactor**
* Workspace feature management moved to entitlement-based model;
permission and quota pipelines redesigned.
  * Admin workspace UI now edits flags only (feature toggles removed).

* **Tests**
* Extensive new and updated tests for permissions, entitlements, quota,
projection, and backfills.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/toeverything/AFFiNE/pull/14996?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
DarkSky
2026-05-19 22:48:05 +08:00
committed by GitHub
parent 103ad2a810
commit c53457691d
150 changed files with 13463 additions and 2458 deletions
+16 -14
View File
@@ -172,7 +172,6 @@ export interface AdminUpdateWorkspaceInput {
enableDocEmbedding?: InputMaybe<Scalars['Boolean']['input']>;
enableSharing?: InputMaybe<Scalars['Boolean']['input']>;
enableUrlPreview?: InputMaybe<Scalars['Boolean']['input']>;
features?: InputMaybe<Array<FeatureType>>;
id: Scalars['String']['input'];
name?: InputMaybe<Scalars['String']['input']>;
public?: InputMaybe<Scalars['Boolean']['input']>;
@@ -1021,6 +1020,7 @@ export interface DocPermissions {
Doc_Comments_Delete: Scalars['Boolean']['output'];
Doc_Comments_Read: Scalars['Boolean']['output'];
Doc_Comments_Resolve: Scalars['Boolean']['output'];
Doc_Comments_Update: Scalars['Boolean']['output'];
Doc_Copy: Scalars['Boolean']['output'];
Doc_Delete: Scalars['Boolean']['output'];
Doc_Duplicate: Scalars['Boolean']['output'];
@@ -1779,8 +1779,7 @@ export interface Mutation {
addContextFile: CopilotContextFile;
/** Update workspace embedding files */
addWorkspaceEmbeddingFiles: CopilotWorkspaceFile;
addWorkspaceFeature: Scalars['Boolean']['output'];
/** Update workspace flags and features for admin */
/** Update workspace flags for admin */
adminUpdateWorkspace: Maybe<AdminWorkspace>;
approveMember: Scalars['Boolean']['output'];
/** Ban an user */
@@ -1836,6 +1835,7 @@ export interface Mutation {
forkCopilotSession: Scalars['String']['output'];
generateLicenseKey: Scalars['String']['output'];
generateUserAccessToken: RevealedAccessToken;
grantCommercialEntitlement: Scalars['Boolean']['output'];
grantDocUserRoles: Scalars['Boolean']['output'];
grantMember: Scalars['Boolean']['output'];
/** import users */
@@ -1871,7 +1871,6 @@ export interface Mutation {
removeContextFile: Scalars['Boolean']['output'];
/** Remove workspace embedding files */
removeWorkspaceEmbeddingFiles: Scalars['Boolean']['output'];
removeWorkspaceFeature: Scalars['Boolean']['output'];
reorderWorkspaceByokConfigs: Array<WorkspaceByokKeyConfigType>;
/** Request to apply the subscription in advance */
requestApplySubscription: Array<SubscriptionType>;
@@ -1879,6 +1878,7 @@ export interface Mutation {
resolveComment: Scalars['Boolean']['output'];
resumeSubscription: SubscriptionType;
retryTranscriptTask: Maybe<TranscriptionResultType>;
revokeCommercialEntitlement: Scalars['Boolean']['output'];
revokeDocUserRoles: Scalars['Boolean']['output'];
revokeInviteLink: Scalars['Boolean']['output'];
revokeMember: Scalars['Boolean']['output'];
@@ -1966,11 +1966,6 @@ export interface MutationAddWorkspaceEmbeddingFilesArgs {
workspaceId: Scalars['String']['input'];
}
export interface MutationAddWorkspaceFeatureArgs {
feature: FeatureType;
workspaceId: Scalars['String']['input'];
}
export interface MutationAdminUpdateWorkspaceArgs {
input: AdminUpdateWorkspaceInput;
}
@@ -2127,6 +2122,13 @@ export interface MutationGenerateUserAccessTokenArgs {
input: GenerateAccessTokenInput;
}
export interface MutationGrantCommercialEntitlementArgs {
plan: Scalars['String']['input'];
quantity?: InputMaybe<Scalars['Int']['input']>;
targetId: Scalars['String']['input'];
targetType: Scalars['String']['input'];
}
export interface MutationGrantDocUserRolesArgs {
input: GrantDocUserRolesInput;
}
@@ -2219,11 +2221,6 @@ export interface MutationRemoveWorkspaceEmbeddingFilesArgs {
workspaceId: Scalars['String']['input'];
}
export interface MutationRemoveWorkspaceFeatureArgs {
feature: FeatureType;
workspaceId: Scalars['String']['input'];
}
export interface MutationReorderWorkspaceByokConfigsArgs {
input: ReorderWorkspaceByokConfigsInput;
}
@@ -2247,6 +2244,11 @@ export interface MutationRetryTranscriptTaskArgs {
workspaceId: Scalars['String']['input'];
}
export interface MutationRevokeCommercialEntitlementArgs {
targetId: Scalars['String']['input'];
targetType: Scalars['String']['input'];
}
export interface MutationRevokeDocUserRolesArgs {
input: RevokeDocUserRoleInput;
}