// This file was auto-generated by generate_types in the remote crate.
// Do not edit manually.

// Electric row types
export type JsonValue = number | string | boolean | Array<JsonValue> | { [key in string]?: JsonValue } | null;

export type Project = { id: string, organization_id: string, name: string, color: string, sort_order: number, created_at: string, updated_at: string, };

export type Notification = { id: string, organization_id: string, user_id: string, notification_type: NotificationType, payload: NotificationPayload, issue_id: string | null, comment_id: string | null, seen: boolean, dismissed_at: string | null, created_at: string, };

export type NotificationGroupKind = "single" | "issue_changes" | "status_changes" | "comments" | "reactions" | "issue_deleted";

export type NotificationPayload = { deeplink_path?: string | null, issue_id?: string | null, issue_simple_id?: string | null, issue_title?: string | null, actor_user_id?: string | null, comment_preview?: string | null, old_status_id?: string | null, new_status_id?: string | null, old_status_name?: string | null, new_status_name?: string | null, new_title?: string | null, old_priority?: IssuePriority | null, new_priority?: IssuePriority | null, assignee_user_id?: string | null, emoji?: string | null, };

export type NotificationType = "issue_comment_added" | "issue_status_changed" | "issue_assignee_changed" | "issue_priority_changed" | "issue_unassigned" | "issue_comment_reaction" | "issue_deleted" | "issue_title_changed" | "issue_description_changed";

export type Workspace = { id: string, project_id: string, owner_user_id: string, issue_id: string | null, local_workspace_id: string | null, name: string | null, archived: boolean, files_changed: number | null, lines_added: number | null, lines_removed: number | null, created_at: string, updated_at: string, };

export type ProjectStatus = { id: string, project_id: string, name: string, color: string, sort_order: number, hidden: boolean, created_at: string, };

export type Tag = { id: string, project_id: string, name: string, color: string, };

export type Issue = { id: string, project_id: string, issue_number: number, simple_id: string, status_id: string, title: string, description: string | null, priority: IssuePriority | null, start_date: string | null, target_date: string | null, completed_at: string | null, sort_order: number, parent_issue_id: string | null, parent_issue_sort_order: number | null, extension_metadata: JsonValue, creator_user_id: string | null, created_at: string, updated_at: string, };

export type IssueAssignee = { id: string, issue_id: string, user_id: string, assigned_at: string, };

export type Blob = { id: string, project_id: string, blob_path: string, thumbnail_blob_path: string | null, original_name: string, mime_type: string | null, size_bytes: bigint, hash: string, width: number | null, height: number | null, created_at: string, updated_at: string, };

export type Attachment = { id: string, blob_id: string, issue_id: string | null, comment_id: string | null, created_at: string, expires_at: string | null, };

export type AttachmentWithBlob = { id: string, blob_id: string, issue_id: string | null, comment_id: string | null, created_at: string, expires_at: string | null, blob_path: string, thumbnail_blob_path: string | null, original_name: string, mime_type: string | null, size_bytes: bigint, hash: string, width: number | null, height: number | null, };

export type IssueFollower = { id: string, issue_id: string, user_id: string, };

export type IssueTag = { id: string, issue_id: string, tag_id: string, };

export type IssueRelationship = { id: string, issue_id: string, related_issue_id: string, relationship_type: IssueRelationshipType, created_at: string, };

export type IssueRelationshipType = "blocking" | "related" | "has_duplicate";

export type IssueComment = { id: string, issue_id: string, author_id: string | null, parent_id: string | null, message: string, created_at: string, updated_at: string, };

export type IssueCommentReaction = { id: string, comment_id: string, user_id: string, emoji: string, created_at: string, };

export type IssuePriority = "urgent" | "high" | "medium" | "low";

export type IssueSortField = "sort_order" | "priority" | "created_at" | "updated_at" | "title";

export type ListIssuesQuery = { project_id: string, };

export type SearchIssuesRequest = { project_id: string, status_id?: string, status_ids?: Array<string>, priority?: IssuePriority, parent_issue_id?: string, search?: string, simple_id?: string, assignee_user_id?: string, tag_id?: string, tag_ids?: Array<string>, sort_field?: IssueSortField, sort_direction?: SortDirection, limit?: number, offset?: number, };

export type ListIssuesResponse = { issues: Array<Issue>, total_count: number, limit: number, offset: number, };

export type PullRequestStatus = "open" | "merged" | "closed";

export type PullRequest = { id: string, url: string, number: number, status: PullRequestStatus, merged_at: string | null, merge_commit_sha: string | null, target_branch_name: string, project_id: string, issue_id: string, workspace_id: string | null, created_at: string, updated_at: string, };

