How dsnme013/cannda-health works
1. Repository shape
- This is a monorepo with three main parts: a Next.js frontend, a Fastify/Node.js backend API, and a PostgreSQL/PostGIS database with migration and sync scripts.
- The backend is the primary application server; the frontend is a separate client app that talks to it over HTTP.
2. Frontend boundary
- The frontend lives under frontend/src/app using the Next.js App Router.
- Main user-facing flows are:
- homepage/search entry,
- search results,
- clinic detail pages,
- appointment booking pages.
- UI is composed from reusable components such as SearchInterface, FilterPanel, Map, ClinicCard, and AppointmentBooking, with custom hooks for debounce, geolocation, and search state.
3. Backend API boundary
- The backend is organized around route modules: search, clinics, locations, appointments, and sync.
- backend/server.js is the API entry point, and backend/routes/index.js likely wires the route modules together.
- This backend is the single source of truth for provider lookup, availability/booking, and data synchronization operations.
4. Search and discovery subsystem
- Search is split across backend/services/search-engine.js, location-service.js, and utils/distance.js.
- The architecture suggests a hybrid search flow:
- text / full-text lookup in PostgreSQL,
- spatial filtering with PostGIS for radius-based queries,
- ranking or enrichment through service-layer logic.
- The frontend’s search page and map consume these search results to display providers near a location.
5. Geospatial handling
- Location is a first-class concern throughout the system.
- The backend has a dedicated geocoding-service and locations routes, which indicates addresses or user-entered places are converted into coordinates before search.
- PostGIS in PostgreSQL is important here: it supports distance queries, geo-indexing, and provider/radius filtering.
6. Appointment workflow
- Appointment behavior is separated into appointments routes and appointment-service.
- The frontend booking page and booking component likely call these endpoints to fetch availability and create bookings.
- The README mentions virtual and in-person appointments, so the booking layer likely normalizes multiple appointment types behind one API.
7. External data ingestion
- backend/services/alberta-api.js and database/scripts/sync-alberta-data.js show an integration with an external Alberta healthcare data source.
- data-sync.js suggests a controlled import pipeline that pulls external provider data into the local database.
- The sync route exposes this functionality operationally, likely for manual or scheduled refreshes.
8. Persistence and schema management
- Database structure is managed with SQL files under database/migrations plus database/init.sql.
- Seed migrations indicate the database is preloaded with sample or baseline healthcare data.
- database/scripts/migrate.js is the schema-management entry point, making schema changes explicit and versioned.
9. Caching and operational controls
- Redis is configured separately in backend/config/redis.js and used by middleware such as cache.js and rate-limit.js.
- That means expensive search or location queries can be cached, and API traffic can be throttled at the edge of the backend.
- validation.js indicates request payloads are checked before business logic runs.
10. Request/data flow
- A typical user flow is: frontend collects search criteria or location → backend geocodes if needed → backend queries PostgreSQL/PostGIS and possibly Redis → frontend renders provider cards, map markers, and clinic details.
- For booking, the frontend sends appointment requests to the backend → backend validates and processes them through the appointment service → database state is updated.
11. Deployment and runtime packaging
- Both frontend and backend have Dockerfiles, and the repo includes docker-compose.yml, so the system is designed to run as containerized services.
- The top-level scripts/setup.sh and scripts/deploy.sh indicate environment bootstrap and deployment automation around those containers.
12. Architecture takeaway for diagrams
- The key boundaries to draw are:
- browser/client UI,
- backend API,
- PostgreSQL/PostGIS datastore,
- Redis cache,
- external Alberta data source / geocoding provider.
- The most important data flows are search/location lookup, clinic detail retrieval, appointment booking, and external data sync into the local database.
Main entry points: index.js Routes · init.sql Schema · api.js API Client · SearchInterface.jsx Search UI
Components 31
Frontend
Next.js client app
- Home · Homepage and search entry
frontend/src/app/page.js - Search · Search results view
frontend/src/app/search/page.js - Clinic · Clinic detail view
frontend/src/app/clinic/[id]/page.js - Booking · Appointment booking view
frontend/src/app/appointment/page.js - Search UI · Search and filter interface
frontend/src/components/SearchInterface.jsx - Map · Location and marker display
frontend/src/components/Map.jsx - Clinic Card · Provider summary card
frontend/src/components/ClinicCard.jsx - Booking Form · Appointment booking UI
frontend/src/components/AppointmentBooking.jsx - Hooks · Debounce, geolocation, and search state
frontend/src/hooks/useSearch.js - API Client · Frontend calls to backend API
frontend/src/lib/api.js
Backend API
Fastify/Node application server
- Server · Backend API bootstrap
backend/server.js - Routes · Central route registration
backend/routes/index.js - Search API · Search and discovery endpoints
backend/routes/search.js - Clinics API · Clinic detail endpoints
backend/routes/clinics.js - Locations API · Geocoding and location endpoints
backend/routes/locations.js - Appointments API · Availability and booking endpoints
backend/routes/appointments.js - Sync API · Data refresh and import endpoints
backend/routes/sync.js - Search Engine · Text and spatial provider lookup
backend/services/search-engine.js - Location Service · Coordinate lookup and radius queries
backend/services/location-service.js - Geocoding · Address-to-coordinate resolution
backend/services/geocoding-service.js - Booking Service · Appointment normalization and processing
backend/services/appointment-service.js - Data Sync · Import pipeline for external provider data
backend/services/data-sync.js - Alberta API · External healthcare data source adapter
backend/services/alberta-api.js - Middleware · Cache, rate limit, and validation
backend/middleware/cache.js - Config · Database, Redis, and constants
backend/config/database.js
Database
PostgreSQL/PostGIS schema and sync
- Schema · Tables and indexes
database/init.sql - Migrations · Versioned schema changes and seeds
database/migrations/001_create_tables.sql - Migrate Tool · Schema migration runner
database/scripts/migrate.js - Sync Script · External Alberta data import runner
database/scripts/sync-alberta-data.js
Ops
Container and deployment support
- Redis · Caching and rate limiting backend
backend/config/redis.js - Client Apps · Users interacting with the frontend
Connections 38
- Client Apps → Home: uses · Users start at the homepage or search entry
- Home → Search UI: renders · Homepage composes the main search interface
- Search → Search UI: renders · Search page uses the search interface
- Search → Map: renders · Search results show map and nearby providers
- Search → Clinic Card: lists · Search results are summarized as clinic cards
- Clinic → Clinic Card: renders · Clinic page reuses provider presentation
- Booking → Booking Form: renders · Booking page centers on appointment form
- Search UI → Hooks: uses · Search UI relies on state and geolocation hooks
- Map → API Client: fetches · Map loads providers and locations through the API client
- Search UI → API Client: calls · Search submissions are sent to the backend
- Clinic Card → API Client: calls · Clinic detail data comes from API requests
- Booking Form → API Client: calls · Booking actions are sent to the backend
- API Client → Server: HTTP · Frontend talks to the backend API over HTTP
- Server → Routes: registers · Server bootstraps the route tree
- Routes → Search API: includes · Search endpoints are mounted
- Routes → Clinics API: includes · Clinic endpoints are mounted
- Routes → Locations API: includes · Location and geocoding endpoints are mounted
- Routes → Appointments API: includes · Appointment endpoints are mounted
- Routes → Sync API: includes · Sync endpoints are mounted
- Search API → Search Engine: uses · Search route delegates provider lookup
- Search API → Location Service: uses · Search route uses location-aware filtering
- Locations API → Geocoding: uses · Location route resolves user-entered places
- Appointments API → Booking Service: uses · Booking route delegates appointment logic
- Sync API → Data Sync: uses · Sync route triggers import pipeline
- Data Sync → Alberta API: fetches · External provider data is pulled from Alberta source
- Search Engine → Schema: queries · Search uses PostgreSQL/PostGIS data
- Location Service → Schema: queries · Location lookups use the datastore
- Booking Service → Schema: updates · Bookings update persistent appointment state
- Geocoding → Schema: reads · Geocoding and provider lookup share stored location data
- Search Engine → Redis: caches · Search results can be cached
- Middleware → Redis: uses · Cache and rate-limit controls rely on Redis
- Server → Middleware: applies · Middleware wraps incoming requests
- Migrations → Schema: builds · Migrations create and evolve the schema
- Migrate Tool → Migrations: runs · Migration runner applies SQL files
- Sync Script → Data Sync: invokes · Script reuses sync pipeline logic
- Sync Script → Schema: loads · Imported data is persisted to the database
- Config → Schema: configures · Database connection settings support schema access
- Config → Redis: configures · Redis connection settings support cache access