I decided to use L2 MSTP (or RSTP if you like) plus dynamic WDS, and one bridge per router. WDS interfaces are dynamically added to the bridge as in Mesh scenario.
For controlling weights/costs I set wlan5G interface def50 range50-100
For wlan2G I set def200 range100-300
MSTP dynamically updates costs as signal strength changes. STP root ports are dynamically recalculated.
DHCP server, DNS-proxy on """Mesh portal""" main router.
I also set main router's bridge MSTP (STP) Priority to 0x1000. So that it would always be the main router (unless he is gone, then someone with lowest MAC will be elected temporarily).
Reduced MSTP MaxMessageAge(=6s) and ForwardDelay(=4s) to minimum values.
Set bridge AdminMAC to keep local bridge mac constant (for routers local DHCP-client lease).
Then used terminal "export" command and then made script out of that for executing it other routers, for keeping configuration consistent (to avoid typos). The only input needed to change for that in script is router identity friendly name.
So far works well, but I think for this solution I will need to add netwatch-script which would detect if main router is reachable and if it is not, then child routers would go from ap-bridge to station mode until main router is reachable again. Because as for now, the can be case then userdevice connects to strongest WiFi ap, but it doesn't have reachability to main router. This netwatch would allow to avoid that.
Child router's configuration export (annonymized):
# jul/25/2021 11:02:53 by RouterOS 6.48.3
# model = RBcAPGi-5acD2nD
/interface bridge
add arp=proxy-arp forward-delay=4s igmp-snooping=yes igmp-version=3 max-message-age=6s multicast-querier=yes \
name=LanBridge protocol-mode=mstp region-name=Lan vlan-filtering=yes
/interface list
add name=LAN
/interface wireless security-profiles
add authentication-types=wpa2-psk disable-pmkid=yes eap-methods="" management-protection=allowed \
management-protection-key=Shrek2 mode=\
dynamic-keys name=wpa2_Lan supplicant-identity="" wpa2-pre-shared-key=Nun0fUrBus1ness
/interface wireless
set [ find default-name=wlan1 ] ampdu-priorities=0,1,2,3 band=2ghz-onlyn channel-width=20/40mhz-Ce country=\
lithuania disabled=no disconnect-timeout=15s hw-protection-mode=rts-cts installation=indoor mode=ap-bridge \
name=wlan2_2G_Lan security-profile=wpa2_Lan ssid=Lan wds-cost-range=100-300 wds-default-bridge=\
LanBridge wds-default-cost=200 wds-mode=dynamic wireless-protocol=802.11 wmm-support=required wps-mode=\
disabled
/ip hotspot profile
set [ find default=yes ] html-directory=hotspot
/interface bridge port
add bridge=LanBridge interface=wlan2_2G_Lan path-cost=300 priority=0xC0 trusted=yes
add bridge=LanBridge interface=LAN priority=0x40 trusted=yes
/interface bridge settings
set use-ip-firewall=yes use-ip-firewall-for-pppoe=yes use-ip-firewall-for-vlan=yes
/interface list member
add interface=ether1 list=LAN
add interface=wlan2_2G_Lan list=LAN
/ip dhcp-client
add disabled=no interface=LanBridge
/ip dhcp-relay
add add-relay-info=yes dhcp-server=192.168.128.1 disabled=no interface=LanBridge name=relay1 \
relay-info-remote-id=the5.router.lan
/ip dns static
add address=192.168.128.1 name=the1.router.lan
add address=192.168.128.2 name=the2.router.lan
add address=192.168.128.3 name=the3.router.lan
add address=192.168.128.4 name=the4.router.lan
add address=192.168.128.5 name=the5.router.lan
/ip service
set telnet disabled=yes
set ftp disabled=yes
set www disabled=yes
set ssh disabled=yes
set api disabled=yes
set winbox address=192.168.128.0/17
set api-ssl disabled=yes
/routing ospf interface
add cost=100 network-type=broadcast use-bfd=yes
add interface=LanBridge use-bfd=yes
/system clock
set time-zone-name=Europe/Vilnius
/system identity
set name=the5.router.lan
/tool mac-server
set allowed-interface-list=none
/
WMM support probably should set to enabled instead of required...
Non-WDS interfaces to the bridge are added dynamically through interface-list. For (non-WDS) interfaces which needs non-dynamic-default cost or priority, I add them separately to the bridge (while keeping them in interface-list).
What do you think about this solution?