export type PullRequestIssue = { id: string, pull_request_id: string, issue_id: string, };

export type CreatePullRequestIssueRequest = { 
/**
 * Optional client-generated ID. If not provided, server generates one.
 * Using client-generated IDs enables stable optimistic updates.
 */
id?: string, issue_id: string, url: string, number: number, status: PullRequestStatus, merged_at: string | null, merge_commit_sha: string | null, target_branch_name: string, };

export type SortDirection = "asc" | "desc";

export type UserData = { user_id: string, first_name: string | null, last_name: string | null, username: string | null, };

export type User = { id: string, email: string, first_name: string | null, last_name: string | null, username: string | null, created_at: string, updated_at: string, };

export type RelayHost = { id: string, owner_user_id: string, machine_id: string, name: string, status: string, last_seen_at: string | null, agent_version: string | null, created_at: string, updated_at: string, access_role: string, };

export type ListRelayHostsResponse = { hosts: Array<RelayHost>, };

export type CreateRemoteSessionResponse = { session_id: string, };

export enum MemberRole { ADMIN = "ADMIN", MEMBER = "MEMBER" }

export type OrganizationMember = { organization_id: string, user_id: string, role: MemberRole, joined_at: string, last_seen_at: string | null, };

export type CreateProjectRequest = { 
/**
 * Optional client-generated ID. If not provided, server generates one.
 * Using client-generated IDs enables stable optimistic updates.
 */
id?: string, organization_id: string, name: string, color: string, };

export type UpdateProjectRequest = { name: string | null, color: string | null, sort_order: number | null, };

export type UpdateNotificationRequest = { seen: boolean | null, };

export type CreateTagRequest = { 
/**
 * Optional client-generated ID. If not provided, server generates one.
 * Using client-generated IDs enables stable optimistic updates.
 */
id?: string, project_id: string, name: string, color: string, };

export type UpdateTagRequest = { name: string | null, color: string | null, };

export type CreateProjectStatusRequest = { 
/**
 * Optional client-generated ID. If not provided, server generates one.
 * Using client-generated IDs enables stable optimistic updates.
 */
id?: string, project_id: string, name: string, color: string, sort_order: number, hidden: boolean, };

export type UpdateProjectStatusRequest = { name: string | null, color: string | null, sort_order: number | null, hidden: boolean | null, };

export type CreateIssueRequest = { 
/**
 * Optional client-generated ID. If not provided, server generates one.
 * Using client-generated IDs enables stable optimistic updates.
 */
id?: string, project_id: string, status_id: string, title: string, description: string | null, priority: IssuePriority | null, start_date: string | null, target_date: string | null, completed_at: string | null, sort_order: number, parent_issue_id: string | null, parent_issue_sort_order: number | null, extension_metadata: JsonValue, };

export type UpdateIssueRequest = { status_id?: string | null, title?: string | null, description?: string | null | null, priority?: IssuePriority | null | null, start_date?: string | null | null, target_date?: string | null | null, completed_at?: string | null | null, sort_order?: number | null, parent_issue_id?: string | null | null, parent_issue_sort_order?: number | null | null, extension_metadata?: JsonValue | null, };

export type CreateIssueAssigneeRequest = { 
/**
 * Optional client-generated ID. If not provided, server generates one.
 * Using client-generated IDs enables stable optimistic updates.
 */
id?: string, issue_id: string, user_id: string, };

export type CreateIssueFollowerRequest = { 
/**
 * Optional client-generated ID. If not provided, server generates one.
 * Using client-generated IDs enables stable optimistic updates.
 */
id?: string, issue_id: string, user_id: string, };

export type CreateIssueTagRequest = { 
/**
 * Optional client-generated ID. If not provided, server generates one.
 * Using client-generated IDs enables stable optimistic updates.
 */
id?: string, issue_id: string, tag_id: string, };

export type CreateIssueRelationshipRequest = { 
/**
 * Optional client-generated ID. If not provided, server generates one.
 * Using client-generated IDs enables stable optimistic updates.
 */
id?: string, issue_id: string, related_issue_id: string, relationship_type: IssueRelationshipType, };

export type CreateIssueCommentRequest = { 
/**
 * Optional client-generated ID. If not provided, server generates one.
 * Using client-generated IDs enables stable optimistic updates.
 */
id?: string, issue_id: string, message: string, parent_id: string | null, };

export type UpdateIssueCommentRequest = { message: string | null, parent_id: string | null | null, };

export type CreateIssueCommentReactionRequest = { 
/**
 * Optional client-generated ID. If not provided, server generates one.
 * Using client-generated IDs enables stable optimistic updates.
 */
id?: string, comment_id: string, emoji: string, };

