/**
 * Generated by orval v8.5.3 🍺
 * Do not edit manually.
 * Api
 * Tx OS API specification
 * OpenAPI spec version: 0.1.0
 */
export interface HealthStatus {
  status: string;
}

export interface ErrorResponse {
  error: string;
}

export interface SuccessResponse {
  success: boolean;
}

export interface RegisterBody {
  username: string;
  email: string;
  password: string;
  /** @nullable */
  displayNameAr?: string | null;
  /** @nullable */
  displayNameEn?: string | null;
  preferredLanguage?: string;
}

export interface CreateUserBody {
  username: string;
  email: string;
  password: string;
  /** @nullable */
  displayNameAr?: string | null;
  /** @nullable */
  displayNameEn?: string | null;
  preferredLanguage?: string;
  /** Initial group memberships in addition to the auto-assigned Everyone group. */
  groupIds?: number[];
}

export interface LoginBody {
  username: string;
  password: string;
}

export interface ForgotPasswordBody {
  /** Username or email */
  identifier: string;
}

export interface ForgotPasswordResponse {
  success: boolean;
}

export interface ResetPasswordBody {
  token: string;
  /** @minLength 6 */
  newPassword: string;
}

export interface VerifyResetTokenBody {
  token: string;
}

export interface AdminResetLinkResponse {
  resetUrl: string;
  expiresAt: string;
}

export interface VerifyResetTokenResponse {
  valid: boolean;
}

export interface UpdateLanguageBody {
  language: string;
}

/**
 * Per-user home-screen clock style preference
 */
export type ClockStyle = (typeof ClockStyle)[keyof typeof ClockStyle];

export const ClockStyle = {
  full: "full",
  digital: "digital",
  "digital-no-seconds": "digital-no-seconds",
  analog: "analog",
  minimal: "minimal",
} as const;

export interface UpdateClockStyleBody {
  /** Clock style; pass null to clear and use the default */
  clockStyle: ClockStyle | null;
}

export interface UpdateClockHour12Body {
  /**
   * Whether to use 12-hour (AM/PM) clock format; null clears and uses the default (24-hour)
   * @nullable
   */
  clockHour12: boolean | null;
}

export interface GroupSummary {
  id: number;
  name: string;
  /** @nullable */
  descriptionAr?: string | null;
  /** @nullable */
  descriptionEn?: string | null;
}

export interface AuthUser {
  id: number;
  username: string;
  email: string;
  /** @nullable */
  displayNameAr?: string | null;
  /** @nullable */
  displayNameEn?: string | null;
  preferredLanguage: string;
  clockStyle?: ClockStyle | null;
  /** @nullable */
  clockHour12?: boolean | null;
  /** @nullable */
  avatarUrl?: string | null;
  isActive: boolean;
  roles: string[];
  groups: GroupSummary[];
  createdAt: string;
}

export interface UserProfile {
  id: number;
  username: string;
  email: string;
  /** @nullable */
  displayNameAr?: string | null;
  /** @nullable */
  displayNameEn?: string | null;
  preferredLanguage: string;
  clockStyle?: ClockStyle | null;
  /** @nullable */
  clockHour12?: boolean | null;
  /** @nullable */
  avatarUrl?: string | null;
  isActive: boolean;
  roles: string[];
  groups: GroupSummary[];
  createdAt: string;
  /** Dependent record counts. Populated only by the admin list endpoint
(GET /users) so the delete dialog can warn before the first click.
Omitted from single-user responses (GET /users/:id, PATCH, etc).
 */
  noteCount?: number;
  /** Number of service orders owned by this user. Populated only by the
admin list endpoint (GET /users).
 */
  orderCount?: number;
  /** Number of conversations created by this user. Populated only by the
admin list endpoint (GET /users).
 */
  conversationCount?: number;
  /** Number of messages authored by this user. Populated only by the
admin list endpoint (GET /users).
 */
  messageCount?: number;
}

