From 3ab916bf7552093d2664d307eaf663afae754d1a Mon Sep 17 00:00:00 2001 From: chriscrosstalk <49691103+chriscrosstalk@users.noreply.github.com> Date: Sat, 18 Jul 2026 11:06:57 -0500 Subject: [PATCH] chore(catalog): sunset orphaned Meshtastic Daemon card (#1049) Meshtastic Daemon was pulled from DEFAULT_SERVICES because it can't work without hands-on setup (radio MAC address, etc.). The seeder never deletes, so every early-access deployment keeps an orphaned nomad_meshtasticd row and still shows the broken card. Migration mirrors the legacy-Kolibri sunset: drop the row where installed=0, flag is_deprecated where installed=1 (keeps it manageable, hides from catalog). Runs automatically on each box's next update. Co-authored-by: Claude Opus 4.8 (1M context) --- .../1776400000001_sunset_meshtastic_daemon.ts | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 admin/database/migrations/1776400000001_sunset_meshtastic_daemon.ts diff --git a/admin/database/migrations/1776400000001_sunset_meshtastic_daemon.ts b/admin/database/migrations/1776400000001_sunset_meshtastic_daemon.ts new file mode 100644 index 0000000..276469e --- /dev/null +++ b/admin/database/migrations/1776400000001_sunset_meshtastic_daemon.ts @@ -0,0 +1,37 @@ +import { BaseSchema } from '@adonisjs/lucid/schema' +import { SERVICE_NAMES } from '../../constants/service_names.js' + +export default class extends BaseSchema { + protected tableName = 'services' + + async up() { + // Sunset the Meshtastic Daemon catalog entry. It was removed from the seeder's DEFAULT_SERVICES + // because it can't work without hands-on setup (the user's radio MAC address, etc.), so leaving + // the card in the catalog only offers a broken install. The seeder is additive + sync-existing + // and never deletes, so every deployment seeded while it was in the catalog (all early-access + // boxes) keeps an orphaned `nomad_meshtasticd` row and still shows the non-functional card. + // Mirror the legacy-Kolibri sunset; the `is_deprecated` column already exists from that migration. + this.defer(async (db) => { + // Never installed → just an orphaned catalog row; drop it outright so the card disappears. + await db + .from(this.tableName) + .where('service_name', SERVICE_NAMES.MESHTASTICD) + .where('installed', false) + .delete() + + // Currently installed (rare) → keep the row so it stays Nomad's handle to stop/uninstall the + // container, but flag it deprecated: it drops out of the catalog (see SystemService.getServices) + // and shows a "Legacy" badge. Honors the "we don't remove pre-installed apps" policy. + await db + .from(this.tableName) + .where('service_name', SERVICE_NAMES.MESHTASTICD) + .where('installed', true) + .update({ is_deprecated: true }) + }) + } + + async down() { + // The orphaned-row deletion is a one-way data change and is not restored here. The is_deprecated + // column is owned by the legacy-Kolibri migration, so there is nothing schema-level to revert. + } +}