//flynt-disable field-type-breaking-change, renamed-field-breaking-change, removing-required-annotation-must-sdk-signature
syntax = "proto3";

package com.wixpress.roles.management.api;

import "google/api/annotations.proto";
import "wix/api/permissions.proto";
import "google/protobuf/wrappers.proto";
import "com/wixpress/invites/api/invites.proto";
import "users.proto";
import "people.proto";
import "account.proto";
import "policy.proto";
import "roles.proto";
import "wix/api/annotations.proto";
import "wix/api/entity.proto";
import "wix/api/validations.proto";
import "wix/common/paging.proto";
import "google/protobuf/struct.proto";
import "com/wixpress/authorization/abac/management/Policy.proto";
import "com/wixpress/authorization/abac/management/Subject.proto";
import "subject-assignments.proto";

service RolesManagementService {
    option (wix.api.service_entity).message = "com.wixpress.roles.management.api.User";

    rpc GetTeam (GetTeamRequest) returns (GetTeamResponse) {
        option (google.api.http).get = "/team";
        option (wix.api.exposure) = INTERNAL;
    };

    // Changes an existing team member's role.
    rpc ChangeRole (ChangeRoleRequest) returns (ChangeRoleResponse) {
        option (google.api.http).post = "/team/{id}/change";
        option (wix.api.required) = "ChangeRoleRequest.id";
        option (wix.api.required) = "ChangeRoleRequest.policy_ids";
        option (wix.api.permission).name = "team.change-member";
        option (wix.api.exposure) = INTERNAL;
    };

    // Removes a team member from the requesting account.
    // > **Important**: This call requires an account level API key and cannot be authenticated with the standard authorization header. API keys are currently available to selected beta users only.
    //flynt-disable http-mapping-breaking-change
    rpc RemoveMember (RemoveMemberRequest) returns (RemoveMemberResponse) {
        option (wix.api.maturity) = GA;
        option (wix.api.exposure) = PUBLIC;
        option (google.api.http).post = "/team/remove";
        option (wix.api.required) = "RemoveMemberRequest.user_id";
        option (wix.api.permission).name = "team.delete-member";
    };

    rpc Users (GetUsersRequest) returns (GetUsersResponse) {
        option (google.api.http).get = "/team/users";
        option (wix.api.exposure) = INTERNAL;
    }

    rpc GetScopes (GetScopesRequest) returns (GetScopesResponse) {
        option (google.api.http).get = "/scopes";
        option (wix.api.exposure) = INTERNAL;
    }

    // Get all the available scope areas with backend filtering.
    // Filters scope areas by host, experiments, and appDefIds on the backend.
    rpc GetScopesV2 (GetScopesV2Request) returns (GetScopesV2Response) {
        option (wix.api.permission).name = "ACCOUNT_ROLES.GET_SCOPES";
        option (google.api.http).get = "/v2/scopes";
        option (wix.api.exposure) = INTERNAL;

    }

    rpc GetPeople (GetPeopleRequest) returns (GetPeopleResponse) {
        option (google.api.http).get = "/people";
        option (wix.api.exposure) = INTERNAL;
    };

    rpc GetTeamV2 (GetTeamRequest) returns (GetTeamV2Response) {
        option (google.api.http).get = "/v2/team";
        option (wix.api.exposure) = INTERNAL;
    };

    rpc GetTeamInvites (GetTeamInvitesRequest) returns (GetTeamInvitesResponse) {
        option (google.api.http).get = "/v2/invites";
        option (wix.api.exposure) = INTERNAL;
    };

    rpc GetPolicies (GetPoliciesRequest) returns (GetPoliciesResponse) {
        option (google.api.http).get = "/v2/team/policies";
        option (wix.api.exposure) = INTERNAL;
    };

    /*
    Retrieves a list of all team members of the requesting account with the specified filtering, sorting, and paging.

    > **Important**: This call requires an account level API key and can't be authenticated with the standard authorization header. API keys are currently available to selected beta users only.

    ## Filters
  
    When using filters for dates, you must use
    [UTC time](https://en.wikipedia.org/wiki/Coordinated_Universal_Time).
    
    ## See also

    To learn about working with *Search* methods, see
    [API Query Language](https://dev.wix.com/docs/rest/articles/get-started/api-query-language) and 
    [Sorting and Paging](https://dev.wix.com/docs/rest/articles/get-started/sorting-and-paging). 
    
    //flynt-disable http-mapping-breaking-change
    */
    rpc SearchTeam (SearchTeamRequest) returns (SearchTeamResponse) {
        option (google.api.http).post = "/v3/team/search";
        option (wix.api.maturity) = GA;
        option (wix.api.exposure) = PUBLIC;
    }

    // Get all the available roles, both predefined roles and custom roles of the account taken from the target account in the call context.
    // Roles contain their visibility for the caller.
    rpc GetRoles (GetRolesRequest) returns (GetRolesResponse) {
        option (wix.api.permission).name = "ACCOUNT_ROLES.GET_ROLES";
        option (google.api.http).get = "/account/roles";
        option (wix.api.exposure) = INTERNAL;
    };

    // Retrieves all available roles in the requesting account, including predefined and custom roles.
    // > **Important**: This call requires an account level API key and cannot be authenticated with the standard authorization header. API keys are currently available to selected beta users only.
    //flynt-disable http-mapping-breaking-change
    rpc GetRolesInfo (GetRolesInfoRequest) returns (GetRolesInfoResponse) {
        option (wix.api.permission).name = "ACCOUNT_ROLES.GET_ROLES";
        option (google.api.http).get = "/roles";
        option (wix.api.maturity) = GA;
        option (wix.api.exposure) = PUBLIC;
    };

    // Create a custom role in the account taken from the target account in the call context.
    rpc CreateCustomRole(CreateCustomRoleRequest) returns (CreateCustomRoleResponse) {
        option (wix.api.maturity) = ALPHA;
        option (wix.api.exposure) = INTERNAL;
        option (google.api.http).post = "/account/roles/custom";
        option (wix.api.permission).name = "team.manage-team-member-roles";
        option (wix.api.required) = "CreateCustomRoleRequest.role";
    }

    // Updates the roles and conditions for an existing team member. Changing roles changes the team member's access to account assets. 
    // > **Important**: This call requires an account level API key and cannot be authenticated with the standard authorization header. API keys are currently available to selected beta users only.
    rpc ChangeRoleV2(ChangeRoleV2Request) returns (ChangeRoleV2Response) {
        option (wix.api.maturity) = ALPHA;
        option (wix.api.exposure) = PUBLIC;
        option (wix.api.permission).name = "team.manage-team-member-roles";
        option (google.api.http).patch = "/v2/team/roles";
        option (wix.api.required) = "ChangeRoleV2Request.user_id";
        option (wix.api.required) = "ChangeRoleV2Request.roles";
        option (wix.api.required) = "ChangeRoleV2Request.assignment_ids_to_replace";
    }

    // Updates the assignments of roles and conditions for an existing team member.  Changing assignments changes the team member’s access to account assets. 
    // > **Important**: This call requires an account level API key and cannot be authenticated with the standard authorization header. API keys are currently available to selected beta users only.
    //flynt-disable http-mapping-breaking-change
    rpc UpdateTeamMemberAssignments(UpdateTeamMemberAssignmentsRequest) returns (UpdateTeamMemberAssignmentsResponse) {
        option (wix.api.maturity) = GA;
        option (wix.api.exposure) = PUBLIC;
        option (wix.api.permission).name = "team.manage-team-member-roles";
        option (google.api.http).patch = "/v2/team/assignments";
        option (wix.api.required) = "UpdateTeamMemberAssignmentsRequest.user_id";
        option (wix.api.required) = "UpdateTeamMemberAssignmentsRequest.new_assignments";
        option (wix.api.required) = "UpdateTeamMemberAssignmentsRequest.assignment_ids_to_remove";
    }

    // Get subjects assignments
    rpc GetSubjectsAssignments (GetSubjectsAssignmentsRequest) returns (GetSubjectsAssignmentsResponse) {
        option (wix.api.permission).name = "ACCOUNT.SUBJECTS_ASSIGNMENTS_READ";
        option (google.api.http).get = "/account/subjects-assignments";
        option (wix.api.exposure) = INTERNAL;
    };

    // Get scopes for a specific role.
    rpc GetScopesByRole (GetScopesByRoleRequest) returns (GetScopesByRoleResponse) {
        option (wix.api.permission).name = "ACCOUNT_ROLES.GET_SCOPES";
        option (google.api.http).get = "/v2/scopes/role/{role_id}";
        option (wix.api.exposure) = INTERNAL;
        option (wix.api.required) = "GetScopesByRoleRequest.role_id";
    }

    // Get all the available roles with backend filtering.
    // Filters roles by host, experiments, and appDefIds on the backend.
    rpc GetRolesV2 (GetRolesV2Request) returns (GetRolesV2Response) {
        option (wix.api.permission).name = "ACCOUNT_ROLES.GET_ROLES";
        option (google.api.http).get = "/v2/account/roles";
        option (wix.api.exposure) = INTERNAL;

    };
}

