From 6f4a44e281d190a6f4f60d99f01bd72c99430289 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Guti=C3=A9rrez?= <35082514+alezmad@users.noreply.github.com> Date: Wed, 15 Apr 2026 14:26:48 +0100 Subject: [PATCH] =?UTF-8?q?fix(db):=20realign=20audit=5Flog=20schema=20?= =?UTF-8?q?=E2=80=94=20actor=5Fmember=5Fid,=20prev=5Fhash,=20hash=20chain?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The broker code moved to an append-only hash-chained audit log (actor_member_id / actor_display_name / payload / prev_hash / hash with integer GENERATED ALWAYS AS IDENTITY id) but prod still had the original 0000-migration shape (actor_peer_id / metadata / text id). Every peer_joined / peer_left event logged 'audit log insert failed' — no audit trail captured at all. Applied manually on prod already; committing the migration so future environments converge. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../0021_audit-log-schema-realign.sql | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 packages/db/migrations/0021_audit-log-schema-realign.sql diff --git a/packages/db/migrations/0021_audit-log-schema-realign.sql b/packages/db/migrations/0021_audit-log-schema-realign.sql new file mode 100644 index 0000000..843f810 --- /dev/null +++ b/packages/db/migrations/0021_audit-log-schema-realign.sql @@ -0,0 +1,33 @@ +-- Realign mesh.audit_log to match the current code schema. +-- +-- The schema drifted: code has moved to an append-only hash-chained design +-- (actor_member_id/actor_display_name/payload/prev_hash/hash and an integer +-- GENERATED ALWAYS AS IDENTITY id) but the 0000 migration still shows the +-- old shape (actor_peer_id/target_peer_id/metadata/text id). Every peer +-- join/leave event has been logging "audit log insert failed" since the +-- broker code was updated. +-- +-- Approach: drop the legacy table (no production data is read from it — the +-- old schema was unused after the code rename) and recreate under the new +-- shape. Safe because the broker treats audit-log failures as non-fatal and +-- existing rows were never surfaced via any API. + +-- Guard against partial prior runs. +DROP INDEX IF EXISTS "mesh"."audit_log_mesh_id_idx"; +DROP TABLE IF EXISTS "mesh"."audit_log"; + +CREATE TABLE "mesh"."audit_log" ( + "id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY NOT NULL, + "mesh_id" text NOT NULL, + "event_type" text NOT NULL, + "actor_member_id" text, + "actor_display_name" text, + "payload" jsonb NOT NULL DEFAULT '{}'::jsonb, + "prev_hash" text NOT NULL, + "hash" text NOT NULL, + "created_at" timestamp NOT NULL DEFAULT now(), + CONSTRAINT "audit_log_mesh_id_fk" FOREIGN KEY ("mesh_id") REFERENCES "mesh"."mesh"("id") ON DELETE CASCADE ON UPDATE CASCADE +); + +CREATE INDEX IF NOT EXISTS "audit_log_mesh_id_idx" ON "mesh"."audit_log" ("mesh_id"); +CREATE INDEX IF NOT EXISTS "audit_log_created_at_idx" ON "mesh"."audit_log" ("created_at");