Auburn MyGov Docs Gitea

Overview

System Map

The complete map of Auburn MyGov modules, their responsibilities, and the integration seams between them. This is the entry point for the integration design — all other documents zoom into specific seams described here.

Status Draft
Last updated
Scope Public website modules and their integration points; excludes internal system implementation details

Purpose & Scope

Auburn's public website is not a single application — it is a collection of purpose-built modules (Employees, Facilities, Calendars, Programs, Reservations, eNotifier, Pages) running on a shared platform with shared infrastructure. Each module manages its own domain. The design challenge is not the internal workings of any one module but the seams between them: what data flows where, who initiates it, and how.

This document answers three questions for every integration:

  1. Connection — what links to what, and why?
  2. Direction — which system is the source of truth, and which consumes?
  3. Trigger — is the integration automated, scheduled, manual, or pull-on-demand?

Separately, several external systems sit at the boundary: Microsoft 365 (Exchange resource mailboxes, Entra authentication, Outlook calendars), ESRI / county GIS services, and third-party registration platforms used by Parks and Library. Those boundaries are also mapped here, though the integration design for each is covered in its own document.

Modules

Internal modules are owned by MyGov and managed in the admin portal. External systems are shown with a dashed border — we integrate with them but do not own them.

Pages / CMS

The website content management system. Non-technical staff author pages. Pages reference other modules (contact cards, calendars, program lists) rather than duplicating their data.

Internal
Employees

Staff directory. Maintains the record of truth (HR data) separately from the public-facing contact card (EmployeeContact). A page may surface an employee contact card without exposing the underlying record.

Internal
Facilities

City facilities (buildings, parks, libraries, etc.). Maintains FacilityContact for public display — hours, address, phone — separate from the operational facility record. The physical anchor for Programs, Events, and Reservations.

Internal
Calendars

Municipal calendars for meetings, events, holidays, and programs. Supports parent/child hierarchy so a parent calendar (e.g., "Parks Programs") can aggregate many child calendars. Programs and standalone events both surface here.

Internal
Programs & Registration

Parks and Library program listings. A program has one or more sessions (which are time-bound occurrences), optional registration rules (cost, capacity, deadlines), and a location. Programs push into Calendars for unified time-based views. Registration is internal — the goal is a first-party module that works for both Parks and Library before either department goes live with an external platform. Library is evaluating Vega; Parks may use a separate external system. If a department goes external, integration (not replacement) is the path.

Internal
Facility Spaces & Reservations

Bookable spaces within facilities (rooms, fields, equipment). Maintains FacilitySpaceContact for public display. Reservations carry rules: lead time, padding, occupancy limits. The most greenfield module — not yet in production.

Internal
eNotifier

Mass-mailer and interest list manager. Sends announcements across many content categories: job openings, programs, events, road closures, meeting schedules, press releases. Integrates with other modules either by push (a system event queues a notification) or pull (a user composing a mailer selects content from other modules).

Internal
Workflow Engine (ServerJob)

Automation engine. Triggers actions on a schedule or in response to form submissions. The primary mechanism for cross-module automation — not a user-facing module but the plumbing behind most automated integrations.

Internal / Platform
Microsoft 365

Exchange resource mailboxes (each is a calendar), Entra/Azure for employee authentication, and Outlook calendar feeds. MyGov is the authority for public-facing data; M365 may be the authority for operational room booking depending on integration decisions.

External
ESRI / County GIS

Authoritative spatial data: parcels, addresses, boundaries. MyGov queries these services and/or maintains SQL geometry data internally. Referenced by Facilities, Programs, and Reservations for location data.

External
Parks Registration System

Third-party registration platform used by Parks. Programs that require registration link out via registrationUrl rather than handling registration internally.

External

Integration Seams

Each row is one integration seam: a directional connection between two modules. Direction shows which system is the source → which is the consumer. Trigger describes how the data moves. Detailed design for each seam lives in its own document (linked in the sidebar).