message CreateCustomRoleRequest {
    // The custom role to create
    com.wixpress.authorization.abac.management.Policy role = 1;
}

message CreateCustomRoleResponse {
    // The newly created custom role
    com.wixpress.authorization.abac.management.Policy role_created = 1;
}

message SearchTeamRequest {
    /*
    Free text to match in searchable fields. 
    
    For example, search for specific values in 
    `name` or `email`.
    */
    google.protobuf.StringValue query = 1;
    // Field name and order to sort by.
    repeated Ordering order_by = 2;
    /*
    Filter object for narrowing search results.
    
    For example, to return only users with a specific role: `{"filter": {"roleId": "6600344420111308827"}}`

    See [API Query Language](https://dev.wix.com/docs/rest/articles/get-started/api-query-language)
    for more information.

    Supported values: `inviteType` and `roleId`.
    */ 
    google.protobuf.Struct filter = 3;
    /*
    Group data into categories (facets) and return the total count for each category.
    
    For example, use `facets` to aggregate search results by team member, invite status, or role.
    */
    repeated FacetType facets = 4;
    // Paging options.
    wix.common.Paging paging = 5;
}

message Ordering {
    // Field to sort by.
    OrderField field_name = 1;
    // Sort order.
    Direction direction = 2;

    enum Direction {
        UninitializedDirection = 0 [(.wix.api.enum_exposure) = INTERNAL]; // For internal use.
        ASC = 1; // Ascending.
        DESC = 2; // Descending.
    }

    enum OrderField {
        Undefined = 0 [(.wix.api.enum_exposure) = INTERNAL]; // For internal use.
        Name = 1; // Team member name.
        JoinedAt = 2; // Date team member joined the account.
    }
}