export interface UpdateUserBody {
  /** @nullable */
  displayNameAr?: string | null;
  /** @nullable */
  displayNameEn?: string | null;
  isActive?: boolean;
  preferredLanguage?: string;
  /** If provided, replaces the user's group memberships */
  groupIds?: number[];
}

export interface AddUserRoleBody {
  /** @minLength 1 */
  roleName: string;
}

export interface Role {
  id: number;
  name: string;
  /** @nullable */
  descriptionAr?: string | null;
  /** @nullable */
  descriptionEn?: string | null;
  isSystem: boolean;
  createdAt: string;
}

export interface CreateRoleBody {
  /** @minLength 1 */
  name: string;
  /** @nullable */
  descriptionAr?: string | null;
  /** @nullable */
  descriptionEn?: string | null;
}

export interface UpdateRoleBody {
  /** @minLength 1 */
  name?: string;
  /** @nullable */
  descriptionAr?: string | null;
  /** @nullable */
  descriptionEn?: string | null;
}

export interface RoleUsage {
  userCount: number;
  groupCount: number;
}

export interface RoleDeletionConflict {
  error: string;
  userCount: number;
  groupCount: number;
}

export interface Permission {
  id: number;
  name: string;
  /** @nullable */
  descriptionAr?: string | null;
  /** @nullable */
  descriptionEn?: string | null;
}

export interface AddAppPermissionBody {
  /** ID of the permission to require for this app. */
  permissionId: number;
}

export interface AppPermissionLink {
  appId: number;
  permissionId: number;
}

export interface AppPermissionsImpactBody {
  /** Candidate set of permission IDs that would gate this app. Pass an empty array to model "remove every requirement" (i.e. make the app unrestricted). */
  permissionIds: number[];
}

export interface AppPermissionImpactGroup {
  id: number;
  name: string;
}

export interface AppPermissionsImpact {
  /** Distinct non-admin users who currently see the app and would lose visibility under the candidate permission set. Already accounts for users who keep access via `group_apps` group-grants. */
  affectedUserCount: number;
  /** Distinct non-admin users who currently see the app under the existing permission set. Useful for showing the warning as a fraction (e.g. "12 of 80 will lose access"). */
  currentlyVisibleUserCount: number;
  /** Groups that currently grant this app via `group_apps`. Members of any of these groups keep access regardless of permission changes. */
  groups: AppPermissionImpactGroup[];
  /** True when the candidate set is identical to the current permission set so no change would actually be saved. */
  noChange: boolean;
}

export interface ReplaceRolePermissionsBody {
  /** Full set of permission IDs the role should grant. Existing assignments not present here are removed. */
  permissionIds: number[];
}

export interface RolePermissionsImpactBody {
  /** Candidate set of permission IDs to evaluate against the role's current assignments. */
  permissionIds: number[];
}

export interface RolePermissionImpactGroup {
  id: number;
  name: string;
}

export interface RolePermissionImpactItem {
  permissionId: number;
  permissionName: string;
  /** Distinct users who currently have this permission via this role and would lose it (no other role they hold grants the permission). */
  userCount: number;
  /** Number of groups that currently grant this role. */
  groupCount: number;
  /** Groups that currently grant this role and therefore propagate the removal to their members. */
  groups: RolePermissionImpactGroup[];
}

export interface RolePermissionsImpact {
  /** One entry per permission that is currently assigned to the role but not in the candidate set. */
  removed: RolePermissionImpactItem[];
  /** Distinct users that would lose at least one permission across all removals. */
  totalAffectedUsers: number;
}

export interface Group {
  id: number;
  name: string;
  /** @nullable */
  descriptionAr?: string | null;
  /** @nullable */
  descriptionEn?: string | null;
  isSystem: boolean;
  memberCount: number;
  appCount: number;
  roleCount: number;
  createdAt: string;
}