Automated — fires on a system event, no staff action
Manual — staff-initiated action in the UI
Scheduled — runs on a cron/ServerJob schedule
Pull — consumer fetches on demand (e.g., at render time or when composing)
From To What Direction Trigger Mechanism Detail doc
Employees Pages EmployeeContact card surfaced on page → consume Pull Page references EmployeeContact by ID; rendered at display time Contact Surface
Facilities Pages FacilityContact card surfaced on page → consume Pull Page references FacilityContact by ID; rendered at display time Contact Surface
Facility Spaces Pages FacilitySpaceContact surfaced on page → consume Pull Page references FacilitySpaceContact by ID; rendered at display time Contact Surface
Programs Calendars Program sessions appear as calendar entries → push Automated Creating/updating a program session writes to the associated calendar; category → calendar mapping drives which calendar receives it Calendar Aggregation
Reservations Calendars Confirmed reservations block time on a facility calendar → push Automated Reservation confirmation writes a calendar entry (or blocks the Exchange resource mailbox — TBD per Microsoft Ecosystem doc) Reservations
Programs / Calendars eNotifier Content blocks added to a mailer ← pull Pull Staff composing a mailer selects a calendar or program; block inserts recent/upcoming items. A prototyped pattern — preferred over auto-push for this seam. eNotifier
Employees eNotifier Job opening announcements → push Manual Staff publishing a job opening opts to queue an eNotifier announcement; interest list subscribers are notified eNotifier
Programs eNotifier New season / brochure announcements → push Manual Staff publishes a program season and opts to notify subscribers; or staff compose a mailer and pull in program content blocks eNotifier
Facilities / Facility Spaces Location (ESRI / GIS) Spatial location linked to facility record ← pull Pull Facility record stores a spatial reference (parcel ID, address ID, or coordinates); resolved against ESRI / county GIS on display or query Location
Programs / Events Facilities / Facility Spaces Location of a program session or event → reference Pull Program session or calendar event carries a FacilitySpace (or Facility) foreign key; resolved at display time Location
Reservations Facility Spaces Availability and rule enforcement ← pull Pull Reservation request checks FacilitySpace for occupancy, lead time, and padding rules before confirming Reservations
Reservations Microsoft 365 (Exchange) Resource mailbox calendar block → push Automated TBD — confirmed reservation may write to the Exchange resource mailbox for the space, keeping Outlook in sync. Decision pending Microsoft Ecosystem doc. Microsoft Ecosystem
Calendars Microsoft 365 (Outlook) Calendar feed for public/staff subscription → publish Scheduled MyGov calendars publish an iCal/ICS feed; Outlook and other clients subscribe. MyGov is the source of truth — not Exchange. WCAG-compliant web view is the primary citizen surface. Microsoft Ecosystem
Microsoft 365 (Entra) MyGov (all modules) Employee authentication / identity ← pull Automated MyGov admin portal authenticates staff via Azure/Entra SSO. No credentials stored in MyGov. Group/role claims may inform module permissions. Microsoft Ecosystem
Workflow Engine Any module Cross-module automation (schedule or form-response triggered) → orchestrate Automated Scheduled ServerJobs execute on a schedule or in response to citizen form submissions. Used to implement automated integration seams — e.g., sync, notification queuing, status updates — without hard-coding them into module logic. Workflow Engine

Implementation Status — Audit Summary

All design docs audited against codebase as of 2026-06-09. Each module-level doc has a full Audit Findings section. Summary below.

Overall status by module