export type UpdateIssueCommentReactionRequest = { emoji: string | null, };

export type InitUploadRequest = { project_id: string, filename: string, size_bytes: number, hash: string, };

export type InitUploadResponse = { upload_url: string, upload_id: string, expires_at: string, skip_upload: boolean, existing_blob_id: string | null, };

export type ConfirmUploadRequest = { project_id: string, upload_id: string, filename: string, content_type?: string, size_bytes: number, hash: string, issue_id?: string, comment_id?: string, };

export type CommitAttachmentsRequest = { attachment_ids: Array<string>, };

export type CommitAttachmentsResponse = { attachments: Array<AttachmentWithBlob>, };

export type AttachmentUrlResponse = { url: string, };

export type ExportRequest = { organization_id: string, 
/**
 * If empty, exports all projects in the organization.
 */
project_ids: Array<string>, include_attachments: boolean, };

// Shape definition interface
export interface ShapeDefinition<T> {
  readonly table: string;
  readonly params: readonly string[];
  readonly url: string;
  readonly fallbackUrl: string;
  readonly _type: T;  // Phantom field for type inference (not present at runtime)
}

// Helper to create type-safe shape definitions
function defineShape<T>(
  table: string,
  params: readonly string[],
  url: string,
  fallbackUrl: string
): ShapeDefinition<T> {
  return { table, params, url, fallbackUrl } as ShapeDefinition<T>;
}

// Individual shape definitions with embedded types
export const PROJECTS_SHAPE = defineShape<Project>(
  'projects',
  ['organization_id'] as const,
  '/v1/shape/projects',
  '/v1/fallback/projects'
);

export const NOTIFICATIONS_SHAPE = defineShape<Notification>(
  'notifications',
  ['user_id'] as const,
  '/v1/shape/notifications',
  '/v1/fallback/notifications'
);

export const ORGANIZATION_MEMBERS_SHAPE = defineShape<OrganizationMember>(
  'organization_member_metadata',
  ['organization_id'] as const,
  '/v1/shape/organization_members',
  '/v1/fallback/organization_members'
);

export const USERS_SHAPE = defineShape<User>(
  'users',
  ['organization_id'] as const,
  '/v1/shape/users',
  '/v1/fallback/users'
);

export const PROJECT_TAGS_SHAPE = defineShape<Tag>(
  'tags',
  ['project_id'] as const,
  '/v1/shape/project/{project_id}/tags',
  '/v1/fallback/tags'
);

export const PROJECT_PROJECT_STATUSES_SHAPE = defineShape<ProjectStatus>(
  'project_statuses',
  ['project_id'] as const,
  '/v1/shape/project/{project_id}/project_statuses',
  '/v1/fallback/project_statuses'
);

export const PROJECT_ISSUES_SHAPE = defineShape<Issue>(
  'issues',
  ['project_id'] as const,
  '/v1/shape/project/{project_id}/issues',
  '/v1/fallback/issues'
);

export const USER_WORKSPACES_SHAPE = defineShape<Workspace>(
  'workspaces',
  ['owner_user_id'] as const,
  '/v1/shape/user/workspaces',
  '/v1/fallback/user_workspaces'
);

export const PROJECT_WORKSPACES_SHAPE = defineShape<Workspace>(
  'workspaces',
  ['project_id'] as const,
  '/v1/shape/project/{project_id}/workspaces',
  '/v1/fallback/project_workspaces'
);

export const PROJECT_ISSUE_ASSIGNEES_SHAPE = defineShape<IssueAssignee>(
  'issue_assignees',
  ['project_id'] as const,
  '/v1/shape/project/{project_id}/issue_assignees',
  '/v1/fallback/issue_assignees'
);

export const PROJECT_ISSUE_FOLLOWERS_SHAPE = defineShape<IssueFollower>(
  'issue_followers',
  ['project_id'] as const,
  '/v1/shape/project/{project_id}/issue_followers',
  '/v1/fallback/issue_followers'
);

export const PROJECT_ISSUE_TAGS_SHAPE = defineShape<IssueTag>(
  'issue_tags',
  ['project_id'] as const,
  '/v1/shape/project/{project_id}/issue_tags',
  '/v1/fallback/issue_tags'
);

export const PROJECT_ISSUE_RELATIONSHIPS_SHAPE = defineShape<IssueRelationship>(
  'issue_relationships',
  ['project_id'] as const,
  '/v1/shape/project/{project_id}/issue_relationships',
  '/v1/fallback/issue_relationships'
);