export interface GroupDeletionConflict {
  error: string;
  memberCount: number;
  appCount: number;
  roleCount: number;
}

export interface UserDeletionConflict {
  error: string;
  noteCount: number;
  orderCount: number;
  conversationCount: number;
  messageCount: number;
}

export interface AppDeletionConflict {
  error: string;
  groupCount: number;
  restrictionCount: number;
  openCount: number;
}

export interface ServiceDeletionConflict {
  error: string;
  orderCount: number;
}

export interface GroupDetail {
  id: number;
  name: string;
  /** @nullable */
  descriptionAr?: string | null;
  /** @nullable */
  descriptionEn?: string | null;
  isSystem: boolean;
  appIds: number[];
  roleIds: number[];
  userIds: number[];
  createdAt: string;
}

export interface CreateGroupBody {
  /** @minLength 1 */
  name: string;
  /** @nullable */
  descriptionAr?: string | null;
  /** @nullable */
  descriptionEn?: string | null;
  appIds?: number[];
  roleIds?: number[];
  userIds?: number[];
}

export interface UpdateGroupBody {
  /** @minLength 1 */
  name?: string;
  /** @nullable */
  descriptionAr?: string | null;
  /** @nullable */
  descriptionEn?: string | null;
  appIds?: number[];
  roleIds?: number[];
  userIds?: number[];
}

export interface App {
  id: number;
  slug: string;
  nameAr: string;
  nameEn: string;
  /** @nullable */
  descriptionAr?: string | null;
  /** @nullable */
  descriptionEn?: string | null;
  iconName: string;
  route: string;
  color: string;
  isActive: boolean;
  isSystem: boolean;
  sortOrder: number;
  createdAt: string;
  updatedAt: string;
  /** Number of groups granting access to this app. Populated only by the
admin list endpoint (GET /admin/apps) so the delete dialog can warn
before the first click. Omitted from non-admin and single-app
responses.
 */
  groupCount?: number;
  /** Number of legacy permission restrictions for this app. Populated
only by the admin list endpoint (GET /admin/apps).
 */
  restrictionCount?: number;
  /** Number of recorded app-open events for this app. Populated only by
the admin list endpoint (GET /admin/apps).
 */
  openCount?: number;
}

export interface CreateAppBody {
  slug: string;
  nameAr: string;
  nameEn: string;
  /** @nullable */
  descriptionAr?: string | null;
  /** @nullable */
  descriptionEn?: string | null;
  iconName: string;
  route: string;
  color: string;
  isActive?: boolean;
  isSystem?: boolean;
  sortOrder?: number;
  /** Optional set of permission IDs to gate the new app on. Inserted with onConflictDoNothing so duplicates are tolerated. */
  permissionIds?: number[];
}

export interface UpdateAppBody {
  nameAr?: string;
  nameEn?: string;
  /** @nullable */
  descriptionAr?: string | null;
  /** @nullable */
  descriptionEn?: string | null;
  iconName?: string;
  route?: string;
  color?: string;
  isActive?: boolean;
  sortOrder?: number;
}

export interface Service {
  id: number;
  /** @nullable */
  categoryId?: number | null;
  nameAr: string;
  nameEn: string;
  /** @nullable */
  descriptionAr?: string | null;
  /** @nullable */
  descriptionEn?: string | null;
  /** @nullable */
  imageUrl?: string | null;
  /** @nullable */
  price?: string | null;
  isAvailable: boolean;
  sortOrder: number;
  createdAt: string;
  updatedAt: string;
  /** Number of service_orders rows referencing this service. Populated
only by the list endpoint (GET /services) so the admin delete
dialog can warn before the first click. Omitted from single-service
responses.
 */
  orderCount?: number;
}

