Source: config/migrations/20260822-runner-team-visibility.js

/**
 * Migration: Link existing runners to their owner groups and seed Visible admin.
 *
 * Runners now follow the same visibility model as projects:
 * - `shared` runners get a `memberA` link to their org root group
 * - every runner gets a `Visible admin` row for its creator (UIDuser)
 *
 * No schema change is needed — the `Links` and `Visible` tables already exist.
 */
export const id = '20260822-runner-team-visibility';
export const name = 'Link runners to owner groups and seed Visible admin';

/**
 * @param {{ query: Function }} api
 */
export const migrate = async ({ query }) => {
    // Shared runners → memberA link to their org root group (UIDBelongsTo).
    // Team runners did not exist before this migration, so only shared needs backfilling.
    await query(`
        INSERT IGNORE INTO Links (UID, Type, UIDTarget, UIDuser)
        SELECT ObjectBase.UID, 'memberA', ObjectBase.UIDBelongsTo, ObjectBase.UIDuser
        FROM ObjectBase
        WHERE ObjectBase.Type = 'runner'
          AND JSON_VALUE(ObjectBase.Data, '$.mode') = 'shared'
          AND ObjectBase.UIDBelongsTo IS NOT NULL
    `, []);

    // Every runner → Visible admin for its creator, so the admin always sees
    // and can administrate the runner.
    await query(`
        INSERT IGNORE INTO Visible (UID, Type, UIDUser)
        SELECT ObjectBase.UID, 'admin', ObjectBase.UIDuser
        FROM ObjectBase
        WHERE ObjectBase.Type = 'runner'
          AND ObjectBase.UIDuser IS NOT NULL
    `, []);
};