Context
Belo Horizonte has an intense, decentralized cultural scene: street fairs, independent shows, neighborhood meetups, and events that rarely reach the big aggregators. Mapa dos Rolezinhos was born with two goals that reinforce each other — solve a real problem in the city and serve as a complete technical lab, from database to interface, built and maintained by one person.
Problem
Information about these events is ephemeral and fragmented. It circulates in stories that vanish in 24 hours and in closed groups, so anyone outside the right circle finds out about the event after it is over. And there is no spatial view: none of those sources answer the question “what is happening near me?”.
User
Two profiles drive the product decisions. The visitor wants frictionless discovery: open the map, see what is nearby, and save what looks interesting — without creating an account. The curator (admin role) needs to create, fix, and remove events quickly to keep the map trustworthy. At this stage, publishing is centralized in curation on purpose: trust in the content matters as much as the interface.
Stack
- JavaScript — a framework-less SPA; the domain (map, list, forms) did not justify an extra layer.
- Leaflet + OpenStreetMap — map rendering, markers, and popups over open tiles.
- Firebase — Firestore as the dynamic database and Authentication protecting the admin panel.
- localStorage — favorites persisted in the browser itself, with no backend.
Architecture
The frontend is a static SPA that talks directly to Firebase, with no server of its own. Leaflet renders the map and markers from the events read from Firestore, so new content reaches the public without a rebuild or redeploy. Browser geolocation brings the map closer to the user’s area — always as an optional enhancement, never a requirement. The admin panel is an authenticated area of the same application, running full CRUD on the events collection. Favorites live on the device only.
Features
- Interactive map with markers and details for each event.
- “Near me”: geolocation through the browser API to explore the current area.
- Favorites saved in the browser, available on future visits without login.
- Admin panel with full CRUD for events (create, edit, delete).
- Dynamic data: the map reflects the production database without a new deploy.
Technical decisions
- Leaflet/OpenStreetMap instead of Google Maps. No billing key or usage limits while the idea is being validated, and full control over look and behavior. The cost is giving up extras such as Places — which the product does not need.
- Firebase instead of a custom backend. For a solo project, removing the server, the ORM, and API deployment shortens the path to a working product. Vendor coupling is a conscious trade-off, acceptable at the validation stage.
- SPA without a framework. Driving the DOM directly keeps the bundle small and forced me to solve code organization, state, and rendering without ready-made abstractions — exactly the kind of fundamentals frameworks hide.
- Favorites without accounts. Storing favorites in localStorage removes signup friction and avoids holding visitors’ personal data. The limitation — favorites do not sync across devices — is deliberate and documented for later.
Security
The core principle: in a client-side application, the interface is not a security boundary. The Firebase configuration exposed in the bundle is not a secret — what protects the data are the Firestore rules, which treat every write as a privileged operation: public read access only for the event catalog, writes only for the authenticated curation user. The panel sits behind Firebase Authentication, and the visitor/admin split also shrinks the data surface: visitors never create accounts, and their favorites never leave the device.
Lessons learned
- Security in serverless apps is about rules and data-model design — hiding the admin button protects nothing.
- Maps on mobile are a problem of their own: gestures, popups, and marker volume demand UX and performance decisions that desktop forgives.
- In Firestore, modeling around the queries (rather than the “ideal” relational model) avoids painful migrations.
- Shipping early, even with manual curation, produces a kind of feedback no amount of planning replaces.
Next steps
- Community event submissions, with a moderation queue before publishing.
- Category and date filters directly on the map.
- PWA evolution: installability and offline reading of already-loaded content.
- Event pages with shareable links, so an event can travel beyond the map.