/** * Kysely table types. snake_case columns; timestamps are ISO-8601 text; JSON columns are text * (use `toJson`/`fromJson`); booleans are integer 0/1. All IDs come from app code (`newId()`), * so nothing here is `Generated<>`. */ export type Role = "admin" | "member"; export type EntryStatus = "planned" | "in_progress" | "paused" | "completed" | "dropped" | "none"; export type Visibility = "private" | "friends" | "public"; export type TokenScope = "read" | "write" | "ingest"; export type CustomFieldLevel = "entry" | "engagement" | "copy"; export type ListKind = "list" | "grouping" | "thread"; export type AttachmentEntity = "entry" | "engagement" | "copy" | "list" | "work"; export type SuggestionStatus = "pending" | "accepted" | "rejected"; export type ConnectionStatus = "active" | "paused" | "error"; export type RunMode = "full" | "changes" | "file"; export type RunStatus = "running" | "ok" | "failed"; export type ChangeType = "added" | "changed" | "removed" | "merged" | "conflict"; export type ChangeStatus = "pending" | "auto_applied" | "accepted" | "ignored" | "kept_mine"; export type JobStatus = "queued" | "running" | "done" | "failed"; export interface UsersTable { id: string; username: string; display_name: string; password_hash: string; role: Role; preferences: string; created_at: string; updated_at: string; } export interface SessionsTable { id: string; user_id: string; token_hash: string; expires_at: string; created_at: string; } export interface InvitesTable { id: string; code_hash: string; created_by: string; used_by: string | null; expires_at: string; created_at: string; } export interface AppTokensTable { id: string; user_id: string; name: string; token_hash: string; /** JSON `TokenScope[]`. */ scopes: string; last_used_at: string | null; revoked_at: string | null; created_at: string; } export interface WorksTable { id: string; media_type: string; title: string; original_title: string; year: number | null; release_date: string | null; creators: string; description: string; cover_url: string; cover_attachment_id: string | null; metadata: string; parent_id: string | null; position: string | null; owner_user_id: string | null; merged_into_id: string | null; created_at: string; updated_at: string; } export interface ExternalIdsTable { id: string; work_id: string; namespace: string; value: string; } export interface WorkAliasesTable { id: string; user_id: string; from_work_id: string; to_work_id: string; } export interface WorkHistoryTable { id: string; work_id: string; before: string; after: string; actor: string; created_at: string; } export interface EntriesTable { id: string; user_id: string; work_id: string; status: EntryStatus; rating: number | null; review: string | null; private_notes: string | null; /** 0 or 1. */ favorite: number; tags: string; custom_fields: string; visibility: Visibility; overrides: string; media_type_override: string | null; field_sources: string; created_at: string; updated_at: string; deleted_at: string | null; } export interface EngagementsTable { id: string; entry_id: string; started_at: string | null; started_precision: string; finished_at: string | null; finished_precision: string; progress: string; platform: string | null; rating: number | null; notes: string | null; custom_fields: string; field_sources: string; created_at: string; updated_at: string; deleted_at: string | null; } export interface EngagementSourcesTable { id: string; engagement_id: string; connection_id: string; record_key: string; } export interface ListensTable { id: string; user_id: string; listened_at: string; artist: string; track: string; album: string | null; duration_ms: number | null; mbids: string; work_id: string | null; source: string; source_key: string; created_at: string; } export interface ListsTable { id: string; user_id: string; name: string; description: string; kind: ListKind; visibility: Visibility; rating: number | null; review: string | null; created_at: string; updated_at: string; deleted_at: string | null; } export interface ListItemsTable { id: string; list_id: string; work_id: string; position: number; note: string | null; } export interface CustomFieldDefinitionsTable { id: string; user_id: string; name: string; type: string; options: string; /** JSON `MediaType[] | "all"`. */ applies_to: string; level: CustomFieldLevel; created_at: string; } export interface CopiesTable { id: string; user_id: string; work_id: string | null; title_hint: string | null; format: string | null; acquired_from: string | null; acquired_at: string | null; acquired_precision: string; price_cents: number | null; currency: string | null; notes: string | null; custom_fields: string; source_ref: string | null; created_at: string; updated_at: string; deleted_at: string | null; } export interface AttachmentsTable { id: string; user_id: string; sha256: string; mime: string; size: number; filename: string; caption: string | null; taken_at: string | null; visibility: Visibility | null; created_at: string; } export interface AttachmentLinksTable { id: string; attachment_id: string; entity: AttachmentEntity; entity_id: string; } export interface UserHistoryTable { id: string; user_id: string; entity: string; entity_id: string; before: string; after: string; actor: string; created_at: string; } export interface MatchSuggestionsTable { id: string; user_id: string; work_id: string; candidate_work_id: string; score: number; status: SuggestionStatus; created_at: string; } export interface SourceConnectionsTable { id: string; user_id: string; plugin_id: string; name: string; config: string; credentials_enc: string | null; schedule_minutes: number | null; cursor: string | null; status: ConnectionStatus; last_run_at: string | null; created_at: string; } export interface SourceRunsTable { id: string; connection_id: string; mode: RunMode; started_at: string; finished_at: string | null; status: RunStatus; counts: string; log: string; error: string | null; } export interface SourceRecordsTable { id: string; connection_id: string; key: string; kind: string; current_hash: string; first_seen: string; last_seen: string; deleted_at: string | null; merged_into_key: string | null; target_entity: string | null; target_id: string | null; } export interface SourceRecordVersionsTable { id: string; record_id: string; hash: string; /** Base64 of gzipped raw record. */ raw_gz: string; seen_at: string; } export interface ChangeEventsTable { id: string; user_id: string; connection_id: string | null; run_id: string | null; record_id: string | null; type: ChangeType; target_entity: string; target_id: string | null; payload: string; status: ChangeStatus; created_at: string; resolved_at: string | null; } export interface JobsTable { id: string; type: string; payload: string; run_at: string; status: JobStatus; attempts: number; last_error: string | null; locked_at: string | null; lock_key: string | null; created_at: string; } export interface Database { users: UsersTable; sessions: SessionsTable; invites: InvitesTable; app_tokens: AppTokensTable; works: WorksTable; external_ids: ExternalIdsTable; work_aliases: WorkAliasesTable; work_history: WorkHistoryTable; entries: EntriesTable; engagements: EngagementsTable; engagement_sources: EngagementSourcesTable; listens: ListensTable; lists: ListsTable; list_items: ListItemsTable; custom_field_definitions: CustomFieldDefinitionsTable; copies: CopiesTable; attachments: AttachmentsTable; attachment_links: AttachmentLinksTable; user_history: UserHistoryTable; match_suggestions: MatchSuggestionsTable; source_connections: SourceConnectionsTable; source_runs: SourceRunsTable; source_records: SourceRecordsTable; source_record_versions: SourceRecordVersionsTable; change_events: ChangeEventsTable; jobs: JobsTable; }