refactor(approvals): persist title+options on channel/sender approval tables
getAskQuestionRender used to hardcode the card title and option labels
for pending_channel_approvals and pending_sender_approvals in the
DB-access layer, duplicating wording that already lived in the approval
modules. That caused a visible drift between the initial card title —
picked per event in channel-approval.ts ("📣 Bot mentioned in new chat"
vs. "💬 New direct message") — and the post-click render, which
always showed the constant "📣 Channel registration".
Mirror the pattern already used by pending_approvals: add title /
options_json columns on both pending_*_approvals tables via migration
013, have the approval modules write them at creation time, and let
getAskQuestionRender just SELECT.
- Migration 013 ALTERs the two tables to add title + options_json.
- PendingChannelApproval / PendingSenderApproval types and their
create functions grow the two fields.
- channel-approval.ts / sender-approval.ts normalize options once
and pass both title and options_json into the insert.
- getAskQuestionRender drops the hardcoded render objects and reads
the stored values.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -120,6 +120,7 @@ export async function requestChannelApproval(input: RequestChannelApprovalInput)
|
||||
: senderName
|
||||
? `${senderName} DM'd your agent on ${originChannelType}. Wire it to ${target.name} and let it respond?`
|
||||
: `Someone DM'd your agent on ${originChannelType}. Wire it to ${target.name} and let it respond?`;
|
||||
const options = normalizeOptions(APPROVAL_OPTIONS);
|
||||
|
||||
createPendingChannelApproval({
|
||||
messaging_group_id: messagingGroupId,
|
||||
@@ -127,6 +128,8 @@ export async function requestChannelApproval(input: RequestChannelApprovalInput)
|
||||
original_message: JSON.stringify(event),
|
||||
approver_user_id: delivery.userId,
|
||||
created_at: new Date().toISOString(),
|
||||
title,
|
||||
options_json: JSON.stringify(options),
|
||||
});
|
||||
|
||||
const adapter = getDeliveryAdapter();
|
||||
@@ -151,7 +154,7 @@ export async function requestChannelApproval(input: RequestChannelApprovalInput)
|
||||
questionId: messagingGroupId,
|
||||
title,
|
||||
question,
|
||||
options: normalizeOptions(APPROVAL_OPTIONS),
|
||||
options,
|
||||
}),
|
||||
);
|
||||
log.info('Channel registration card delivered', {
|
||||
|
||||
@@ -17,6 +17,10 @@ export interface PendingChannelApproval {
|
||||
original_message: string;
|
||||
approver_user_id: string;
|
||||
created_at: string;
|
||||
/** Card title shown at creation and re-used by getAskQuestionRender on click. */
|
||||
title: string;
|
||||
/** Normalized options (JSON-encoded NormalizedOption[]) — same shape persisted on pending_approvals. */
|
||||
options_json: string;
|
||||
}
|
||||
|
||||
export function createPendingChannelApproval(row: PendingChannelApproval): void {
|
||||
@@ -24,11 +28,11 @@ export function createPendingChannelApproval(row: PendingChannelApproval): void
|
||||
.prepare(
|
||||
`INSERT INTO pending_channel_approvals (
|
||||
messaging_group_id, agent_group_id, original_message,
|
||||
approver_user_id, created_at
|
||||
approver_user_id, created_at, title, options_json
|
||||
)
|
||||
VALUES (
|
||||
@messaging_group_id, @agent_group_id, @original_message,
|
||||
@approver_user_id, @created_at
|
||||
@approver_user_id, @created_at, @title, @options_json
|
||||
)`,
|
||||
)
|
||||
.run(row);
|
||||
|
||||
@@ -19,6 +19,10 @@ export interface PendingSenderApproval {
|
||||
original_message: string;
|
||||
approver_user_id: string;
|
||||
created_at: string;
|
||||
/** Card title shown at creation and re-used by getAskQuestionRender on click. */
|
||||
title: string;
|
||||
/** Normalized options (JSON-encoded NormalizedOption[]) — same shape persisted on pending_approvals. */
|
||||
options_json: string;
|
||||
}
|
||||
|
||||
export function createPendingSenderApproval(row: PendingSenderApproval): void {
|
||||
@@ -26,11 +30,13 @@ export function createPendingSenderApproval(row: PendingSenderApproval): void {
|
||||
.prepare(
|
||||
`INSERT INTO pending_sender_approvals (
|
||||
id, messaging_group_id, agent_group_id, sender_identity,
|
||||
sender_name, original_message, approver_user_id, created_at
|
||||
sender_name, original_message, approver_user_id, created_at,
|
||||
title, options_json
|
||||
)
|
||||
VALUES (
|
||||
@id, @messaging_group_id, @agent_group_id, @sender_identity,
|
||||
@sender_name, @original_message, @approver_user_id, @created_at
|
||||
@sender_name, @original_message, @approver_user_id, @created_at,
|
||||
@title, @options_json
|
||||
)`,
|
||||
)
|
||||
.run(row);
|
||||
|
||||
@@ -92,6 +92,7 @@ export async function requestSenderApproval(input: RequestSenderApprovalInput):
|
||||
|
||||
const title = '👤 New sender';
|
||||
const question = `${senderDisplay} wants to talk to your agent in ${originName}. Allow?`;
|
||||
const options = normalizeOptions(APPROVAL_OPTIONS);
|
||||
|
||||
createPendingSenderApproval({
|
||||
id: approvalId,
|
||||
@@ -102,6 +103,8 @@ export async function requestSenderApproval(input: RequestSenderApprovalInput):
|
||||
original_message: JSON.stringify(event),
|
||||
approver_user_id: target.userId,
|
||||
created_at: new Date().toISOString(),
|
||||
title,
|
||||
options_json: JSON.stringify(options),
|
||||
});
|
||||
|
||||
const adapter = getDeliveryAdapter();
|
||||
@@ -126,7 +129,7 @@ export async function requestSenderApproval(input: RequestSenderApprovalInput):
|
||||
questionId: approvalId,
|
||||
title,
|
||||
question,
|
||||
options: APPROVAL_OPTIONS,
|
||||
options,
|
||||
}),
|
||||
);
|
||||
log.info('Unknown-sender approval card delivered', {
|
||||
|
||||
Reference in New Issue
Block a user