export interface CreateServiceBody {
  /** @nullable */
  categoryId?: number | null;
  nameAr: string;
  nameEn: string;
  /** @nullable */
  descriptionAr?: string | null;
  /** @nullable */
  descriptionEn?: string | null;
  /** @nullable */
  imageUrl?: string | null;
  /** @nullable */
  price?: string | null;
  isAvailable?: boolean;
  sortOrder?: number;
}

export interface UpdateServiceBody {
  /** @nullable */
  categoryId?: number | null;
  nameAr?: string;
  nameEn?: string;
  /** @nullable */
  descriptionAr?: string | null;
  /** @nullable */
  descriptionEn?: string | null;
  /** @nullable */
  imageUrl?: string | null;
  /** @nullable */
  price?: string | null;
  isAvailable?: boolean;
  sortOrder?: number;
}

export interface ServiceCategory {
  id: number;
  nameAr: string;
  nameEn: string;
  sortOrder: number;
  createdAt: string;
}

export interface ServiceOrderUser {
  id: number;
  username: string;
  /** @nullable */
  displayNameAr?: string | null;
  /** @nullable */
  displayNameEn?: string | null;
  /** @nullable */
  avatarUrl?: string | null;
}

export interface ServiceOrderService {
  id: number;
  nameAr: string;
  nameEn: string;
  /** @nullable */
  imageUrl?: string | null;
}

export type ServiceOrderStatus =
  (typeof ServiceOrderStatus)[keyof typeof ServiceOrderStatus];

export const ServiceOrderStatus = {
  pending: "pending",
  received: "received",
  preparing: "preparing",
  completed: "completed",
  cancelled: "cancelled",
} as const;

export interface ServiceOrder {
  id: number;
  serviceId: number;
  userId: number;
  /** @nullable */
  assignedTo?: number | null;
  /** @nullable */
  notes?: string | null;
  status: ServiceOrderStatus;
  createdAt: string;
  updatedAt: string;
  service: ServiceOrderService;
  requester?: ServiceOrderUser | null;
  assignee?: ServiceOrderUser | null;
}

export interface CreateServiceOrderBody {
  serviceId: number;
  /**
   * @maxLength 500
   * @nullable
   */
  notes?: string | null;
}

export type UpdateServiceOrderStatusBodyStatus =
  (typeof UpdateServiceOrderStatusBodyStatus)[keyof typeof UpdateServiceOrderStatusBodyStatus];

export const UpdateServiceOrderStatusBodyStatus = {
  pending: "pending",
  received: "received",
  preparing: "preparing",
  completed: "completed",
  cancelled: "cancelled",
} as const;

export interface UpdateServiceOrderStatusBody {
  status: UpdateServiceOrderStatusBodyStatus;
}

export interface ParticipantInfo {
  id: number;
  username: string;
  /** @nullable */
  displayNameAr?: string | null;
  /** @nullable */
  displayNameEn?: string | null;
  /** @nullable */
  avatarUrl?: string | null;
  isAdmin: boolean;
}

export type MessageWithSenderKind =
  (typeof MessageWithSenderKind)[keyof typeof MessageWithSenderKind];

export const MessageWithSenderKind = {
  user: "user",
  group_renamed: "group_renamed",
  members_added: "members_added",
  member_removed: "member_removed",
  member_left: "member_left",
  admin_promoted: "admin_promoted",
} as const;

export type MessageWithSenderMeta = { [key: string]: unknown } | null;

export interface MessageWithSender {
  id: number;
  conversationId: number;
  senderId: number;
  content: string;
  kind: MessageWithSenderKind;
  meta?: MessageWithSenderMeta;
  sender: ParticipantInfo;
  createdAt: string;
  updatedAt: string;
}

export interface ConversationWithDetails {
  id: number;
  /** @nullable */
  nameAr?: string | null;
  /** @nullable */
  nameEn?: string | null;
  /** @nullable */
  avatarUrl?: string | null;
  isGroup: boolean;
  createdBy: number;
  participants: ParticipantInfo[];
  lastMessage?: MessageWithSender | null;
  unreadCount: number;
  isMuted: boolean;
  isArchived: boolean;
  createdAt: string;
  updatedAt: string;
}

