Plant Operations Dashboard – Technical Details
Back to DemoHigh-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.jscoordinates summary metrics and map rendering;orders.js,inventory.js, andshipments.jshandle CRUD tables and form interactions. - API communication: Shared
PortfolioApi.routes.fiberconstants 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.jssends 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/fiberand require[Authorize(Policy = "Authenticated")]. - Routes:
/orders,/materials,/shipments, and/dashboard/statsexpose 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
ProblemDetailsfor 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, andIFiberDashboardServiceseparate domain operations. - Business rules: Services enforce current-user presence, create/update timestamps, required fields, partial update behavior, and not-found/conflict semantics.
- Dashboard aggregation:
FiberDashboardServicecomputes 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
DbContextusage.
Data Access Layer
- Repository pattern: Fiber repositories isolate EF Core querying,
AsNoTrackingread paths, updates, andSaveChangesAsync. - 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
SaveChangesAsyncper 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?