Project
One engine behind five live maps
Mapify runs wine cellar, wine festival, castle, mountain trail and restaurant maps from one codebase. They range from 19 castles to 419 restaurants.
Why I built it
Wine cellar open days publish their cellars as a long numbered list of names, addresses and phone numbers, which is hard to plan a day from. I wanted them on a map, where I could filter them, plan a route and mark the ones I had visited.
The same need came back for castles, mountain trail points and restaurants, so it became one engine.
Adding a map
A new map needs its data, a config file and a hosting entry. It needs no new app code, and the config holds the real differences.
The wine cellar data comes from the organiser's published lists, geocoded into coordinates.






Map imagery by Google.
Key decisions
Each map decides how to treat closed places. The restaurant map hides them by default, while the castle map keeps them, because Google Places often reports ruins as permanently closed.
Map data is read-only for clients. Firestore rules deny client writes to maps and points, and validate the fields on user data.
A planned route belongs to its map. The selection is saved per map, so it survives a reload and does not leak into another map.
What went wrong
About half of the Google Places updates were lost. Google leaves out optional fields on some places, and those undefined values made Firestore writes fail without anyone noticing. The writes now ignore undefined properties.
Visited counts included points no longer on the map. The progress tracker and profile stats counted old interactions. They now count only points that are still on the map.
Where it is now
It has 94 automated tests.
Ionic React, TypeScript, Firebase, Google Maps