Plant Operations Dashboard – Technical Details

Back to Demo

High-Level System Overview

  • Purpose: Manage fiber plant operations across orders, materials, shipments, clients, and dashboard metrics.
  • Business problem: Consolidates operational workflows and KPI visibility that would otherwise be split across spreadsheets, inventory logs, and shipment tracking tools.
  • Architecture: Razor Page dashboard → modular JavaScript managers → authenticated versioned fiber APIs → services → repositories → PostgreSQL via EF Core.
  • Technologies: .NET 10, Razor Pages, Bootstrap, DataTables.js, ArcGIS JavaScript SDK, EF Core/Npgsql, Google OAuth cookie authentication.
  • Deployment model: Hosted with the Portfolio application on Render and designed for containerized deployment through Docker and Kubernetes manifests.

Frontend Architecture

The dashboard is a Razor Page enhanced with focused JavaScript files under wwwroot/js/PlantOperationsDashboard. Each module owns a bounded UI concern: map/dashboard summary, orders, inventory/materials, or shipments.

  • JavaScript organization: dashboard.js coordinates summary metrics and map rendering; orders.js, inventory.js, and shipments.js handle CRUD tables and form interactions.
  • API communication: Shared PortfolioApi.routes.fiber constants provide consistent versioned URLs for orders, materials, shipments, and dashboard stats.
  • State management: DataTables and page-local module state manage loaded records, selected rows, and refresh behavior after mutations.
  • Authentication handling: api-fetch.js sends cookies and redirects 401 API responses to Google login with a return URL.
  • UX decisions: Summary cards, status badges, toast notifications, and tabular grids support operational scanning rather than long-form record editing.

API Layer

  • Controllers: Fiber APIs are versioned under /api/v1/fiber and require [Authorize(Policy = "Authenticated")].
  • Routes: /orders, /materials, /shipments, and /dashboard/stats expose CRUD and aggregate dashboard data.
  • Authorization flow: Cookie authentication protects the endpoints; services resolve the current user through IUserProfileService.GetCurrentUserId().
  • Request validation: Controllers perform minimal shape checks and delegate domain validation, user scoping, timestamps, and defaulting to services.
  • Error handling: Controllers translate expected not-found and validation cases where implemented and return ProblemDetails for unexpected server errors.
  • API design: DTOs are used at every boundary so EF Core entities do not leak to the client.

Services and Business Logic

  • Service boundaries: IFiberOrderService, IFiberMaterialService, IFiberShipmentService, IFiberClientService, and IFiberDashboardService separate domain operations.
  • Business rules: Services enforce current-user presence, create/update timestamps, required fields, partial update behavior, and not-found/conflict semantics.
  • Dashboard aggregation: FiberDashboardService computes MTD revenue, open orders, active shipments, low-stock alerts, orders by status, top clients, and inventory by category.
  • External integration: Shipment location fields are visualized by the ArcGIS JavaScript SDK in the browser; backend services provide the operational shipment data.
  • Dependency injection: Each service and repository is scoped, matching ASP.NET Core request lifetimes and EF Core DbContext usage.

Data Access Layer

  • Repository pattern: Fiber repositories isolate EF Core querying, AsNoTracking read paths, updates, and SaveChangesAsync.
  • Database: PostgreSQL is accessed through EF Core/Npgsql with entity mappings in Portfolio.Repositories/Mappings.
  • User scoping: Per-user operational data is filtered by owner/user id inside repository predicates rather than in the browser.
  • Query optimization: Dashboard metrics aggregate from repository-provided domain collections; future growth would push heavier aggregations into optimized SQL, materialized views, or read models.
  • Transaction handling: Simple CRUD writes call SaveChangesAsync per operation; no distributed transaction is required for the current workflows.

Infrastructure and Deployment

  • Hosting: Render runs the ASP.NET Core app with PostgreSQL configuration supplied through environment variables.
  • Secrets management: Google OAuth and database credentials are externalized; Kubernetes secret manifests contain placeholders only.
  • Shared Redis infrastructure: Plant operations data is persisted in PostgreSQL, while Redis is available to the host application for geocoding caches, batch job state, and production Data Protection keys.
  • Containerization: Docker supports repeatable application packaging; Docker Compose adds Redis for local distributed infrastructure parity.
  • Kubernetes: Manifests define namespace, config map, secret, deployment, service, Redis, and HPA for a scalable container platform target.
  • Reliability considerations: Stateless API replicas plus shared database/cache services support horizontal scale; future production hardening would add managed Redis, managed PostgreSQL, health checks, and centralized telemetry.

Engineering Decisions and Tradeoffs

  • Classic layered architecture: Clear service/repository boundaries make the domain easy to test and explain, but can add boilerplate compared with vertical-slice endpoints.
  • Server-side aggregates: Keeps KPI logic authoritative, but may require read-model optimization if operational volume grows.
  • Razor Pages plus JavaScript: Avoids SPA complexity while still supporting rich dashboard behavior; a large enterprise dashboard might eventually justify a dedicated frontend app.
  • Future improvements: Add audit-event persistence, optimistic concurrency, outbox events for inventory changes, real-time updates with SignalR, and warehouse-specific access control.

Interview Discussion Points

  • How would you redesign dashboard metrics for millions of orders and shipments?
  • Where should transactional consistency matter most: inventory, shipments, orders, or revenue recognition?
  • How would you implement multi-tenant authorization and per-warehouse access boundaries?
  • What belongs in OLTP tables versus read-optimized projections or materialized views?
  • How would you add real-time operational updates without overloading the database?