enum FacetType {
    Undefined = 0 [(.wix.api.enum_exposure) = INTERNAL];
    // Total team members with each role.
    Roles = 1;
    /*
    Total team members by [invite](https://dev.wix.com/docs/rest/account-level/user-management/accounts/account-invites/account-invite-object). 
    `status`.
    */
    InviteStatus = 2;
    // Total team members.
    Users = 3;
}

message SearchTeamResponse {
    // Retrieved facets as specified in the request.
    repeated Facet facets = 1;
    /*
    Retrieved team members and sent invites that match the search criteria specified in the request.

    Each file includes all standard `user` and `invite` information.
    */
    repeated TeamMemberV3 team_members = 2;
}

message TeamMemberV3 {
    oneof members {
        // Existing team member data.
        UserV3 user = 1;
        // Invited team member data. 
        InviteV3 invite = 2;
    }
}

message Facet {
    // Type of facet.
    FacetType facet_type = 1;
    // Values and the amount of each. Values with a count of `0` aren't returned.
    repeated FacetValue values = 2;
}

message FacetValue {
    // Supported values: `Roles`, `InviteStatus`, `Users`.
    string value = 1;
    // Number of existing items for the `value`.
    int32 count = 2;
}

message GetPeopleRequest {
    PeopleResource resource = 1;
    PeopleType people_type = 2;

    wix.common.Paging paging = 3;
    // The locale of the request. Defaults to en
    google.protobuf.StringValue locale = 4;
}

