export const id = '20261003-node-object-types';
export const name = "Node als generischer Tailnet-Objekttyp: ObjectBase.Type 'node', Links 'tailnetNode'; Runner werden Nodes mit role='runner'";
/**
* Ein Tailscale-Node war bisher **kein** Objekt — nur Runner hatten eine
* ObjectBase-Zeile (`Type='runner'`). Gateways und Dev-PCs existierten
* ausschließlich in Headscale: ohne Sichtbarkeit, ohne Gruppenzuordnung, ohne
* Möglichkeit, sie im UI einem Team/Netz zuzuordnen.
*
* Diese Migration macht den Node zum **ersten Objekttyp** für jede Maschine im
* Tailnet; der Runner ist ab jetzt ein Node mit `Data.role='runner'`:
*
* Type='node'
* Data.role 'runner' | 'gateway' | 'dev-pc'
* Data.hostname Tailnet-Hostname (TS_HOSTNAME)
* Data.tailnetNodeId / tailnetIp
* Data.mode personal|team|shared (Eigentum, wie bisher beim Runner)
* + runner-spezifisch: publicKey, architecture, operatingSystem,
* capabilities, status, revokedAt
*
* Sichtbarkeit und Eigentum bleiben unverändert: `Links` (`member`/`memberA`)
* und `Visible` wie bei Projekten/Lists/Runnern. Die Companion-Zeile für den
* heißen Zustand ist die generische `Member`-Tabelle (Member-Muster, seit
* 20260926-runner-companion-into-member) — sie ist nur für `role='runner'`
* sinnvoll (Credential-`lookup_key`, Heartbeat) und wird für andere Rollen
* nicht angelegt.
*
* Bestehende Daten:
* - `runner` → `node` + `role='runner'`
* - Links `tailnetRunner` → `tailnetNode` (UID=Netz, UIDTarget=Node)
*
* Enum-Superset bewusst vollständig (Vereinigung aus ausgerollten DBs und dem
* Schema-Snapshot, inkl. bereits entfernter Literale wie `deployment`/`workspace`)
* — ein zu kurzes Enum würde beim MODIFY bestehende Zeilen abschneiden
* („Data truncated"). `system_versioning_alter_history=1` erlaubt das MODIFY
* trotz History-Partitionen mit alten Literalen (Muster aus
* 20260827-tailnet-object-types). 'runner' bleibt im Enum (History/Rollback).
*/
const OBJECTBASE_TYPE_ENUM = [
'account',
'accountingChangeable',
'accountingVisible',
'achievement',
'achievementT',
'action',
'actionT',
'app',
'appAsset',
'appDomain',
'changeable',
'costcenter',
'deployment',
'deploymentEndpoint',
'directoryShare',
'dlist',
'document',
'email',
'entry',
'event',
'eventFunctionT',
'eventJob',
'eventJobT',
'eventT',
'exclude',
'extern',
'family',
'fiscalyear',
'function',
'gentry',
'ggroup',
'group',
'guest',
'historic',
'include',
'intersect',
'job',
'list',
'location',
'locationC',
'locationT',
// Neu: generischer Node (Tailnet-Maschine, Rolle in Data.role)
'node',
'person',
'project',
'repositoryShare',
'runner',
'tailnet',
'user',
'visible',
'workspace',
];
const LINKS_TYPE_ENUM = [
'achievement',
'action',
'actionT',
'admin',
'appAsset',
'appDomain',
'botRepo',
'config',
'deploymentRunner',
'dynamic',
'event',
'family',
'familyFees',
'filter',
'function',
'identifyer',
'list',
'location',
'locationC',
'locationT',
'member',
'member0',
'memberA',
'memberGA',
'memberS',
'memberSys',
'portal_pending',
'projectShare',
// Neu: Node → Netz (verdrängt tailnetRunner; alt bleibt im Enum)
'tailnetNode',
'tailnetRunner',
'transaction',
'transactionLine',
'txReference',
'workspaceLease',
'workspaceRunner',
];
const renderEnum = (values) => values.map((v) => `'${v}'`).join(',');
export const migrate = async ({ query }) => {
await query('SET @@system_versioning_alter_history = 1', []);
await query(
`ALTER TABLE ObjectBase
MODIFY COLUMN \`Type\` enum(${renderEnum(OBJECTBASE_TYPE_ENUM)}) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NOT NULL`,
[],
);
await query(
`ALTER TABLE Links
MODIFY COLUMN \`Type\` enum(${renderEnum(LINKS_TYPE_ENUM)}) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NOT NULL`,
[],
);
await query('SET @@system_versioning_alter_history = 0', []);
// Runner → Node mit Rolle. `COALESCE`/`JSON_SET` auch für (theoretisch)
// leere Data-Spalten; idempotent, weil nur `Type='runner'` betroffen ist.
await query(
`UPDATE ObjectBase
SET \`Type\`='node',
\`Data\`=JSON_SET(COALESCE(\`Data\`, JSON_OBJECT()), '$.role', 'runner')
WHERE \`Type\`='runner'`,
[],
);
// Netz-Link umbenennen (Node → Tailnet).
await query(
`UPDATE Links SET \`Type\`='tailnetNode' WHERE \`Type\`='tailnetRunner'`,
[],
);
};