For the 1. you can use the rule above.
For the 2. you can use CI_COMMIT_MESSAGE =~ /^Merged .../ which is usually in format Merged branch into ... (see in your commits) and $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
The issue/confusion is that gitlab does not trigger a CI pipeline when details of a merge request are updated.
So even though the CI is configured with '$CI_PIPELINE_SOURCE == "merge_request_event"' no CI pipeline will be triggered if the title, description, labels, approval status, etc. of the merge request changes.
The only time when the $CI_PIPELINE_SOURCE is merge_request_event is if there are commits pushed to the source branch in the merge request.
It is possible to use the $CI_MERGE_REQUEST_APPROVED in the ci rules, although it is not that useful as the following conditions have to be met:
Your merge request has to be approved.
Your ci job or workflow rules have to enable merge request events. (- if: $CI_PIPELINE_SOURCE == "merge_request_event")
You have to push a new commit to the source branch.
You have to make sure that the merge request approvals are kept when new commits are added in the repo settings (Settings > Merge requests > When a commit is added: Keep approvals).
Otherwise the approval status will get reset each time a new commit is added and you will never catch the $CI_MERGE_REQUEST_APPROVED variable.
With that being said, it is actually possible to run a pipeline immediately after a merge request gets approved.
Gitlab can fire a webhook when a merge request is approved or updated and it is possible to use that webhook to start a ci job with a pipeline trigger token.
First you have to create a pipeline trigger token. (Settings > CI/CD > Pipeline trigger tokens)
Then you need to create the webhook. (Settings > Webhooks).
Set the URL to your pipeline trigger token, without the ref part.