message GetPeopleResponse {
    People people = 1;
}

message GetTeamRequest {
    google.protobuf.Int32Value users_limit = 1 [deprecated = true];
    // The locale of the request. Defaults to en
    google.protobuf.StringValue locale = 2;

    wix.common.Paging paging = 3;
}

message GetTeamResponse {
    repeated User users = 1;
    repeated com.wixpress.invites.api.AccountInvite invites = 2;
    AccountInfo account_info = 3;
    repeated string permissions = 4;
    string user_id = 5;
    string target_account_id = 6;
    repeated Policy policies = 7;
    int64 total_users_in_account = 8;
    PredefinedRoles predefined_roles = 9;
}

message ChangeRoleRequest {
    // User ID.
    string id = 1;
    // Deprecated. Use `policyIds`.
    string role = 2[deprecated = true];
    //Role IDs to be assigned.
    repeated string policy_ids = 3;
}

message ChangeRoleResponse {}

message RemoveMemberRequest {
    // User ID of the team member to remove.
    string user_id = 1;
}

message RemoveMemberResponse {}

message GetUsersRequest {
    // The number of items to load
    google.protobuf.Int32Value limit = 1 [(wix.api.min) = 0];
    // number of items to skip in the current sort order
    google.protobuf.Int32Value offset = 2 [(wix.api.min) = 0];
}

message GetUsersResponse {
    repeated User users = 1;
}

message GetScopesRequest {
    // The locale of the request. Defaults to en
    google.protobuf.StringValue locale = 1;
}

message GetScopesResponse {
    repeated ScopeArea scope_areas = 1;
}

message ScopeArea {
    string title = 1;
    repeated string app_def_ids = 2;
    repeated PermissionScope scopes = 3;
    ScopeLevel restrict_from_level = 4;
}

message PermissionScope {
    enum Visibility {
        VISIBLE = 0; // The scope should be visible to the caller
        BLOCKED_BY_CAPABILITY = 1; // The scope shouldn't be visible for the caller, because the capability that blocks it is turned on for the caller
    }

    string id = 1;
    string title = 2;
    string description = 3;
    ScopeLevel level = 4;
    repeated string experiments = 5;
    repeated string dependant_scopes = 6;
    ScopeLevel restrict_from_level = 7;
    google.protobuf.BoolValue deprecated = 8;
    Visibility visibility = 9; // The visibility of the scope for the caller
    repeated string app_def_ids = 10 [(.wix.api.maxSize) = 20, (wix.api.format) = GUID];
}

enum ScopeLevel {
    None = 0;
    SITE = 1;
    ACCOUNT = 2;
}

message GetTeamInvitesRequest {
    // The locale of the request. Defaults to en
    google.protobuf.StringValue locale = 1;
}

message GetTeamInvitesResponse {
    repeated Invite invites = 1;
}

message GetTeamV2Response {
    repeated User users = 1;
    int64 total_users_in_account = 2;
}