export interface CreateConversationBody {
  participantIds: number[];
  /** @nullable */
  nameAr?: string | null;
  /** @nullable */
  nameEn?: string | null;
  /** @nullable */
  avatarUrl?: string | null;
  isGroup?: boolean;
}

export interface UpdateConversationBody {
  /** @nullable */
  avatarUrl?: string | null;
  /** @nullable */
  nameAr?: string | null;
  /** @nullable */
  nameEn?: string | null;
}

export interface UpdateConversationStateBody {
  isMuted?: boolean;
  isArchived?: boolean;
}

export interface AddParticipantsBody {
  userIds: number[];
}

export interface SendMessageBody {
  content: string;
}

export interface Notification {
  id: number;
  userId: number;
  titleAr: string;
  titleEn: string;
  /** @nullable */
  bodyAr?: string | null;
  /** @nullable */
  bodyEn?: string | null;
  type: string;
  isRead: boolean;
  /** @nullable */
  relatedId?: number | null;
  /** @nullable */
  relatedType?: string | null;
  createdAt: string;
}

export interface AppSettings {
  siteNameAr: string;
  siteNameEn: string;
  registrationOpen: boolean;
  footerTextAr: string;
  footerTextEn: string;
  updatedAt?: string;
}

export interface UpdateMyAppOrderBody {
  /** App IDs in the desired display order */
  order: number[];
}

export interface UpdateAppSettingsBody {
  /**
   * @minLength 1
   * @maxLength 200
   */
  siteNameAr?: string;
  /**
   * @minLength 1
   * @maxLength 200
   */
  siteNameEn?: string;
  registrationOpen?: boolean;
  /**
   * @minLength 1
   * @maxLength 300
   */
  footerTextAr?: string;
  /**
   * @minLength 1
   * @maxLength 300
   */
  footerTextEn?: string;
}

export interface RequestUploadUrlBody {
  /** @minLength 1 */
  name: string;
  /** @minimum 1 */
  size: number;
  /** @minLength 1 */
  contentType: string;
}

export interface RequestUploadUrlResponse {
  uploadURL: string;
  objectPath: string;
  metadata?: RequestUploadUrlBody;
}

export interface HomeStats {
  totalApps: number;
  totalServices: number;
  unreadNotifications: number;
  unreadMessages: number;
  totalUsers: number;
}

export type AdminStatsRange =
  (typeof AdminStatsRange)[keyof typeof AdminStatsRange];

export const AdminStatsRange = {
  "7d": "7d",
  "30d": "30d",
  "90d": "90d",
  custom: "custom",
} as const;

export type AdminStatsSignupsByDayItem = {
  date: string;
  count: number;
};

export type AdminStatsAppOpensByDayItem = {
  date: string;
  count: number;
};

export type AdminStatsServicesCreatedByDayItem = {
  date: string;
  count: number;
};

export interface TopAppItem {
  appId: number;
  slug: string;
  nameAr: string;
  nameEn: string;
  iconName: string;
  color: string;
  count: number;
}

export interface TopUserItem {
  userId: number;
  username: string;
  /** @nullable */
  displayNameAr?: string | null;
  /** @nullable */
  displayNameEn?: string | null;
  /** @nullable */
  avatarUrl?: string | null;
  count: number;
}

export interface AdminStats {
  range: AdminStatsRange;
  rangeDays: number;
  /** Start date (YYYY-MM-DD UTC) of the selected window */
  rangeFrom?: string;
  /** End date (YYYY-MM-DD UTC) of the selected window */
  rangeTo?: string;
  newUsersInRange: number;
  newUsersPrevRange: number;
  activeServices: number;
  inactiveServices: number;
  signupsByDay: AdminStatsSignupsByDayItem[];
  appOpensByDay: AdminStatsAppOpensByDayItem[];
  appOpensInRange: number;
  appOpensPrevRange: number;
  servicesCreatedByDay: AdminStatsServicesCreatedByDayItem[];
  servicesCreatedInRange: number;
  topApps: TopAppItem[];
  mostActiveUsers: TopUserItem[];
}