Module Core entities Integration seams Key gaps Design doc
Employees / EmployeeContact ✓ BUILT ✓ BUILT — SyncUsersDelta, GetUserPhoto Legacy OverrideName/Phone on organization.employee needs migration; EnotifierEmployee is a parallel table Contact Surface
Facilities / FacilityContact ✓ BUILT ⚠ PARTIAL — GIS sync fields exist; sync job not fully audited GIS sync mechanism not confirmed; useType not normalized Location, Contact Surface
FacilitySpaces / FacilitySpaceContact ✓ BUILT ✓ BUILT — Exchange mailbox link on FacilitySpace bookingRules is a JSON blob; typed ReservationConfig with Divisions not yet built Location
Calendars ✓ BUILT (Option A schema) ⚠ PARTIAL — pull + program push built; no on-publish auto-trigger No Option B extension fields (sourceType/sourceId/imageUrl); no parent/child hierarchy; no Reservation→Calendar push Calendar Aggregation
Programs ✓ BUILT ⚠ PARTIAL — sync-calendar built; manual trigger only On-publish auto-trigger missing; Exchange blocking requires FacilitySpace.ExchangeResourceMailbox Calendar Aggregation
Reservations ✓ BUILT ⚠ PARTIAL — Exchange events + GUID cancel + workflow trigger all built Approval flow always confirms immediately; Divisions not built; no CalendarEvent for citizen-facing calendar; no waitlist Reservations
eNotifier ✓ BUILT ⚠ PARTIAL — Events Block pull built; NDR handler built (needs activation) HMAC unsubscribe token security gap; EnotifierEmployee is a parallel table; auto-push hooks not built; hard-coded Parks/Library facilityContactId=16 eNotifier
Workflow Engine ✓ BUILT ✓ BUILT — 20 handlers registered No async/pause state (multi-step approval must be simulated); V1 fields on FormAction not retired; reservation-specific actions not yet defined Workflow Engine
Microsoft 365 N/A (external) ⚠ PARTIAL — read/write Exchange events built; employee sync built; NDR handler built (needs activation) Resource mailbox provisioning not built; Entra group management for portal roles not audited Microsoft Ecosystem
ESRI / GIS N/A (external) ⚠ PARTIAL — Facility/FacilitySpace have geometry columns + GIS ID fields ArcGIS import workflow not fully audited; ArcGisHandler exists in workflow engine but actions not documented Location
Polaris ILS (Library) N/A (external) ✓ BUILT — DragonstoneContext queries Polaris for barcode/patron lookup Used in reservation flow; patron registration query uses raw SQL — should be encapsulated Reservations

Top priority implementation gaps

  1. HMAC unsubscribe tokens — eNotifier security gap. Must be resolved before the public unsubscribe endpoint is promoted.
  2. NDR processing activation — ✓ Done. ServerJob active; processed bounces from first live campaign.
  3. On-publish calendar sync trigger — Program publish should automatically call sync-calendar; currently manual only.
  4. Reservation approval flow — per-space requiresApproval flag; Exchange event should only be created on confirmation, not submit.
  5. CalendarEvent for reservations — confirmed reservations should write a CalendarEvent so they appear on the citizen-facing calendar.
  6. Option B extension fields — add sourceType/sourceId to CalendarEvent; update program sync to populate them.
  7. EnotifierEmployee → unified employee model — EnotifierEmployee is a parallel table; should be a role flag on organization.Employee or EmployeeContact.
  8. Legacy override fields on organization.employee — OverrideName/OverridePhone should migrate to EmployeeContact then be dropped.
  9. EventsBlockModal hard-coding — facilityContactId===16 check needs to be replaced with a theme/department field on Calendar.
  10. Resource mailbox provisioning — admin portal + API action to create new Exchange resource mailboxes via Graph.

Design vs. Audit — Deviation Analysis

The following items represent the largest gaps between the design intent and the current implementation, ranked by long-term impact. These are not bugs — they are known deviations that will compound over time if not addressed.

1. Reservation confirmation is immediate — no approval flow

Severity: High. The design describes a per-space requiresApproval flag and a Pending → Confirmed workflow. The current implementation always sets Status = "Confirmed" immediately on submit and creates the Exchange calendar event before any staff review. This is the single most consequential deviation because:

  • It cannot be corrected after data accumulates — reversing confirmed reservations retroactively is operationally difficult.
  • Exchange events are already created on submit. Removing them if staff later rejects is possible but creates a confusing history.
  • The Workflow Engine's multi-step approval pattern (schedule string mechanism) is already built — the reservation controller just needs to be wired to it. The fix is targeted.

Recommended fix: Add requiresApproval to FacilitySpaceContact. On submit, set status to Pending and skip Exchange event creation. Create the Exchange event only when staff runs StartWorkflow(formResponse, "Status:Approved") via an admin action. The cancel-by-GUID flow and idempotency guard are already in place.

