How cityssm/sunrise-cms works
1. This is a server-rendered Node/TypeScript application for cemetery management. The primary user-facing domains are cemeteries, burial sites, contracts, funeral homes, work orders, reports, and an admin console. The README confirms the app is intended to run locally or on modest infrastructure, with no separate database server requirement implied by the architecture.
2. The top-level request path is: routes/* define URL groups, handlers/* contain the actual page/action logic, and views/* render EJS templates back to the browser. This is the main architectural boundary: routing, request handling, and presentation are separated into distinct folders per business area.
3. The code is organized by feature rather than by technical layer. Major subsystems include burialSites, cemeteries, contracts, funeralHomes, workOrders, dashboard, reports, admin, print, and api. Each of these has paired GET/POST handler folders, which suggests standard page rendering plus form-action endpoints in the same feature boundary.
4. The data layer lives in database/* and is very granular. Instead of a single ORM-style repository, the app exposes many task-specific functions such as add/update/delete/get/move/restore/backup/cleanup operations for each record type. That indicates a procedural persistence layer where handlers call narrowly scoped database functions directly.
5. Shared business logic is concentrated in helpers/*. These helpers cover authentication, permissions, configuration, caching, database utilities, reports, printing/PDF behavior, images, partial dates, Find a Grave integration, i18n, and domain-specific logic for burial sites, contracts, users, and attachments. This is the main service layer between handlers and persistence.
6. There is a substantial cache subsystem under helpers/cache/* for reference data such as cemeteries, burial site types, contract types, service types, settings, and work order metadata. These caches likely reduce repeated database reads for low-churn configuration tables and are important to the app’s read path.
7. The UI is classic server-side rendering with EJS templates in views/* and static assets in public/*. Client-side behavior is bundled as feature-specific scripts in public/javascripts/*, with matching TypeScript sources. The front end is therefore thin and page-oriented rather than a standalone SPA.
8. Admin functionality is a separate subsystem with its own views, handlers, and client scripts. It manages reference tables, user accounts, permissions, audit logs, settings, fees, database maintenance, and configuration tables. The architecture treats admin data as a distinct control plane from the operational cemetery records.
9. Work orders are a first-class workflow module, not just a note-taking add-on. The work order area includes milestones, workday views, iCal/calendar output, comments, related records, and close/reopen operations. That implies a transactional workflow flow: create work order → attach burial sites/contracts → track milestones/time → close or reopen as needed.
10. Integrations are isolated under integrations/*. The repo includes Consigno Cloud workflow support, Dynamics GP helpers/types, and Ntfy helpers/types. These external service boundaries are used by domain handlers and background tasks rather than being embedded throughout the codebase.
11. There are dedicated background/operational entry points in tasks/* and Windows service scripts at the repo root. There is also a CLI importer under cli/findAGraveMemorialExtractorImport and legacy import utilities in temp/legacyImportFromCsv. This shows the system has operational flows beyond the web UI: scheduled backups, workflow polling, service installation, and data migration/import.
12. Data and file handling is explicit. The data/ folder contains attachments, backups, sessions, and partial configuration files; public-internal/ holds internal images; and several feature areas support attachments and PDFs. This suggests the system’s operational state is partly file-based, with the application coordinating database records and filesystem artifacts.
13. Authentication, authorization, and permissions are centralized. There are shared authentication helpers, a handlers/permissions.ts module, and feature-level behavior changes for read-only vs update/admin users, which is also reflected in the Cypress test suites. Permission checks are therefore a cross-cutting concern applied before handlers execute domain actions.
14. Localization and environment-specific configuration are built in. The app has locales/en and locales/de, plus config helpers, default config, partial configs, and test-specific config files. This makes runtime behavior dependent on environment and locale, but still managed through shared config helpers rather than hardcoded feature logic.
15. Testing is layered: unit tests live in test/, end-to-end browser tests live in cypress/e2e/, and CI workflows cover linting and coverage. The test structure mirrors the feature architecture, which is useful when drawing the system diagram because it validates the same request/handler/database boundaries used in production.
Main entry points: database Database · helpers Helpers · handlers Handlers · integrations Integrations
Components 19
Runtime
Application entry, routing, and server-side rendering
- App entry · Starts the server process and wires the application runtime.
app/app.ts - Routes · Defines request paths and dispatches them into feature handlers.
routes - Handlers · Feature-specific GET/POST page and action handlers.
handlers - Views · Server-rendered page templates and partials for browser responses.
views
Features
Business domains exposed through routes, handlers, and views
- Cemeteries · Core cemetery records and related burial-site navigation.
handlers/cemeteries-get - Burial sites · Burial-site CRUD, search, mapping, GPS capture, and comments.
handlers/burialSites-get - Contracts · Contract records with fees, interments, attachments, related records, and external workflow actions.
handlers/contracts-get - Funeral homes · Funeral-home records and related service lookup.
handlers/funeralHomes-get - Work orders · Work-order lifecycle, milestones, workday views, calendar output, and close/reopen actions.
handlers/workOrders-get - Admin console · Reference tables, users, permissions, settings, audit log, and database maintenance.
handlers/admin-get - Reports · Search and render operational reports from shared report data.
handlers/reports-get - Print output · Printable screen and PDF renderers for records and work orders.
handlers/print-get - API · Small API surface for generated outputs and integrations.
handlers/api-get
Platform
Shared helpers, persistence, integrations, and files
- Helpers · Cross-cutting business logic for auth, permissions, config, caching, reports, printing, and domain utilities.
helpers - Database · Task-specific persistence functions for CRUD, search, lifecycle transitions, maintenance, and audit logging.
database - Caches · In-memory or shared caches for low-churn reference and settings data.
helpers/cache - Integrations · Isolated adapters for Consigno Cloud, Dynamics GP, and Ntfy.
integrations - Files & assets · Attachments, backups, sessions, partial configs, images, and static assets managed alongside the app.
data
Operations
Background jobs, imports, and service management
- Tasks & services · Background tasks, import utilities, and Windows service entry points.
tasks
Connections 22
- App entry → Routes: mounts · Application startup registers route modules.
- Routes → Handlers: dispatches to · URL groups invoke feature GET/POST handlers.
- Handlers → Views: renders · Handlers return EJS pages for browser responses.
- Handlers → Helpers: uses · Request logic depends on shared business helpers.
- Handlers → Database: reads/writes · Handlers call targeted persistence functions directly.
- Helpers → Caches: consults · Helpers use caches for reference data and settings.
- Helpers → Database: supports · Shared utilities wrap or coordinate database behavior.
- Helpers → Integrations: adapts · Shared service logic bridges external workflows and services.
- Helpers → Files & assets: manages · Helpers coordinate attachments, images, PDFs, sessions, and config artifacts.
- Cemeteries → Database: persists · Cemetery handlers create, update, delete, and search cemetery records.
- Burial sites → Database: persists · Burial-site handlers handle maps, GPS, comments, restoration, and search.
- Contracts → Database: persists · Contract handlers manage fees, interments, attachments, transactions, and related contracts.
- Contracts → Integrations: syncs · Contracts can start or inspect external workflows and documents.
- Work orders → Database: persists · Work-order handlers manage milestones, comments, closure, and workday state.
- Work orders → Print output: exports · Work orders produce calendar and printable outputs.
- Admin console → Database: administers · Admin handlers manage reference tables, users, settings, and maintenance actions.
- Admin console → Caches: refreshes · Admin changes update cached reference data.
- Reports → Database: queries · Reports are assembled from report-specific data access.
- Print output → Helpers: formats · Print output relies on PDF, print, and locale helpers.
- API → Helpers: uses · API endpoints reuse shared business and formatting logic.
- Tasks & services → Database: maintains · Background jobs and import/service scripts initialize, back up, clean up, and migrate data.
- Tasks & services → Integrations: polls · Operational tasks support external workflow polling and sync.