import { randomUUID } from 'node:crypto' const TABLE = 'vk_guilds' /** * @typedef {{ id: string, name: string, slug: string, lead_user_id: string, require_lead_approval: boolean, created_at: Date }} Guild */ /** * @param {{ db: import('knex').Knex }} deps */ export function createGuilds({ db }) { if (typeof db !== 'function') throw new Error('createGuilds: db is required') /** * 建公会并把负责人登记为成员。slug 已被占用返回 CONFLICT(由 UNIQUE 约束裁决)。 * @param {object} _ctx * @param {{ name: string, slug: string, lead_user_id: string, require_lead_approval: boolean, checkpoint_interval_sec?: number, piece_review_window_sec?: number, contest_review_window_sec?: number, transfer_ttl_sec?: number }} input 四个时间规则不传时用列默认值(6h / 24h / 72h / 24h) * @returns {Promise<{ ok: true, guild: Guild } | { ok: false, code: 'CONFLICT' }>} */ async function create(_ctx, { name, slug, lead_user_id, require_lead_approval, ...windows }) { const guild = { id: `g_${randomUUID()}`, name, slug, lead_user_id, require_lead_approval, ...windows, created_at: new Date() } return db.transaction(async (trx) => { // slug 冲突由 UNIQUE 裁决:被忽略的插入读不回本次 id。 await trx(TABLE).insert(guild).onConflict('slug').ignore() if ((await trx(TABLE).where({ id: guild.id }).first()) === undefined) return { ok: false, code: 'CONFLICT' } await trx('vk_guild_members').insert({ id: `gm_${randomUUID()}`, guild_id: guild.id, user_id: lead_user_id, role: 'lead', created_at: guild.created_at }) return { ok: true, guild } }) } /** * 全部公会(认领 Agent 时选择)。 * @param {object} _ctx * @returns {Promise>} */ async function list(_ctx) { return db(TABLE).orderBy('name', 'asc').select('id', 'name', 'slug') } return { create, list } }