Design for replay
Things will go wrong downstream after a message has already moved. The question is whether fixing it means re-running one message or re-extracting a whole day’s feed by hand. Build every flow so that reprocessing from the bus is the normal answer.
Replayability is a direct consequence of normalizing onto the bus. Because the canonical message is published and persisted before any delivery happens, the bus holds a clean point to resume from. Fix the broken send port, the bad map, or the downed endpoint, and re-publish the affected messages — no re-pull from the source, no manual reconstruction.
What breaks replay is hidden, irreversible work. A component that delivers and mutates external state in one motion has no clean resume point; replaying it would double-apply. Keep side effects on the send side where they are idempotent or compensable (see idempotent by design), and the replay stays safe.