feat(triggers): surface name on the Trigger model (§4.5, step B-1)

Read the new `name` column through the data model: `Trigger`/`TriggerRow`
carry it, every trigger SELECT/RETURNING includes it, and the row→Trigger
assembly + the interactive create paths populate it (the create INSERTs
still omit it, so they take the migration's default). Behavior unchanged
— the apply diff still keys on the semantic tuple; B-2 switches it to
name-keying (enabling Update) and wires the manifest.

Tested: manager-core lib 367 + trigger journeys green; clippy clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-06-23 21:17:52 +02:00
parent 816f143ffd
commit 73c8c289c1
3 changed files with 38 additions and 11 deletions

View File

@@ -1445,7 +1445,13 @@ fn disabled_target_warnings(bundle: &Bundle) -> Vec<String> {
if r.enabled && disabled.contains(r.script.as_str()) {
out.push(format!(
"route `{}` is enabled but its script `{}` is disabled — it will 404",
route_key(r.method.as_deref(), r.host_kind, &r.host, r.path_kind, &r.path),
route_key(
r.method.as_deref(),
r.host_kind,
&r.host,
r.path_kind,
&r.path
),
r.script
));
}
@@ -1919,6 +1925,7 @@ mod tests {
id: TriggerId::from(uuid::Uuid::new_v4()),
app_id: AppId::from(uuid::Uuid::nil()),
script_id,
name: "t".into(),
kind,
enabled: true,
dispatch_mode: TriggerDispatchMode::Async,

View File

@@ -34,6 +34,8 @@ pub struct Trigger {
pub id: TriggerId,
pub app_id: AppId,
pub script_id: ScriptId,
/// §4.5 per-app trigger identifier; the manifest merge/upsert key.
pub name: String,
pub kind: TriggerKind,
pub enabled: bool,
pub dispatch_mode: TriggerDispatchMode,
@@ -735,7 +737,7 @@ impl TriggerRepo for PostgresTriggerRepo {
retry_max_attempts, retry_backoff, retry_base_ms, \
registered_by_principal \
) VALUES ($1, $2, 'kv', TRUE, $3, $4, $5, $6, $7) \
RETURNING id, app_id, script_id, kind, enabled, dispatch_mode, \
RETURNING id, app_id, script_id, name, kind, enabled, dispatch_mode, \
retry_max_attempts, retry_backoff, retry_base_ms, \
registered_by_principal, created_at, updated_at",
)
@@ -766,6 +768,7 @@ impl TriggerRepo for PostgresTriggerRepo {
id: parent.id.into(),
app_id: parent.app_id.into(),
script_id: parent.script_id.into(),
name: parent.name.clone(),
kind: TriggerKind::Kv,
enabled: parent.enabled,
dispatch_mode: dispatch_from_str(&parent.dispatch_mode),
@@ -800,7 +803,7 @@ impl TriggerRepo for PostgresTriggerRepo {
retry_max_attempts, retry_backoff, retry_base_ms, \
registered_by_principal \
) VALUES ($1, $2, 'docs', TRUE, $3, $4, $5, $6, $7) \
RETURNING id, app_id, script_id, kind, enabled, dispatch_mode, \
RETURNING id, app_id, script_id, name, kind, enabled, dispatch_mode, \
retry_max_attempts, retry_backoff, retry_base_ms, \
registered_by_principal, created_at, updated_at",
)
@@ -831,6 +834,7 @@ impl TriggerRepo for PostgresTriggerRepo {
id: parent.id.into(),
app_id: parent.app_id.into(),
script_id: parent.script_id.into(),
name: parent.name.clone(),
kind: TriggerKind::Docs,
enabled: parent.enabled,
dispatch_mode: dispatch_from_str(&parent.dispatch_mode),
@@ -863,7 +867,7 @@ impl TriggerRepo for PostgresTriggerRepo {
retry_max_attempts, retry_backoff, retry_base_ms, \
registered_by_principal \
) VALUES ($1, $2, 'dead_letter', TRUE, 'async', 1, 'constant', 0, $3) \
RETURNING id, app_id, script_id, kind, enabled, dispatch_mode, \
RETURNING id, app_id, script_id, name, kind, enabled, dispatch_mode, \
retry_max_attempts, retry_backoff, retry_base_ms, \
registered_by_principal, created_at, updated_at",
)
@@ -891,6 +895,7 @@ impl TriggerRepo for PostgresTriggerRepo {
id: parent.id.into(),
app_id: parent.app_id.into(),
script_id: parent.script_id.into(),
name: parent.name.clone(),
kind: TriggerKind::DeadLetter,
enabled: parent.enabled,
dispatch_mode: dispatch_from_str(&parent.dispatch_mode),
@@ -927,7 +932,7 @@ impl TriggerRepo for PostgresTriggerRepo {
retry_max_attempts, retry_backoff, retry_base_ms, \
registered_by_principal \
) VALUES ($1, $2, 'cron', TRUE, $3, $4, $5, $6, $7) \
RETURNING id, app_id, script_id, kind, enabled, dispatch_mode, \
RETURNING id, app_id, script_id, name, kind, enabled, dispatch_mode, \
retry_max_attempts, retry_backoff, retry_base_ms, \
registered_by_principal, created_at, updated_at",
)
@@ -957,6 +962,7 @@ impl TriggerRepo for PostgresTriggerRepo {
id: parent.id.into(),
app_id: parent.app_id.into(),
script_id: parent.script_id.into(),
name: parent.name.clone(),
kind: TriggerKind::Cron,
enabled: parent.enabled,
dispatch_mode: dispatch_from_str(&parent.dispatch_mode),
@@ -992,7 +998,7 @@ impl TriggerRepo for PostgresTriggerRepo {
retry_max_attempts, retry_backoff, retry_base_ms, \
registered_by_principal \
) VALUES ($1, $2, 'files', TRUE, $3, $4, $5, $6, $7) \
RETURNING id, app_id, script_id, kind, enabled, dispatch_mode, \
RETURNING id, app_id, script_id, name, kind, enabled, dispatch_mode, \
retry_max_attempts, retry_backoff, retry_base_ms, \
registered_by_principal, created_at, updated_at",
)
@@ -1023,6 +1029,7 @@ impl TriggerRepo for PostgresTriggerRepo {
id: parent.id.into(),
app_id: parent.app_id.into(),
script_id: parent.script_id.into(),
name: parent.name.clone(),
kind: TriggerKind::Files,
enabled: parent.enabled,
dispatch_mode: dispatch_from_str(&parent.dispatch_mode),
@@ -1056,7 +1063,7 @@ impl TriggerRepo for PostgresTriggerRepo {
retry_max_attempts, retry_backoff, retry_base_ms, \
registered_by_principal \
) VALUES ($1, $2, 'pubsub', TRUE, $3, $4, $5, $6, $7) \
RETURNING id, app_id, script_id, kind, enabled, dispatch_mode, \
RETURNING id, app_id, script_id, name, kind, enabled, dispatch_mode, \
retry_max_attempts, retry_backoff, retry_base_ms, \
registered_by_principal, created_at, updated_at",
)
@@ -1084,6 +1091,7 @@ impl TriggerRepo for PostgresTriggerRepo {
id: parent.id.into(),
app_id: parent.app_id.into(),
script_id: parent.script_id.into(),
name: parent.name.clone(),
kind: TriggerKind::Pubsub,
enabled: parent.enabled,
dispatch_mode: dispatch_from_str(&parent.dispatch_mode),
@@ -1116,7 +1124,7 @@ impl TriggerRepo for PostgresTriggerRepo {
retry_max_attempts, retry_backoff, retry_base_ms, \
registered_by_principal \
) VALUES ($1, $2, 'email', TRUE, 'async', 3, 'exponential', 1000, $3) \
RETURNING id, app_id, script_id, kind, enabled, dispatch_mode, \
RETURNING id, app_id, script_id, name, kind, enabled, dispatch_mode, \
retry_max_attempts, retry_backoff, retry_base_ms, \
registered_by_principal, created_at, updated_at",
)
@@ -1143,6 +1151,7 @@ impl TriggerRepo for PostgresTriggerRepo {
id: parent.id.into(),
app_id: parent.app_id.into(),
script_id: parent.script_id.into(),
name: parent.name.clone(),
kind: TriggerKind::Email,
enabled: parent.enabled,
dispatch_mode: dispatch_from_str(&parent.dispatch_mode),
@@ -1185,7 +1194,7 @@ impl TriggerRepo for PostgresTriggerRepo {
async fn list_for_app(&self, app_id: AppId) -> Result<Vec<Trigger>, TriggerRepoError> {
let parents: Vec<TriggerRow> = sqlx::query_as(
"SELECT id, app_id, script_id, kind, enabled, dispatch_mode, \
"SELECT id, app_id, script_id, name, kind, enabled, dispatch_mode, \
retry_max_attempts, retry_backoff, retry_base_ms, \
registered_by_principal, created_at, updated_at \
FROM triggers WHERE app_id = $1 ORDER BY created_at DESC",
@@ -1213,7 +1222,7 @@ impl TriggerRepo for PostgresTriggerRepo {
async fn get(&self, id: TriggerId) -> Result<Option<Trigger>, TriggerRepoError> {
let parent: Option<TriggerRow> = sqlx::query_as(
"SELECT id, app_id, script_id, kind, enabled, dispatch_mode, \
"SELECT id, app_id, script_id, name, kind, enabled, dispatch_mode, \
retry_max_attempts, retry_backoff, retry_base_ms, \
registered_by_principal, created_at, updated_at \
FROM triggers WHERE id = $1",
@@ -1463,7 +1472,7 @@ impl TriggerRepo for PostgresTriggerRepo {
retry_max_attempts, retry_backoff, retry_base_ms, \
registered_by_principal \
) VALUES ($1, $2, 'queue', TRUE, $3, $4, $5, $6, $7) \
RETURNING id, app_id, script_id, kind, enabled, dispatch_mode, \
RETURNING id, app_id, script_id, name, kind, enabled, dispatch_mode, \
retry_max_attempts, retry_backoff, retry_base_ms, \
registered_by_principal, created_at, updated_at",
)
@@ -1494,6 +1503,7 @@ impl TriggerRepo for PostgresTriggerRepo {
id: parent.id.into(),
app_id: parent.app_id.into(),
script_id: parent.script_id.into(),
name: parent.name.clone(),
kind: TriggerKind::Queue,
enabled: parent.enabled,
dispatch_mode: dispatch_from_str(&parent.dispatch_mode),
@@ -1700,6 +1710,7 @@ async fn hydrate_one(pool: &PgPool, parent: TriggerRow) -> Result<Trigger, Trigg
id: parent.id.into(),
app_id: parent.app_id.into(),
script_id: parent.script_id.into(),
name: parent.name,
kind,
enabled: parent.enabled,
dispatch_mode: dispatch_from_str(&parent.dispatch_mode),
@@ -1742,6 +1753,7 @@ struct TriggerRow {
id: Uuid,
app_id: Uuid,
script_id: Uuid,
name: String,
kind: String,
enabled: bool,
dispatch_mode: String,

View File

@@ -892,6 +892,7 @@ mod tests {
id,
app_id,
script_id: req.script_id,
name: "mock".into(),
kind: crate::trigger_repo::TriggerKind::Kv,
enabled: true,
dispatch_mode: req.dispatch_mode,
@@ -920,6 +921,7 @@ mod tests {
id,
app_id,
script_id: req.script_id,
name: "mock".into(),
kind: crate::trigger_repo::TriggerKind::Docs,
enabled: true,
dispatch_mode: req.dispatch_mode,
@@ -948,6 +950,7 @@ mod tests {
id,
app_id,
script_id: req.script_id,
name: "mock".into(),
kind: crate::trigger_repo::TriggerKind::DeadLetter,
enabled: true,
dispatch_mode: TriggerDispatchMode::Async,
@@ -977,6 +980,7 @@ mod tests {
id,
app_id,
script_id: req.script_id,
name: "mock".into(),
kind: TriggerKind::Email,
enabled: true,
dispatch_mode: TriggerDispatchMode::Async,
@@ -1021,6 +1025,7 @@ mod tests {
id,
app_id,
script_id: req.script_id,
name: "mock".into(),
kind: crate::trigger_repo::TriggerKind::Cron,
enabled: true,
dispatch_mode: req.dispatch_mode,
@@ -1050,6 +1055,7 @@ mod tests {
id,
app_id,
script_id: req.script_id,
name: "mock".into(),
kind: crate::trigger_repo::TriggerKind::Files,
enabled: true,
dispatch_mode: req.dispatch_mode,
@@ -1078,6 +1084,7 @@ mod tests {
id,
app_id,
script_id: req.script_id,
name: "mock".into(),
kind: crate::trigger_repo::TriggerKind::Pubsub,
enabled: true,
dispatch_mode: req.dispatch_mode,
@@ -1154,6 +1161,7 @@ mod tests {
id,
app_id,
script_id: req.script_id,
name: "mock".into(),
kind: TriggerKind::Queue,
enabled: true,
dispatch_mode: req.dispatch_mode,