/**
 * Pre-seeded Convex gotchas extracted from convexRules.md and common patterns.
 * These are loaded into the DB on first run.
 */
export const CONVEX_GOTCHAS = [
  {
    key: "validator_bigint_deprecated",
    content: "v.bigint() is deprecated for representing signed 64-bit integers. Use v.int64() instead.",
    category: "validator",
    severity: "critical",
    tags: "bigint,int64,deprecated,validator",
  },
  {
    key: "undefined_not_valid",
    content: "JavaScript's undefined is not a valid Convex value. Functions that return undefined or do not return will return null when called from a client. Use null instead of undefined.",
    category: "validator",
    severity: "critical",
    tags: "undefined,null,return,value",
  },
  {
    key: "system_fields_auto",
    content: "_creationTime (v.number()) and _id (v.id(tableName)) are automatically added to all documents as system fields. Do not include them in your schema definition.",
    category: "schema",
    severity: "warning",
    tags: "_creationTime,_id,system,fields,schema",
  },
  {
    key: "index_field_order",
    content: "Index fields must be queried in the same order they are defined. If you want to query by field1 then field2 AND by field2 then field1, you must create separate indexes.",
    category: "schema",
    severity: "critical",
    tags: "index,order,query,field",
  },
  {
    key: "no_map_set_validators",
    content: "v.map() and v.set() are not supported. Use v.record(keys, values) for defining record types instead.",
    category: "validator",
    severity: "critical",
    tags: "map,set,record,validator,unsupported",
  },
  {
    key: "action_from_action",
    content: "Only call an action from another action if you need to cross runtimes (e.g. from V8 to Node). Otherwise, extract the shared code into a helper async function and call that directly.",
    category: "function",
    severity: "warning",
    tags: "action,runtime,v8,node,helper",
  },
  {
    key: "function_ref_not_direct",
    content: "Use api.x.y or internal.x.y function references when calling ctx.runQuery/runMutation/runAction. Do NOT try to pass the callee function directly.",
    category: "function",
    severity: "critical",
    tags: "function,reference,api,internal,runQuery",
  },
  {
    key: "new_function_syntax",
    content: "Always use the new function syntax: query({ args: {}, returns: v.null(), handler: async (ctx, args) => { } }). The old style without args/returns objects is deprecated.",
    category: "function",
    severity: "critical",
    tags: "syntax,query,mutation,action,args,returns",
  },
  {
    key: "internal_for_private",
    content: "Use internalQuery, internalMutation, and internalAction to register internal functions. These are private and not part of the app's public API. Use query/mutation/action only for functions that should be exposed publicly.",
    category: "function",
    severity: "warning",
    tags: "internal,private,public,security,api",
  },
  {
    key: "returns_validator_required",
    content: "Always include argument and return validators for ALL Convex functions (query, internalQuery, mutation, internalMutation, action, internalAction). If a function doesn't return anything, use returns: v.null().",
    category: "function",
    severity: "critical",
    tags: "returns,validator,null,args,required",
  },
  {
    key: "no_register_via_api",
    content: "You CANNOT register a function through the api or internal objects. These are only for referencing already-registered functions.",
    category: "function",
    severity: "critical",
    tags: "register,api,internal,function",
  },
  {
    key: "circular_type_annotation",
    content: "When using ctx.runQuery, ctx.runMutation, or ctx.runAction to call a function in the same file, specify a type annotation on the return value to work around TypeScript circularity limitations.",
    category: "function",
    severity: "warning",
    tags: "circular,type,annotation,typescript,same-file",
  },
  {
    key: "array_max_8192",
    content: "Arrays can have at most 8192 values in Convex.",
    category: "validator",
    severity: "warning",
    tags: "array,limit,8192,size",
  },
  {
    key: "object_max_1024",
    content: "Objects can have at most 1024 entries in Convex.",
    category: "validator",
    severity: "warning",
    tags: "object,limit,1024,entries",
  },
  {
    key: "field_no_dollar_underscore",
    content: "Field names must be nonempty and not start with '$' or '_'. These prefixes are reserved for system use.",
    category: "schema",
    severity: "critical",
    tags: "field,name,dollar,underscore,reserved",
  },
  {
    key: "index_name_include_fields",
    content: "Always include all index fields in the index name. For example, if an index is defined as ['field1', 'field2'], the index name should be 'by_field1_and_field2'.",
    category: "schema",
    severity: "info",
    tags: "index,name,convention,fields",
  },
  {
    key: "http_exact_path",
    content: "HTTP endpoints are always registered at the exact path you specify. For example, /api/someRoute registers at /api/someRoute, not as a prefix match.",
    category: "function",
    severity: "info",
    tags: "http,path,route,endpoint,exact",
  },
  {
    key: "record_key_restrictions",
    content: "Record keys must be only ASCII characters, nonempty, and not start with '$' or '_'.",
    category: "validator",
    severity: "warning",
    tags: "record,key,ascii,restriction",
  },
  {
    key: "string_utf8_1mb",
    content: "Strings are stored as UTF-8 and must be valid Unicode sequences. Strings must be smaller than the 1MB total size limit when encoded as UTF-8.",
    category: "validator",
    severity: "info",
    tags: "string,utf8,size,limit,1mb",
  },
  {
    key: "minimize_action_to_query_calls",
    content: "Try to use as few calls from actions to queries and mutations as possible. Queries and mutations are transactions, so splitting logic into multiple calls introduces race condition risk.",
    category: "function",
    severity: "warning",
    tags: "action,query,mutation,transaction,race,condition",
  },
  {
    key: "pagination_cursor_null_first",
    content: "When using .paginate(), the first call must pass cursor: null (not undefined). Subsequent calls use the continueCursor from the previous response. The paginationOpts validator is paginationOptsValidator from 'convex/server'.",
    category: "function",
    severity: "critical",
    tags: "pagination,cursor,null,paginate,paginationOpts",
  },
  {
    key: "query_no_side_effects",
    content: "Queries (query/internalQuery) CANNOT call ctx.runMutation or ctx.runAction. They are read-only. Attempting to mutate from a query will throw a runtime error.",
    category: "function",
    severity: "critical",
    tags: "query,mutation,action,side-effect,read-only,runtime",
  },
  {
    key: "ctx_auth_returns_null",
    content: "ctx.auth.getUserIdentity() returns null when the user is not authenticated. Always null-check before accessing identity fields. Do NOT assume it returns a value.",
    category: "function",
    severity: "warning",
    tags: "auth,identity,null,getUserIdentity,authentication",
  },
  {
    key: "scheduled_function_must_be_internal",
    content: "Functions passed to ctx.scheduler.runAfter or ctx.scheduler.runAt should be internal functions (internalMutation/internalAction). Using public functions exposes them to the API.",
    category: "function",
    severity: "warning",
    tags: "scheduler,scheduled,runAfter,runAt,internal,cron",
  },
  {
    key: "http_route_no_wildcard",
    content: "Convex HTTP routes use exact path matching, not prefix/wildcard matching. /api/users does NOT match /api/users/123. Register separate routes for each path.",
    category: "function",
    severity: "warning",
    tags: "http,route,wildcard,path,exact,matching",
  },
  {
    key: "http_cors_manual",
    content: "Convex HTTP endpoints do not automatically handle CORS. You must manually add CORS headers (Access-Control-Allow-Origin, etc.) and handle OPTIONS preflight requests.",
    category: "function",
    severity: "warning",
    tags: "http,cors,headers,options,preflight,origin",
  },
  {
    key: "avoid_v_any",
    content: "v.any() defeats the purpose of validators — it accepts any value and provides no type safety. Use specific validators (v.string(), v.object({...}), v.union(...)) instead.",
    category: "validator",
    severity: "warning",
    tags: "any,validator,type-safety,schema",
  },
  {
    key: "storage_get_returns_null",
    content: "ctx.storage.get(storageId) returns null if the file doesn't exist. Always null-check the result before using it. Also, storage IDs are typed as Id<'_storage'>.",
    category: "function",
    severity: "warning",
    tags: "storage,get,null,file,upload,_storage",
  },
  {
    key: "mutation_transaction_atomicity",
    content: "Each mutation runs as a single transaction. If you call ctx.runMutation multiple times from an action, each is a separate transaction — there's no cross-mutation atomicity. Design mutations to be self-contained.",
    category: "function",
    severity: "warning",
    tags: "mutation,transaction,atomicity,action,consistency",
  },
  {
    key: "db_get_returns_null",
    content: "ctx.db.get(id) returns null if the document doesn't exist or was deleted. Always null-check before accessing fields. TypeScript won't catch this at compile time.",
    category: "function",
    severity: "warning",
    tags: "db,get,null,document,deleted",
  },
  {
    key: "convex_1mb_document_limit",
    content: "Individual Convex documents cannot exceed 1MB. Large text, arrays of objects, or embedded binary data can exceed this. Split large data across multiple documents or use file storage.",
    category: "schema",
    severity: "warning",
    tags: "document,size,limit,1mb,split,storage",
  },
  {
    key: "use_node_for_external_api",
    content: "Convex actions that call external APIs (fetch, HTTP clients) must use the Node.js runtime. Add 'use node' at the top of the file. V8 runtime does not support fetch to external URLs.",
    category: "function",
    severity: "critical",
    tags: "node,runtime,fetch,external,api,use-node",
  },
] as const;

export type ConvexGotcha = typeof CONVEX_GOTCHAS[number];