message GetPoliciesRequest {
    // The locale of the request. Defaults to en
    google.protobuf.StringValue locale = 1;

    // Areas filter to include only roles from areas that pass this filter. When not provided, roles from all areas will be returned
    AreasFilter areas_filter = 2;

    // Role level filter to include only roles that are not restricted from the requested resource level (site/account). When set to ALL, all levels are returned
    RoleLevel role_level = 3;
}

message AreasFilter {
    // A list of role area ids, to filter only roles belonging to these areas
    repeated string area_ids = 1;
}

enum RoleLevel {
    ALL = 0;
    SITE_LEVEL = 1;
    ACCOUNT_LEVEL = 2;
}

message GetPoliciesResponse {
    PredefinedRoles policies = 1;
}

message GetRolesRequest {
    // The locale of the predefined roles names and descriptions. Defaults to English
    google.protobuf.StringValue locale = 1;
}

message GetRolesResponse {
    // The predefined roles (by areas)
    repeated PredefinedRolesArea predefined_roles_areas = 1;
    // The custom roles
    repeated CustomRole custom_roles = 2;
}

message RolesInfoFilter {
    // Role level to return. Default: ALL.
    RoleLevel role_level = 1;
    // Filter for editor-specific roles. Default: ALL.
    repeated EditorType editor_types = 2;
}

message GetRolesInfoRequest {
    // Language of predefined roles names and descriptions to return, in ISO 639 format. Default: `en`.
    google.protobuf.StringValue locale = 1;
    // Roles to return.
    RolesInfoFilter filter = 2;
}

message GetRolesInfoResponse {
    // Predefined roles.
    repeated RoleInfo predefined_roles = 1;
    // Custom roles.
    repeated RoleInfo custom_roles = 2;
}

message ChangeRoleV2Request {
    // ID of team member being affected.
    string user_id = 1 [(wix.api.format) = GUID];
    // New assignments, including roles, to apply to the team member in this account. To retrieve all available roles, call Get Roles Info.
    repeated AssignmentV3 roles = 2;
    // Existing assignment IDs to remove. To retrieve all existing assignment IDs for a team member, call Search Team. 
    repeated string assignment_ids_to_replace = 3;
}

message ChangeRoleV2Response {
    // New roles assigned to the given team member.
    repeated AssignmentV3 roles = 1;
}

message UpdateTeamMemberAssignmentsRequest {
    // ID of team member being affected.
    string user_id = 1 [(wix.api.format) = GUID];
    // New assignments to apply to the team member in this account.
    repeated AssignmentV3 new_assignments = 2  [(wix.api.maxSize) = 50];
    // Existing assignment IDs to remove. To retrieve all existing assignment IDs for a team member, call Search Team.
    repeated string assignment_ids_to_remove = 3 [(wix.api.format) = GUID, (wix.api.maxSize) = 50];
}

message UpdateTeamMemberAssignmentsResponse {
    // The new assignments, assigned to the given team member.
    repeated AssignmentV3 assignments = 1;
}

message GetSubjectsAssignmentsRequest {
    // The locale of the request. Defaults to en
    google.protobuf.StringValue locale = 1;
    // list of subjects
    repeated com.wixpress.authorization.abac.management.Subject subjects = 2;
}

message GetSubjectsAssignmentsResponse {
    // list of subjects with assignments
    repeated SubjectAssignments subjects_assignments = 1;
}

message GetRolesV2Request {
    // The locale of the predefined roles names and descriptions. Defaults to English
    google.protobuf.StringValue locale = 1 [(wix.api.format) = LANGUAGE];
    // Optional: The host platform to filter roles for. When not provided, returns roles for all platforms.
    // Valid values: "channels", "enterprise", "studio", "dev-center", "bm-vibe", "bm-headless", "bm-studio", "bm-classic"
    google.protobuf.StringValue host = 2 [(.wix.api.maxLength) = 50];
    // Optional: Additional app definition IDs to treat as installed apps for filtering purposes
    repeated string client_installed_apps = 3 [(wix.api.format) = GUID, (wix.api.maxSize) = 100];
}