export interface AppOpenByAppEntry {
  id: number;
  createdAt: string;
  userId: number;
  username: string;
  /** @nullable */
  displayNameAr?: string | null;
  /** @nullable */
  displayNameEn?: string | null;
  /** @nullable */
  avatarUrl?: string | null;
}

export type AdminAppOpensByAppRange =
  (typeof AdminAppOpensByAppRange)[keyof typeof AdminAppOpensByAppRange];

export const AdminAppOpensByAppRange = {
  "7d": "7d",
  "30d": "30d",
  "90d": "90d",
  custom: "custom",
} as const;

export interface AdminAppOpensByApp {
  appId: number;
  slug: string;
  nameAr: string;
  nameEn: string;
  iconName: string;
  color: string;
  range: AdminAppOpensByAppRange;
  rangeDays: number;
  rangeFrom: string;
  rangeTo: string;
  totalCount: number;
  limit: number;
  offset: number;
  /** @nullable */
  nextOffset: number | null;
  opens: AppOpenByAppEntry[];
}

export interface AppOpenByUserEntry {
  id: number;
  createdAt: string;
  appId: number;
  slug: string;
  nameAr: string;
  nameEn: string;
  iconName: string;
  color: string;
}

export type AdminAppOpensByUserRange =
  (typeof AdminAppOpensByUserRange)[keyof typeof AdminAppOpensByUserRange];

export const AdminAppOpensByUserRange = {
  "7d": "7d",
  "30d": "30d",
  "90d": "90d",
  custom: "custom",
} as const;

export interface AdminAppOpensByUser {
  userId: number;
  username: string;
  /** @nullable */
  displayNameAr?: string | null;
  /** @nullable */
  displayNameEn?: string | null;
  /** @nullable */
  avatarUrl?: string | null;
  range: AdminAppOpensByUserRange;
  rangeDays: number;
  rangeFrom: string;
  rangeTo: string;
  totalCount: number;
  limit: number;
  offset: number;
  /** @nullable */
  nextOffset: number | null;
  opens: AppOpenByUserEntry[];
}

export interface AuditLogActor {
  id: number;
  username: string;
  /** @nullable */
  displayNameAr?: string | null;
  /** @nullable */
  displayNameEn?: string | null;
  /** @nullable */
  avatarUrl?: string | null;
}

export interface RolePermissionAuditEntry {
  id: number;
  roleId: number;
  previousPermissionIds: number[];
  newPermissionIds: number[];
  addedPermissionIds: number[];
  removedPermissionIds: number[];
  createdAt: string;
  actor: AuditLogActor | null;
}

export interface RolePermissionAuditList {
  entries: RolePermissionAuditEntry[];
  totalCount: number;
  limit: number;
  offset: number;
  /** @nullable */
  nextOffset: number | null;
}

export type PermissionAuditEntryTargetKind =
  (typeof PermissionAuditEntryTargetKind)[keyof typeof PermissionAuditEntryTargetKind];

export const PermissionAuditEntryTargetKind = {
  user: "user",
  group: "group",
  app: "app",
} as const;

export type PermissionAuditEntryChangeKind =
  (typeof PermissionAuditEntryChangeKind)[keyof typeof PermissionAuditEntryChangeKind];

export const PermissionAuditEntryChangeKind = {
  userroles: "user.roles",
  usergroups: "user.groups",
  groupusers: "group.users",
  grouproles: "group.roles",
  groupapps: "group.apps",
  apppermissions: "app.permissions",
} as const;