export const PROJECT_PULL_REQUESTS_SHAPE = defineShape<PullRequest>(
  'pull_requests',
  ['project_id'] as const,
  '/v1/shape/project/{project_id}/pull_requests',
  '/v1/fallback/pull_requests'
);

export const PROJECT_PULL_REQUEST_ISSUES_SHAPE = defineShape<PullRequestIssue>(
  'pull_request_issues',
  ['project_id'] as const,
  '/v1/shape/project/{project_id}/pull_request_issues',
  '/v1/fallback/pull_request_issues'
);

export const ISSUE_COMMENTS_SHAPE = defineShape<IssueComment>(
  'issue_comments',
  ['issue_id'] as const,
  '/v1/shape/issue/{issue_id}/comments',
  '/v1/fallback/issue_comments'
);

export const ISSUE_REACTIONS_SHAPE = defineShape<IssueCommentReaction>(
  'issue_comment_reactions',
  ['issue_id'] as const,
  '/v1/shape/issue/{issue_id}/reactions',
  '/v1/fallback/issue_comment_reactions'
);

// =============================================================================
// Mutation Definitions
// =============================================================================

// Mutation definition interface
export interface MutationDefinition<TRow, TCreate = unknown, TUpdate = unknown> {
  readonly name: string;
  readonly url: string;
  readonly _rowType: TRow;  // Phantom field for type inference (not present at runtime)
  readonly _createType: TCreate;  // Phantom field for type inference (not present at runtime)
  readonly _updateType: TUpdate;  // Phantom field for type inference (not present at runtime)
}

// Helper to create type-safe mutation definitions
function defineMutation<TRow, TCreate, TUpdate>(
  name: string,
  url: string
): MutationDefinition<TRow, TCreate, TUpdate> {
  return { name, url } as MutationDefinition<TRow, TCreate, TUpdate>;
}

// Individual mutation definitions
export const PROJECT_MUTATION = defineMutation<Project, CreateProjectRequest, UpdateProjectRequest>(
  'Project',
  '/v1/projects'
);

export const NOTIFICATION_MUTATION = defineMutation<Notification, unknown, UpdateNotificationRequest>(
  'Notification',
  '/v1/notifications'
);

export const TAG_MUTATION = defineMutation<Tag, CreateTagRequest, UpdateTagRequest>(
  'Tag',
  '/v1/tags'
);

export const PROJECT_STATUS_MUTATION = defineMutation<ProjectStatus, CreateProjectStatusRequest, UpdateProjectStatusRequest>(
  'ProjectStatus',
  '/v1/project_statuses'
);

export const ISSUE_MUTATION = defineMutation<Issue, CreateIssueRequest, UpdateIssueRequest>(
  'Issue',
  '/v1/issues'
);

export const ISSUE_ASSIGNEE_MUTATION = defineMutation<IssueAssignee, CreateIssueAssigneeRequest, unknown>(
  'IssueAssignee',
  '/v1/issue_assignees'
);

export const ISSUE_FOLLOWER_MUTATION = defineMutation<IssueFollower, CreateIssueFollowerRequest, unknown>(
  'IssueFollower',
  '/v1/issue_followers'
);

export const ISSUE_TAG_MUTATION = defineMutation<IssueTag, CreateIssueTagRequest, unknown>(
  'IssueTag',
  '/v1/issue_tags'
);

export const ISSUE_RELATIONSHIP_MUTATION = defineMutation<IssueRelationship, CreateIssueRelationshipRequest, unknown>(
  'IssueRelationship',
  '/v1/issue_relationships'
);

export const ISSUE_COMMENT_MUTATION = defineMutation<IssueComment, CreateIssueCommentRequest, UpdateIssueCommentRequest>(
  'IssueComment',
  '/v1/issue_comments'
);

export const ISSUE_COMMENT_REACTION_MUTATION = defineMutation<IssueCommentReaction, CreateIssueCommentReactionRequest, UpdateIssueCommentReactionRequest>(
  'IssueCommentReaction',
  '/v1/issue_comment_reactions'
);

export const PULL_REQUEST_ISSUE_MUTATION = defineMutation<PullRequestIssue, CreatePullRequestIssueRequest, unknown>(
  'PullRequestIssue',
  '/v1/pull_request_issues'
);

// Type helpers to extract types from a mutation definition
export type MutationRowType<M extends MutationDefinition<unknown>> = M extends MutationDefinition<infer R> ? R : never;
export type MutationCreateType<M extends MutationDefinition<unknown, unknown>> = M extends MutationDefinition<unknown, infer C> ? C : never;
export type MutationUpdateType<M extends MutationDefinition<unknown, unknown, unknown>> = M extends MutationDefinition<unknown, unknown, infer U> ? U : never;
