DEV Community

Atul Srivastava
Atul Srivastava

Posted on

Building BloomNest: A Full-Stack Childcare Management Platform with Angular 18 & Appwrite

Childcare centers run on spreadsheets, WhatsApp messages, and paper forms. I wanted to see if I could replace all of that with a single web app. The result is BloomNest — a full-stack management platform for nurseries and kindergartens.

🔗 Live demo: https://bloomnest-mu.vercel.app/
📦 GitHub: https://github.com/atul0016/BloomNest


What it does

BloomNest handles everything a childcare facility needs day-to-day:

  • Child enrollment — profiles, groups, allergies, parent linkage
  • Staff management — roles, status tracking, CRUD operations
  • Smart scheduling — weekly grid, shift blueprints, conflict detection
  • Time tracking — clock in/out, daily logs, monthly summaries
  • Absence management — request/approve workflow with calendar view
  • Analytics dashboard — charts for attendance trends and staff coverage
  • Parent portal — view-only access to their own child's data
  • Push notifications — real-time alerts via Firebase Cloud Messaging
  • Dark mode — because obviously

Five distinct role dashboards: Admin, Board, Manager, Educator, and Parent — each seeing only what they need.


Tech stack

Layer Choice Why
Frontend Angular 18 (standalone components) Strong typing, scalable architecture
UI Bootstrap 5.3 + Bootstrap Icons Fast, consistent layout
Charts Chart.js 4.4 Lightweight, flexible
Database + Auth storage Appwrite Cloud Real-time subscriptions, file storage, easy SDK
Authentication Firebase Auth Reliable, free tier, easy social login
Push notifications Firebase Cloud Messaging Battle-tested for web push
Hosting Vercel Zero-config Angular deploys

Angular 18's standalone components (no NgModule) made the folder structure much cleaner. Lazy loading each feature module kept the initial bundle small.


The interesting architectural decisions

1. Splitting auth between Firebase and Appwrite

Firebase handles identity (sign-in, password reset, token). Appwrite handles everything else — user profiles, role assignments, all app data. The two talk through a thin service layer that keeps the rest of the app unaware of which provider does what.

This sounds like it adds complexity, but in practice it meant I could swap either provider independently. Firebase Auth's email verification flow is excellent; Appwrite's database permissions model is excellent. Both together = best of both worlds.

2. Role-based routing without a library

Rather than pulling in a full RBAC library, I implemented guard-based routing using Angular's CanActivate. Each route declares which roles can access it. A RoleGuard checks the current user's role from a service and redirects if unauthorized.

Simple, type-safe, zero extra dependencies.

3. Shift blueprints for scheduling efficiency

Managers spend a lot of time building the same weekly schedule. I added "shift blueprints" — reusable shift templates that can be applied to any week with one click. It stores the pattern, not the instances, so changing a blueprint does not retroactively alter past schedules.

4. Real-time updates without polling

Appwrite's real-time subscriptions push changes instantly to connected clients. When an admin approves an absence request, the educator's view updates without a page refresh. The subscription teardown on ngOnDestroy prevents memory leaks.


Challenges

Appwrite permissions model — Appwrite uses document-level permissions. Getting role-based read/write to work correctly (especially for the parent portal's read-only access to child documents) required careful collection design. I ended up using server-side functions for anything sensitive.

Chart.js with live data — Chart.js does not automatically re-render when Angular's change detection runs. I had to call chart.update() manually after data changes, which meant tracking chart instances across components.

Angular 18 signals — I started using Angular signals for reactive state in a few components. The mental model is cleaner than RxJS for simple derived values (computed()), but integrating signals with Appwrite's observable SDK took some bridging work.


Demo accounts

You can log in and explore any role:

Role Email Password
Admin aria.thornewood@bloomnest.app admin123
Manager caspian.drake@bloomnest.app manager123
Educator elara.finch@bloomnest.app educator123
Parent diana.whitmore@bloomnest.app parent123

What's next

  • Export reports to PDF/Excel
  • Mobile app (Ionic + Capacitor, same Angular codebase)
  • Multi-facility support (one account, multiple locations)

If you're building with Angular 18 or Appwrite and have questions about any of the patterns above, drop them in the comments. Happy to go deeper on any section.

Top comments (0)