// This proto file was generated from workspace-service-api.yml.
// Care should be taken while both files exist to maintain backwards compatibility with the Conjure generated code.

syntax = "proto3";

package nominal.workspaces.v1;

import "buf/validate/validate.proto";
import "google/api/annotations.proto";
import "nominal/conjure/v1/compat.proto";
import "nominal/gen/v1/alias.proto";
import "nominal/gen/v1/error.proto";
import "nominal/types/types.proto";

option java_multiple_files = true;
option java_package = "io.nominal.workspaces.v1";

message PreferredRefNameConfiguration {
  option (nominal.conjure.v1.conjure_compat) = {union_message: true};

  repeated nominal.types.RefNameAndType v1 = 1;
}

message ProcedureSettings {
  option (nominal.conjure.v1.conjure_compat) = {union_message: true};

  oneof procedure_settings {
    option (buf.validate.oneof) = {required: true};

    ProcedureSettingsV1 v1 = 1;
  }
}

message ProcedureSettingsV1 {
  // A list of procedures that are elevated to the workspace-level.
  // They will be available for execution in a top-level context, rather
  // than just from the procedure details page.
  repeated string workspace_procedures = 1 [(nominal.gen.v1.alias) = {java_name: "io.nominal.api.rids.ProcedureRid"}];
}

// The request to remove a field from a workspace.
message RemoveType {}

// The request to update the display name of the workspace. The request will replace the existing display name
// with the display name specified if it's provided. Otherwise, the current display name will be removed from
// the workspace.
message UpdateOrRemoveWorkspaceDisplayName {
  option (nominal.conjure.v1.conjure_compat) = {union_message: true};

  // The request to update the display name of the workspace. The request will replace the existing display name
  // with the display name specified if it's provided. Otherwise, the current display name will be removed from
  // the workspace.
  oneof update_or_remove_workspace_display_name {
    option (buf.validate.oneof) = {required: true};

    string display_name = 1;
    RemoveType remove_type = 2;
  }
}

// The request to update the symbol of the workspace. The request will replace the existing symbol
// with the symbol specified if it's provided. Otherwise, the current symbol will be removed from
// the workspace.
message UpdateOrRemoveWorkspaceSymbol {
  option (nominal.conjure.v1.conjure_compat) = {union_message: true};

  // The request to update the symbol of the workspace. The request will replace the existing symbol
  // with the symbol specified if it's provided. Otherwise, the current symbol will be removed from
  // the workspace.
  oneof update_or_remove_workspace_symbol {
    option (buf.validate.oneof) = {required: true};

    WorkspaceSymbol symbol = 1;
    RemoveType remove_type = 2;
  }
}

message UpdateWorkspaceRequest {
  optional UpdateOrRemoveWorkspaceDisplayName display_name = 1;

  optional UpdateOrRemoveWorkspaceSymbol symbol = 2;

  optional WorkspaceSettings settings = 3;
}

message Workspace {
  // A unique identifier for the workspace within the organization. The workspace ID must be lower case alphanumeric characters, optionally separated by hyphens.
  string id = 1 [(nominal.gen.v1.alias) = {java_name: "io.nominal.api.ids.WorkspaceId"}];

  string rid = 2 [(nominal.gen.v1.alias) = {java_name: "io.nominal.api.rids.WorkspaceRid"}];

  string org = 3 [(nominal.gen.v1.alias) = {java_name: "io.nominal.authentication.api.OrgRid"}];

  optional string display_name = 4;

  optional WorkspaceSymbol symbol = 5;

  WorkspaceSettings settings = 6;
}

message WorkspaceSettings {
  optional PreferredRefNameConfiguration ref_names = 1;

  optional ProcedureSettings procedures = 2;
}

message WorkspaceSymbol {
  option (nominal.conjure.v1.conjure_compat) = {union_message: true};

  oneof workspace_symbol {
    option (buf.validate.oneof) = {required: true};

    // Workspace icon name (e.g. castle)
    string icon = 1;
    // Workspace emoji name (e.g. :castle:)
    string emoji = 2;
    // Workspace image url (e.g. https://example.com/image.png)
    string image = 3;
  }
}

message GetWorkspacesRequest {}

message GetWorkspacesResponse {
  repeated Workspace workspaces = 1;
}

message GetWorkspaceRequest {
  string workspace_rid = 1 [(nominal.gen.v1.alias) = {java_name: "io.nominal.api.rids.WorkspaceRid"}];
}

message GetWorkspaceResponse {
  Workspace workspace = 1;
}

message UpdateWorkspaceRequestWrapper {
  string rid = 1 [(nominal.gen.v1.alias) = {java_name: "io.nominal.api.rids.WorkspaceRid"}];

  UpdateWorkspaceRequest request = 2;
}

message UpdateWorkspaceResponse {
  Workspace workspace = 1;
}

message GetDefaultWorkspaceRequest {}

message GetDefaultWorkspaceResponse {
  optional Workspace workspace = 1;
}

// buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX
enum SecurityError {
  // Workspaces are hard boundaries in Nominal. Resources from different workspaces cannot be combined.
  SECURITY_ERROR_FORBIDDEN_CROSS_WORKSPACE_OPERATION = 0 [(nominal.gen.v1.error) = {
    code: "INVALID_ARGUMENT"
    message: "Workspaces are hard boundaries in Nominal. Resources from different workspaces cannot be combined."
  }];
  // The workspace with the specified rid was not found.
  SECURITY_ERROR_WORKSPACE_NOT_FOUND = 1 [(nominal.gen.v1.error) = {
    code: "NOT_FOUND"
    message: "The workspace with the specified rid was not found."
  }];
  // A workspace was not specified and could not be inferred.
  SECURITY_ERROR_WORKSPACE_NOT_SPECIFIED = 2 [(nominal.gen.v1.error) = {
    code: "INVALID_ARGUMENT"
    message: "A workspace was not specified and could not be inferred."
  }];
}

// This service provides information about workspaces. Workspaces provide access control boundaries. All resources in
// Nominal live within a workspace.
service WorkspaceService {
  // Gets all workspaces that the requesting user belongs to.
  rpc GetWorkspaces(GetWorkspacesRequest) returns (GetWorkspacesResponse) {
    option (google.api.http) = {
      get: "/workspaces/v1/workspaces"
      response_body: "workspaces"
    };
  }
  // Gets the workspace with the specified WorkspaceRid.
  rpc GetWorkspace(GetWorkspaceRequest) returns (GetWorkspaceResponse) {
    option (google.api.http) = {
      get: "/workspaces/v1/workspaces/{workspace_rid}"
      response_body: "workspace"
    };
  }
  // buf:lint:ignore RPC_REQUEST_STANDARD_NAME
  // Updates the settings of the workspace with the specified WorkspaceRid.
  rpc UpdateWorkspace(UpdateWorkspaceRequestWrapper) returns (UpdateWorkspaceResponse) {
    option (google.api.http) = {
      response_body: "workspace"
      body: "request"
      put: "/workspaces/v1/workspaces/{rid}"
    };
  }
  // Gets the default workspace for the requesting user. If the user belongs to a single workspace,
  // that workspace is returned. Otherwise, if the user's organization has a default workspace and
  // the user belongs to it, that will be returned.
  rpc GetDefaultWorkspace(GetDefaultWorkspaceRequest) returns (GetDefaultWorkspaceResponse) {
    option (google.api.http) = {
      get: "/workspaces/v1/default-workspace"
      response_body: "workspace"
    };
  }
}