export interface PermissionAuditEntry {
  id: number;
  targetKind: PermissionAuditEntryTargetKind;
  targetId: number;
  changeKind: PermissionAuditEntryChangeKind;
  previousIds: number[];
  newIds: number[];
  addedIds: number[];
  removedIds: number[];
  createdAt: string;
  actor: AuditLogActor | null;
}

export interface PermissionAuditList {
  entries: PermissionAuditEntry[];
  totalCount: number;
  limit: number;
  offset: number;
  /** @nullable */
  nextOffset: number | null;
}

/**
 * @nullable
 */
export type AuditLogEntryMetadata = { [key: string]: unknown } | null;

export interface AuditLogEntry {
  id: number;
  action: string;
  targetType: string;
  /** @nullable */
  targetId: number | null;
  /** @nullable */
  metadata: AuditLogEntryMetadata;
  createdAt: string;
  actor: AuditLogActor | null;
}

export interface AuditLogList {
  entries: AuditLogEntry[];
  totalCount: number;
  limit: number;
  offset: number;
  /** @nullable */
  nextOffset: number | null;
  /** All distinct action names present in the audit log (for building filter UI). */
  actions: string[];
}

export type DeleteAppParams = {
  /**
   * Force deletion of an app that has dependent records (records an audit log entry).
   */
  force?: boolean;
};

export type DeleteServiceParams = {
  /**
   * Force deletion of a service that has existing orders (records an audit log entry).
   */
  force?: boolean;
};

export type LeaveConversationBody = {
  /** When the leaver is the only admin, optionally name a specific
remaining member to promote. Omit (or send null) to keep the
automatic behavior of promoting the longest-tenured member.
 */
  successorId?: number | null;
};

export type ListUsersParams = {
  /**
   * Free-text search across username, email, and display names
   */
  q?: string;
  /**
   * Filter to users that belong to the given group
   */
  groupId?: number;
  /**
   * Filter by active/disabled state
   */
  status?: ListUsersStatus;
};

export type ListUsersStatus =
  (typeof ListUsersStatus)[keyof typeof ListUsersStatus];

export const ListUsersStatus = {
  active: "active",
  disabled: "disabled",
} as const;

export type DeleteUserParams = {
  /**
   * Force deletion of a user that owns dependent records (records an audit log entry).
   */
  force?: boolean;
};

export type GetRolePermissionAuditParams = {
  /**
   * @minimum 1
   * @maximum 200
   */
  limit?: number;
  /**
   * @minimum 0
   */
  offset?: number;
  /**
 * Restrict results to entries authored by the given user. Use
`0` or omit to return entries from any actor.

 * @minimum 0
 */
  actorUserId?: number;
  /**
   * Start date (inclusive, YYYY-MM-DD UTC).
   */
  from?: string;
  /**
   * End date (inclusive, YYYY-MM-DD UTC).
   */
  to?: string;
};

export type ListGroupsParams = {
  q?: string;
};

export type DeleteGroupParams = {
  /**
   * Force deletion of a non-empty group (records an audit log entry).
   */
  force?: boolean;
};

export type GetUserPermissionAuditParams = {
  /**
   * @minimum 1
   * @maximum 200
   */
  limit?: number;
  /**
   * @minimum 0
   */
  offset?: number;
  /**
   * @minimum 0
   */
  actorUserId?: number;
  from?: string;
  to?: string;
};

export type GetGroupPermissionAuditParams = {
  /**
   * @minimum 1
   * @maximum 200
   */
  limit?: number;
  /**
   * @minimum 0
   */
  offset?: number;
  /**
   * @minimum 0
   */
  actorUserId?: number;
  from?: string;
  to?: string;
};

export type GetAppPermissionAuditParams = {
  /**
   * @minimum 1
   * @maximum 200
   */
  limit?: number;
  /**
   * @minimum 0
   */
  offset?: number;
  /**
   * @minimum 0
   */
  actorUserId?: number;
  from?: string;
  to?: string;
};

