Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/openstatusHQ/openstatus. ๐ซ Status page with uptime monitoring & API monitoring as code ๐ซ openstatus.dev
bun drizzle-orm monitoring monitoring-as-code nextjs observability on-call open-source shadcn-ui status-page statuspage synthetic-monitoring tinybird turso uptime uptime-checker uptime-monitor
Something went wrong. Try again.
3.8 kB ยท 121 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122import { and, desc, eq } from "@openstatus/db";import { integration } from "@openstatus/db/src/schema";
import { emitAudit } from "../audit";import { requireScope } from "../auth";import { type ServiceContext, withTransaction } from "../context";import { InternalServiceError, NotFoundError } from "../errors";import { type InstallSlackAgentInput, InstallSlackAgentInputSchema,} from "./schemas";import { snapshotIntegration } from "./snapshot";
const SLACK_AGENT_NAME = "slack-agent";
/** * Upsert the workspace's Slack agent integration after a successful OAuth * callback. Emits `integration.create` on first install, `integration.update` * on reinstall (token rotation, re-scoping, bot change). Bot tokens never * enter the audit log โ a SHA-256 fingerprint is recorded instead so * rotations are still visible in `changed_fields`. */export async function installSlackAgent(args: { ctx: ServiceContext; input: InstallSlackAgentInput;}) { const { ctx } = args; requireScope(ctx, "write"); const input = InstallSlackAgentInputSchema.parse(args.input);
return withTransaction(ctx, async (tx) => { // The DB has no `UNIQUE (workspace_id, name)` constraint, so a race // or legacy data could leave more than one `slack-agent` row for a // workspace. Use `.all()` + ordered pick instead of `.get()` so we // (a) deterministically operate on the most recent row and (b) clean // up any older siblings in the same transaction. This is the // service-level enforcement of the "one per workspace" invariant. const existingRows = await tx .select() .from(integration) .where( and( eq(integration.name, SLACK_AGENT_NAME), eq(integration.workspaceId, ctx.workspace.id), ), ) .orderBy(desc(integration.id)) .all();
const [existing, ...stale] = existingRows;
if (stale.length > 0) { console.warn("found duplicate slack-agent rows; consolidating", { workspaceId: ctx.workspace.id, keepId: existing?.id, dropIds: stale.map((r) => r.id), }); for (const row of stale) { const [deleted] = await tx .delete(integration) .where(eq(integration.id, row.id)) .returning(); if (deleted) { await emitAudit(tx, ctx, { action: "integration.delete", entityType: "integration", entityId: deleted.id, before: await snapshotIntegration(deleted), }); } } }
if (existing) { const [updated] = await tx .update(integration) .set({ externalId: input.externalId, credential: input.credential, data: input.data, updatedAt: new Date(), }) .where(eq(integration.id, existing.id)) .returning(); if (!updated) throw new NotFoundError("integration", existing.id);
await emitAudit(tx, ctx, { action: "integration.update", entityType: "integration", entityId: updated.id, before: await snapshotIntegration(existing), after: await snapshotIntegration(updated), }); return updated; }
const [created] = await tx .insert(integration) .values({ name: SLACK_AGENT_NAME, workspaceId: ctx.workspace.id, externalId: input.externalId, credential: input.credential, data: input.data, }) .returning(); if (!created) { throw new InternalServiceError( "Failed to insert slack-agent integration", ); }
await emitAudit(tx, ctx, { action: "integration.create", entityType: "integration", entityId: created.id, after: await snapshotIntegration(created), }); return created; });}