package notificationstore import ( "context" "database/sql" "time" pgtable "galaxy/notification/internal/adapters/postgres/jet/notification/table" ) // deadLetterRow stores the column values written to one dead_letters row. // Kept package-private because the public surface is the routestate // CompleteRouteDeadLetterInput shape; this struct is only the on-disk // projection. type deadLetterRow struct { NotificationID string RouteID string Channel string RecipientRef string FinalAttemptCount int MaxAttempts int FailureClassification string FailureMessage string RecoveryHint string CreatedAt time.Time } // insertDeadLetter writes one dead-letter audit row inside an open // transaction. The composite PRIMARY KEY guards against duplicate inserts // for the same `(notification_id, route_id)` pair. func insertDeadLetter(ctx context.Context, tx *sql.Tx, row deadLetterRow) error { stmt := pgtable.DeadLetters.INSERT( pgtable.DeadLetters.NotificationID, pgtable.DeadLetters.RouteID, pgtable.DeadLetters.Channel, pgtable.DeadLetters.RecipientRef, pgtable.DeadLetters.FinalAttemptCount, pgtable.DeadLetters.MaxAttempts, pgtable.DeadLetters.FailureClassification, pgtable.DeadLetters.FailureMessage, pgtable.DeadLetters.RecoveryHint, pgtable.DeadLetters.CreatedAt, ).VALUES( row.NotificationID, row.RouteID, row.Channel, row.RecipientRef, row.FinalAttemptCount, row.MaxAttempts, row.FailureClassification, row.FailureMessage, row.RecoveryHint, row.CreatedAt.UTC(), ) query, args := stmt.Sql() if _, err := tx.ExecContext(ctx, query, args...); err != nil { return err } return nil }