export type GetAdminStatsParams = {
  /**
   * Time range for trend stats. Use "custom" with from/to.
   */
  range?: GetAdminStatsRange;
  /**
   * Start date (inclusive, YYYY-MM-DD UTC) when range=custom
   */
  from?: string;
  /**
   * End date (inclusive, YYYY-MM-DD UTC) when range=custom
   */
  to?: string;
};

export type GetAdminStatsRange =
  (typeof GetAdminStatsRange)[keyof typeof GetAdminStatsRange];

export const GetAdminStatsRange = {
  "7d": "7d",
  "30d": "30d",
  "90d": "90d",
  custom: "custom",
} as const;

export type GetAdminAppOpensByAppParams = {
  range?: GetAdminAppOpensByAppRange;
  from?: string;
  to?: string;
  /**
   * @minimum 1
   * @maximum 200
   */
  limit?: number;
  /**
   * @minimum 0
   */
  offset?: number;
};

export type GetAdminAppOpensByAppRange =
  (typeof GetAdminAppOpensByAppRange)[keyof typeof GetAdminAppOpensByAppRange];

export const GetAdminAppOpensByAppRange = {
  "7d": "7d",
  "30d": "30d",
  "90d": "90d",
  custom: "custom",
} as const;

export type GetAdminAppOpensByUserParams = {
  range?: GetAdminAppOpensByUserRange;
  from?: string;
  to?: string;
  /**
   * @minimum 1
   * @maximum 200
   */
  limit?: number;
  /**
   * @minimum 0
   */
  offset?: number;
};

export type GetAdminAppOpensByUserRange =
  (typeof GetAdminAppOpensByUserRange)[keyof typeof GetAdminAppOpensByUserRange];

export const GetAdminAppOpensByUserRange = {
  "7d": "7d",
  "30d": "30d",
  "90d": "90d",
  custom: "custom",
} as const;

export type ListAuditLogsParams = {
  /**
   * Exact action name to filter by (e.g. "group.force_delete").
   */
  action?: string;
  /**
 * When true, restrict results to forced deletions only — i.e. rows
with action `group.force_delete`, `user.force_delete`,
`app.force_delete`, `service.force_delete`, or any
`group.delete`/`user.delete`/`app.delete` row whose metadata
contains `force: true`. Overrides the `action` filter when set.

 */
  forcedOnly?: boolean;
  /**
   * Start date (inclusive, YYYY-MM-DD UTC).
   */
  from?: string;
  /**
   * End date (inclusive, YYYY-MM-DD UTC).
   */
  to?: string;
  /**
 * Restrict results to entries whose `target_type` exactly matches
(e.g. "group", "app", "role", "user", "service", "settings").
Combines with `targetId` and the other filters.

 */
  targetType?: string;
  /**
 * Restrict results to entries whose `target_id` exactly matches.
Typically used together with `targetType` to focus on the history
of a single entity.

 * @minimum 1
 */
  targetId?: number;
  /**
   * @minimum 1
   * @maximum 200
   */
  limit?: number;
  /**
   * @minimum 0
   */
  offset?: number;
};

export type ExportAuditLogsCsvParams = {
  /**
   * Exact action name to filter by (e.g. "group.force_delete").
   */
  action?: string;
  /**
 * When true, restrict the export to forced deletions only.
See the list endpoint for the exact set of matching rows.
Overrides the `action` filter when set.

 */
  forcedOnly?: boolean;
  /**
   * Start date (inclusive, YYYY-MM-DD UTC).
   */
  from?: string;
  /**
   * End date (inclusive, YYYY-MM-DD UTC).
   */
  to?: string;
  /**
 * Restrict the export to entries whose `target_type` exactly matches.
Combines with `targetId` and the other filters.

 */
  targetType?: string;
  /**
 * Restrict the export to entries whose `target_id` exactly matches.

 * @minimum 1
 */
  targetId?: number;
};
