schema {
  query: Query
  mutation: Mutation
}

enum ApiKeyPermissionEnum {
  READ_ONLY
  WRITE_ONLY
  READ_WRITE
}

enum UserStatusEnum {
  ACTIVE
  SUSPENDED
}

enum WorkspaceRoleEnum {
  USER
  MANAGER
  ADMIN
}

input LoginInput {
  username: String!
  password: String!
}

input UserCreate {
  username: String!
  password: String!
  displayName: String
  isSysadmin: Boolean!
  isAdmin: Boolean!
}

input WorkspaceCreate {
  name: String!
  description: String
}

input WorkspaceUserCreate {
  userId: Uuid!
  workspaceId: Uuid!
  role: WorkspaceRoleEnum!
}

interface GQLResult {
  success: Boolean!
  error: [ValidationError!]
}

"""
  Combined date and time (with time zone) in [RFC 3339][0] format.

  Represents a description of an exact instant on the time-line (such as the
  instant that a user account was created).

  [`DateTime` scalar][1] compliant.

  See also [`chrono::DateTime`][2] for details.

  [0]: https://datatracker.ietf.org/doc/html/rfc3339#section-5
  [1]: https://graphql-scalars.dev/docs/scalars/date-time
  [2]: https://docs.rs/chrono/latest/chrono/struct.DateTime.html
"""
scalar DateTime

scalar Uuid

type AuthPayload {
  token: String!
  user: User!
}

type AuthResult implements GQLResult {
  success: Boolean!
  payload: AuthPayload
  error: [ValidationError!]
}

type CreateApiKeyResponse {
  apiKey: String!
  id: Uuid!
}

type CreateApiKeyResult implements GQLResult {
  success: Boolean!
  apiKey: CreateApiKeyResponse
  error: [ValidationError!]
}

type DeletionResult implements GQLResult {
  success: Boolean!
  deleted: Boolean
  error: [ValidationError!]
}

type Mutation {
  user: UserMutation!
  workspace: WorkspaceMutation!
  auth(userData: LoginInput!): AuthResult!
}

type Query {
  ping: String!
  user(id: Uuid, username: String): [User!]!
  workspace(id: Uuid, name: String, archived: Boolean): [Workspace!]!
  me: User!
}

type ServiceApiKey {
  id: Uuid!
  workspaceId: Uuid!
  name: String!
  keyPreview: String!
  permissions: ApiKeyPermissionEnum!
  expiresAt: DateTime
}

type ServiceApiKeyResult implements GQLResult {
  success: Boolean!
  serviceApiKey: ServiceApiKey
  error: [ValidationError!]
}

type User {
  id: Uuid!
  username: String!
  displayName: String
  status: UserStatusEnum!
  isAdmin: Boolean!
  isSysadmin: Boolean!
  workspaces(workspaceId: Uuid, workspaceName: String): [Workspace!]!
  userApiKeys: [UserApiKey!]!
}

type UserApiKey {
  id: Uuid!
  userId: Uuid!
  name: String!
  keyPreview: String!
  expiresAt: DateTime
}

type UserMutation {
  create(userData: UserCreate!): UserResult!
  delete(id: Uuid!): DeletionResult!
  createUserApiKey(name: String!, durationDays: Int): CreateApiKeyResult!
  deleteUserApiKey(apiKeyId: Uuid!): DeletionResult!
}

type UserResult implements GQLResult {
  success: Boolean!
  user: User
  error: [ValidationError!]
}

type ValidationError {
  field: String!
  message: String!
}

type Workspace {
  id: Uuid!
  name: String!
  description: String
  archived: Boolean!
  createdAt: DateTime!
  updatedAt: DateTime!
  users(userId: Uuid, username: String): [WorkspaceUser!]!
  serviceApiKeys: [ServiceApiKey!]!
}

type WorkspaceMutation {
  create(adminUserId: Uuid, workspaceData: WorkspaceCreate!): WorkspaceResult!
  delete(workspaceId: Uuid!): DeletionResult!
  addUser(workspaceUser: WorkspaceUserCreate!): WorkspaceUserResult!
  removeUser(workspaceId: Uuid!, userId: Uuid!): DeletionResult!
  changeWorkspaceUserRole(workspaceId: Uuid!, userId: Uuid!, newRole: WorkspaceRoleEnum!): WorkspaceUserResult!
  createServiceApiKey(workspaceId: Uuid!, name: String!, permission: ApiKeyPermissionEnum!, durationDays: Int): CreateApiKeyResult!
  deleteServiceApiKey(workspaceId: Uuid!, apiKeyId: Uuid!): DeletionResult!
}

type WorkspaceResult implements GQLResult {
  success: Boolean!
  workspace: Workspace
  error: [ValidationError!]
}

type WorkspaceUser {
  role: WorkspaceRoleEnum!
  user: User!
  workspace: Workspace!
}

type WorkspaceUserResult implements GQLResult {
  success: Boolean!
  workspaceUser: WorkspaceUser
  error: [ValidationError!]
}