2. EnotifierEmployee is a parallel, unlinked employee table

Severity: Medium-High. eNotifier.EnotifierEmployee is a separate table with no FK to organization.Employee or cms.EmployeeContact. This means:

  • Employee onboarding/offboarding must be done in two places. When someone leaves, they may retain eNotifier access if the parallel table isn't updated.
  • There is no access audit trail connecting eNotifier campaign sends to the Azure AD identity of the sender.
  • As the employee directory grows (more sync fields, role structures), keeping eNotifier in sync becomes increasingly manual.

Recommended fix: Add a permission flag (e.g. canUseEnotifier) to cms.EmployeeContact or a junction table. Migrate eNotifier-specific fields (smsRelayAddress, displayName override) to that record. Retire eNotifier.EnotifierEmployee. Authentication is already Azure AD — the link is the AzureId.

3. CalendarEvent is Option A — no sourceType/sourceId linkage

Severity: Medium. The design calls for CalendarEvents to carry sourceType / sourceId linking back to their originating entity (Program, Reservation, external ICS, etc.). The current schema is pure iCal fields only. This means:

  • A CalendarEvent row has no machine-readable indication of where it came from. Querying "all calendar events for Program 42" requires parsing the uid field convention ("program-session-{id}-{date}") — fragile.
  • When a program is cancelled or rescheduled, finding all associated CalendarEvents requires the same uid prefix parsing.
  • Future sources (reservations, GIS events) will need the same convention, leading to proliferating uid formats.

Recommended fix: Add sourceType (varchar, e.g. "program", "reservation", "ics-feed") and sourceId (int, nullable) to data.CalendarEvent. Populate them during program sync. Index (sourceType, sourceId) for efficient reverse lookups.

4. bookingRules is an untyped JSON blob

Severity: Medium. cms.FacilitySpaceContact.bookingRules is a JSON blob with no schema enforcement. The validator (BookingRulesValidator) reads scalar fields from it, but the structure is not validated against a typed model at the DB or API boundary. As reservation rules grow (Divisions/occupancy tiers, approval config, blackout dates with recurrence), maintaining consistency in an untyped blob becomes increasingly error-prone. A migration to a typed ReservationConfig entity gets harder the more configs are in production.

Recommended fix: Define a typed ReservationConfig class. Keep it as a JSON column for now (EF can project it), but add a JsonSchema or record type that BookingRulesValidator uses. Add API validation on write. Full normalization into a relational entity can wait until the Divisions/approval model is designed.

5. organization.employee is a [Keyless] graph table with legacy fields

Severity: Low-Medium. The [Keyless] EF annotation means no primary key tracking — adds friction to any query that needs to join or update by ID. The graph features ($node_id, edge tables) do not appear to be leveraged in any current code path. The legacy OverrideName / OverridePhone columns duplicate functionality that now lives in EmployeeContact. While not urgent, this creates ongoing confusion: new developers see a graph table and expect graph queries; none exist. Legacy fields on the source table blur the single-responsibility intent of the Entity/Contact split.

Recommended fix: Migrate OverrideName/OverridePhone to EmployeeContact (likely already-populated — just map the data). Drop the columns. The graph table structure can remain if there is a future plan for it; if not, document the intent or migrate to a standard keyed table.

Summary table

DeviationImpactEffort to fixUrgency
Reservation always confirms immediatelyHigh — operational, data integrityMedium (workflow wiring)Before production reservation launch
EnotifierEmployee unlinked from org.EmployeeMedium — security, maintenanceMedium (schema + data migration)Before staff turnover creates orphan access
CalendarEvent no sourceType/sourceIdMedium — query correctness, future-proofingLow (additive migration)Before additional source types added
bookingRules untyped JSON blobMedium — correctness at scaleLow (add typed class, defer normalization)Before Divisions/approval model is built
organization.employee legacy fieldsLow — developer confusion, schema noiseLow (data migration + column drop)Next planned schema cleanup