message GetRolesV2Response {
    // The predefined roles (by areas) with simplified structure
    repeated PredefinedRolesAreaV2 predefined_roles_areas = 1;
    // The custom roles with simplified structure
    repeated CustomRoleV2 custom_roles = 2;
}

message PredefinedRolesAreaV2 {
    // Area ID
    string area_id = 1 [(.wix.api.maxLength) = 50];
    // Area title
    string title = 2 [(.wix.api.maxLength) = 50];
    // Roles in this area
    repeated RoleInfoV2 roles = 3 [(wix.api.maxSize) = 100];
    // Host platforms this area applies to
    repeated string hosts = 4 [(wix.api.maxSize) = 10, (.wix.api.maxLength) = 50];
}

message RoleInfoV2 {
    // Role ID
    string id = 1 [(.wix.api.maxLength) = 50];
    // Role title
    string title = 2 [(.wix.api.maxLength) = 500];
    // Role description
    string description = 3 [(.wix.api.maxLength) = 1000];
    // List of dependent role IDs
    repeated string dependent_roles = 4 [(wix.api.maxSize) = 50, (.wix.api.maxLength) = 50];
}

message CustomRoleV2 {
    // Role ID
    string id = 1 [(.wix.api.maxLength) = 50];
    // Role title
    string title = 2 [(.wix.api.maxLength) = 500];
    // Role description
    string description = 3 [(.wix.api.maxLength) = 1000];
    // List of permission scopes
    repeated string scopes = 4 [(wix.api.maxSize) = 100, (.wix.api.maxLength) = 100];
    // Whether this role is assigned to the current user
    bool assigned = 5;
}

message GetScopesV2Request {
    // The locale of the scope areas names and descriptions. Defaults to English
    google.protobuf.StringValue locale = 1 [(wix.api.format) = LANGUAGE];
    // Optional: The host platform for filtering scope areas. When not provided, returns scope areas for all platforms.
    // Valid values: "channels", "enterprise", "studio", "dev-center", "bm-vibe", "bm-headless", "bm-studio", "bm-classic"
    google.protobuf.StringValue host = 2 [(.wix.api.maxLength) = 50];
    // Optional: Additional app definition IDs to treat as installed apps for filtering purposes
    repeated string client_installed_apps = 3 [(wix.api.format) = GUID, (wix.api.maxSize) = 100];
}

message GetScopesByRoleRequest {
    // The role ID to filter scope areas by
    string role_id = 1 [(.wix.api.maxLength) = 50];
    // The locale of the scope. Defaults to English
    google.protobuf.StringValue locale = 2 [(wix.api.format) = LANGUAGE];
}

message GetScopesByRoleResponse {
    // The scopes included in this role
    repeated PermissionScopeV2 scopes = 2 [(wix.api.maxSize) = 100];
}

message GetScopesV2Response {
    // The filtered scope areas
    repeated ScopeAreaV2 scope_areas = 1 [(wix.api.maxSize) = 100];
}

message ScopeAreaV2 {
    // The title of the scope area
    string title = 1 [(.wix.api.maxLength) = 500];
    // The permission scopes within this area
    repeated PermissionScopeV2 scopes = 2 [(wix.api.maxSize) = 100];
}

message PermissionScopeV2 {
    // The unique identifier for the permission scope
    string id = 1 [(.wix.api.maxLength) = 500];
    // The display title of the permission scope
    string title = 2 [(.wix.api.maxLength) = 500];
    // A description of what this permission scope allows
    string description = 3 [(.wix.api.maxLength) = 1000];
    // List of scope IDs that this scope depends on
    repeated string dependant_scopes = 4 [(wix.api.maxSize) = 500, (.wix.api.maxLength) = 100];
    // The level at which this scope operates (site or account)
    ScopeLevel level = 5;
}
