const TABLE = 'vk_owner_handles' /** 主人 id 的格式:小写字母、数字、下划线、连字符,2–32 位,字母或数字开头。与 DB CHECK 一致。 */ export const HANDLE_PATTERN = /^[a-z0-9][a-z0-9_-]{1,31}$/ /** * 主人的 id(handle)。Agent 的全名是「名字@主人 id」,如 小火子@yibo。 * @param {{ db: import('knex').Knex }} deps */ export function createOwnerHandles({ db }) { if (typeof db !== 'function') throw new Error('createOwnerHandles: db is required') /** * @param {object} _ctx * @param {{ handle: string }} input * @returns {Promise} */ async function isTaken(_ctx, { handle }) { return (await db(TABLE).where({ handle }).first('user_id')) !== undefined } /** * 注册时在同一事务里登记;handle 被占用由 UNIQUE 裁决(调用方应先用 isTaken 给出友好提示)。 * @param {object} _ctx * @param {import('knex').Knex} trx * @param {{ user_id: string, handle: string }} input */ async function assign(_ctx, trx, { user_id, handle }) { await trx(TABLE).insert({ user_id, handle, created_at: new Date() }) } /** * @param {object} _ctx * @param {{ user_id: string }} input * @returns {Promise} */ async function get(_ctx, { user_id }) { const row = await db(TABLE).where({ user_id }).first('handle') return row === undefined ? null : row.handle } return { isTaken, assign, get } }