* Merge expense-approval-bot into payments-dashboard
Port the Slack reaction-driven expense routing workflow (receiver +
processor) from expense-approval-bot into this stack as JavaScript ESM.
Secrets copied to payments-dashboard/ prefix in Secrets Manager.
* Fix review findings from PR #28
- Add length check before timingSafeEqual to prevent RangeError on
malformed signatures (returns 401 instead of 500)
- Check event.type === reaction_added to prevent reaction_removed
from advancing expenses
- Move getPermalink call behind isOrigin check to skip unnecessary
API call on non-origin stage transitions