Skip to content

SmartInventory Web Portal — UI Usage & HTTP API Map

Purpose: Document how the SmartInventory web portal uses its backend, to ground the (already-mapped) smartinventory_qa data model (docs/database/0008) in real application usage. This is a synthesis of (a) a live read-only UI capture of the demo instance, (b) the authoritative .NET source under references/SmartInventory-3.0/Source/, and (c) the DB data-model docs.

Companion docs: docs/database/00-Overview.md08-platform-security-tenancy-catalog.md; docs/SmartInventory_Legacy_Architecture_Study.md. Raw UI capture: references/ui-exploration/ (LIVE_FINDINGS.md, network_*.json, shots/*.png).


1. Scope & caveat

Two distinct things were observed, and they are not the same deployment:

AspectSourceWhat it tells us
Live UIDemo instance http://networkaccess.st.leptonsoftware.com, product v8.16.4.0, admin login, captured via Playwright on 2026-06-16How the product is used and configured — menus, flows, request paths, POST field names. Its layers/data are a small demo set, different from the smartinventory_qa DB.
smartinventory_qa DBLive PostgreSQL 14.8 (~8.8 GB), analyzed in docs/database/The data model (tables, views, fn_* functions) — the real source of business logic. A multi-customer QA mashup (Jio geometry + Safaricom catalogue + a BharatNet postgres_fdw link).
.NET sourcereferences/SmartInventory-3.0/Source/ (the develop-style mainline)The authoritative API surface: 46 web MVC controllers + 29 Admin-area controllers + two OWIN OAuth Web APIs, all calling BL*DA*fn_*.

Live-observed vs code-derived. Section 3 (UI module map) and the request paths in §2/§4 marked “(observed)” were seen live; the full controller/action tables in §4 and the traces in §6 are enumerated from source (so they include endpoints never clicked). Where the trace agent inferred a table name from a .NET return type (e.g. “cable_master”, “connection_info_master”, “network_code_details”), this doc uses the authoritative DB names from docs/database/ instead — the real tables are line_master/point_master/polygon_master, att_details_*, connection_info, att_details_networktickets/ticket_master, entity_additional_attributes. The fn_* names are quoted as found in the DA*.cs source (authoritative).

Caveat on the source clone: AGENTS.md references a GeoSureServices GIS Web API, but that project is not present in this clone — only SmartInventoryServices and IntegrationServices exist here. The clone also lacks compiled output, so action signatures are read from source.


2. App shell & technology

Stack (confirmed from source + live): ASP.NET MVC 5 / Razor (.NET 4.8), jQuery + jQuery UI + jQuery Validation (no SPA framework, no module bundler), System.Web.Optimization bundles, SignalR for realtime, Google Maps JS base layer + MapServer/WMS for feature layers, EF6/Npgsql data access. App is served under a virtual path /Products.

Auth flow (observed + LoginController.cs):

  • GET /Products → login form (fields user_name, password; posts to /Products/).
  • XHR POST /Products/Login/validateuser (checks existence + multi-login) → on success lands on /Products/main (MainController.Index / MapManager).
  • Session is polled by GET /Products/Login/checkSession; logout GET /Products/Login/logout.
  • Multiple auth modes (per AGENTS.md + LoginController): Forms (default, session timeout 120 min), ADFS, Azure AD (Login/AzureadLogin/AzureCode), LDAP, Airtel custom SSO; optional OTP/2FA (Login/ProcessOTP / VerifyOtp). Default route {controller}/{action}/{id} with Login/Index as home (App_Start/RouteConfig.cs).
  • Server-side single-login enforcement lives in Global.asax.cs (Application_AcquireRequestStateBLUser.validateUserLoginHistory, abandons stale sessions).
  • Session keys drive everything downstream: Session["userDetail"], Session["user_id"], Session["ApplicableModuleList"] (the permission/menu set), Session["Language"].

Realtime — SignalR (Startup.cs, Utility/SmartInventoryHub.cs):

  • Hub mapped at /Products/signalr (GET /signalr/negotiate, /signalr/start over WebSockets, /SignalR/hubs); client bundle ~/bundles/NotifySignalR.
  • SmartInventoryHub broadcasts BroadCastInfo(NotificationOutPut) (utilization/upload alerts) and BroadCastUploadStatus(message) (data-upload progress). Notifications also polled via POST /Products/Workforce/GetNotification (observed).

Map rendering (see §5): Google Maps JS provides the basemap (maps.googleapis.com; MapAuthType = KEY or CLIENT); network feature layers are MapServer WMS images over PostGIS views. The client lib is Content/js/googlewms.min.js + mapCore.js (in the ~/bundles/Scripts OSP bundle). At country zoom no GeoJSON XHR fires — WMS tiles load only over data extents.

Bundles (App_Start/BundleConfig.cs) — feature-scoped, version-stamped in production:

  • ~/bundles/Scripts (the big OSP/map bundle: jQuery, googlewms, mapCore, Splicing, SpliceTray, FiberCutTracing, dynamic-attribute serializers, Areas/Admin/.../expressionBuilder.js), ~/css.
  • ~/bundles/ISP/Scripts, ~/ISPSCRIPTS (D3 vertical-cable SVG, room-view/*, equipment-workspace/workspace.js + equipment-builder.js, EquipmentEditor.js), ~/ISPCSS.
  • ~/bundles/NetworkPlanning/Scripts (+ SmartPlanner/SmartPlanner.js, tokml, select2), ~/VizNetworkScripts (vis.js butterfly diagram), ~/bundles/endToEndSchematic/Scripts (D3 dnd-tree).
  • ~/bundles/datauploader, ~/bundles/regionprovincedatauploader, ~/bundles/ExternalDataUploader/Scripts (KML/KMZ via geoxml3), ~/bundles/AdditionalAttributes/Scripts (DynamicForms/*), ~/bundles/Barcode/Scripts, ~/bundles/LandBase.
  • Admin area: ~/bundles/Admincss, ~/bundles/AdminScripts (observed) + Areas/Admin/Content/{css,js} (spectrum color-picker, expression builder).

3. UI module & feature map

3a. Map workspace (/Products/mainMainController)

The default landing surface (screenshot shots/02-dashboard.png, 03-layers-on.png). Layout = a large top toolbar + a left “NETWORK LAYERS” tree + Google Maps canvas.

  • Layer tree is grouped exactly as layer_details + layer_group_mapping dictate, with per-layer visibility / select / edit toggle columns and live feature counts. Observed groups/layers: Transmedia→Cable; Structure1→Pole; Structure→WallMount / Manhole / Central_Office / Building / Tree / Rack / Handhole / Tower; SPAN→Trench / Duct; Equipment→Splitter / CPE / FDP / Cabinet / ATB; plus FDC / CSA_Boundary / SurveyArea / Fault / Sector / DSA_Boundary / Customer / PatchPanel / FAT / SpliceClosure / ROW / CX / Area / Coupler. This is the front-end of the 66-row layer_details registry (docs/database/01).
  • Toolbar capabilities (from the OSP bundle + controllers): geocoder search (Main/GetEntitySearchResult, Google GoogleMap/AddressSearch), draw/place entity, edit geometry (Main/SaveEditGeometry, EditCableTPDetail), measure/distance widget, info/identify (Main/GetEntityInfo), near-by query (Main/GetNearByEntities / GetNearByCables), splicing, fiber-cut tracing, redline markup, print/export, layout (MapLayout/Index), ortho-image raster toggle.

3b. Product modules (which controllers ⇒ which module)

ModuleWeb controllers (this clone)Purpose
SmartInventory (core map/inventory)Main, MapLayout, VectorLayer, GoogleMap, LandBaseLayer, Library (Area/SubArea/DSA/CSA/SurveyArea/Building/Structure/ADB), ISP (HTB/FDB/BDB/CDB/Splitter/Room/Floor/Shaft…), ItemTemplate, Audit, Report, Print, FileDownload, RegionProvince, Multilingual, WorkSpace, RedlinePlace/edit/codify network assets; attribute forms; templates; history/audit; reports.
SmartPlanner / Planning & BOMPlan, SmartPlanner, BOMBOQ, Integration, ProjectManagementAuto network planning (trench→duct→cable→splice), point-to-point, loop mgmt, BOM/BOQ generation & costing, plan→inventory promotion, OSS superset integration.
Connectivity / SplicingSplicing (OSP+CPE+ODF), FiberAllocationTool (FAT auto-splice), FiberCutTracing, CommonPathFinder, WorkSpace (equipment/rack workspace incl. OLT patching)Splice ports, OLT/ODF patching, end-to-end schematic, OTDR fault trace, common-path finder, optical link budget.
SmartOps / WFMWorkforce, TicketManager, NetworkTicket, SurveyArea, RosterManagement, JobPack, KPIMasterJob-order assignment, ticketing (Customer/Network/HPSM), survey assignment & location tracking, rostering/timesheets, job packs, KPI dashboards.
SmartSQ / Feasibility(web entry via Main/Plan; the engine is in IntegrationServices + fn_sf_*)Serviceability / dark-fiber feasibility (pgRouting over existing cable with free cores).
WirelessWireless/Tower, Wireless/Sector, Wireless/Antenna, Wireless/MicrowaveLinkTowers, sectors, antennas, microwave links (RF params).
Data ingestionDataUploader, BulkUpdate, FileUpload (TAB/Shapefile/DXF/KMZ), RegionProvince uploaderExcel/KML upload → temp_du_* staging → validate → commit.
Dashboard / Auth / ErrorDashboard, Login, Error, UnAuthorizedLogin, dashboards, error pages.

3c. Admin / configuration area (/Products/Admin/<Controller>/<Action>)

The configuration surface that administers the data model (screenshots 04-admin.png, adm-layerconfig.png, adm-portstatus.png, adm-vendorspec.png, adm-equipmodels.png, adm-roles.png, adm-rolemodule.png, adm-templates.png, adm-changecode.png). Route prefix Admin/{controller}/{action}/{id}. The left menu (observed) groups 29 controllers; the menu has more sections than the original capture noted — full list: OLT Patching, Users, Dashboard, Layer Settings, Vendor Specification, Rights Management (Roles/Templates), Equipment Builder, Miscellaneous Feature, OSP Settings, Vendor, LandBase Layer Settings, Advanced Settings, API Consumer Master, Accessories, Help & FAQ’s, Project, Link Budget Settings, Application Logs (+ Resources, Email/OTP settings, Dynamic Theme/Form, Backup download, Long-running queries, WFM RCA, Business Layer).

Admin controllerKey actionsDB structure it administers
LayerSettingsViewGroups, ViewLayerGroupsMapping, LayerConfigurationSettings / saveLayerConfigurationSettings, AddLayerDetailSettings/SaveLayerDetail, ShowlayerDetails, ViewLayerStyleMaster/SaveLayerStyleMasterDetailslayer_details (66×114), layer_group_master, layer_group_mapping, layer_style_master (map styling/label expression). Observed form fields: layer_id, layer_title, minzoomlevel, is_mobile_layer, is_visible_in_mobile_lib, is_visible_on_mobile_map.
MiscellaneousViewPortStatus (port-status enum grid: Status, Color Code, Is Active, Is Manual, Is Splicing Allowed, audit), ChangeNetworkCode / getNewNetworkcode / getNetworkIdDependency / SaveChangeNewNetworkcode (re-codification), DropDownMaster (entity dropdown vocab), ViewUtilizationSetting, error/API/GIS logs, FAQport_status (vocab in docs/database/04), codification (fn_get_network_code, entity_network_code_history), dropdown_master, entity_utilization_settings.
VendorSepcification (sic)Add/View/Save/UploadVendorSpecification, ViewSpecificationServices, BindSplitterPortRatio, GetVendorSpecificationHistory, attachment uploadBOQ/costing catalog = item_template_master (Cost Per Unit/meter, Service Cost, Port/Fiber Info, Sub-Category 1–3, A/B/C-RFS flags) per docs/database/02/05.
Equipment (Equipment Builder)CreateModel/SaveModel/SaveModelMapping, ViewModels, ViewModelsImage, CreateRule/SaveRule (parent/child model rules), GetWorkspaceData/GetLibraryData (canvas), model-type/colour/port mgmt, SVG uploadThe Equipment→Chassis→Slot→Card→Port→Tray hierarchy via isp_model_* (isp_model_info, isp_model_mapping, isp_model_rules, isp_model_type_master) — docs/database/04. Model categories observed: Equipment, OLT, ACT FRB, FDP, Nokia OLT, Chassis, Slot, Card, Port, Tray.
UserAddUser/SaveUser, ViewUsers, ViewUsersLoginHistory, BulkUserUpload (→ bulk_user_*, fn_bulk_user_upload_process), region/province/subdistrict/block cascades, UserReportMappinguser_master, user_login_history, user_permission_area, bulk_user_*.
RolesAddRole/SaveRole, ViewRoles, UpdateRoleModule / SaveRoleModuleMapping, service-facility/JO mappingsrole_master, role_module_mapping (module gating), role_permission_entity (per-layer CRUD).
TemplateAddTemplate/SaveTemplate (+ BLRoleRights.SaveRoleRights), ViewTemplatesitem_template_* library + layer_rights_template_permission.
OSPSettingsInfoSettings, SearchSettings, Zoom, labelSettings (+ expressionBuilder), TubeCoreColorSettings, ViewCableMapColorSettingslayer_details info/search/zoom/label columns; cable tube/core colour & map-colour settings (feeds the .map styling).
AdvancedSettingsViewGlobalSettings/SaveGlobalSetting, ModuleSettings, LayerActionSettings, ConnectionLabelSettings/SyncAllLabels, ReportColumnSettings, HistoryColumnSettings, FormInputSettings, VoiceCommandMasterglobal_settings, module_master, connection-label rules, report/history/form column config.
LandbaseSettingslayer/dropdown/search/label settingslandbase_layer_master, landbase_dropdown_master, landbase_layer_columns_settings (docs/database/06).
Configuration / Vendor / Accessories / Projectequipment-type/brand/model masters; vendor master; accessories + entity mapping; project/planning/workorder/purpose codesclassification masters; vendor_master; accessories; project-code masters.
APIConsumerMasterGetAPIConsumer, AddAPIConsumer/SaveAPIConsumerapi_consumer_master (the IntegrationServices clients — note empty-password client finding in docs/database/08).
OpticalLinkBudgetAddLinkBudget/SaveLinkBudget, splitter-losslink-budget tables (drives Splicing/viewlossdetails).
OTPAuthenticationSettings / EmailSettings / DynamicTheme / DynamicFormOTP/email config, theming, dynamic-form builderotp_authentication_configuration, mail settings, dynamic_controls.
BulkUpdateTemplatedata-uploader column settingsdata_uploader_template.
WFMRCAMaster (root-cause vocab)WFM RCA dropdowns.
LongRunningQueries / Downloadbckfile / Resources / BusinessLayer / FeToolskill long queries; DB backup download; multilingual resource mgmt; business-logic layer registry; field-engineer tool allocationops/admin plumbing.
Homeindex, POST getDashboardData (observed), HeaderInfo_Admin, Export_Dashboard_Dataadmin dashboard (active/last-month users).

4. HTTP API surface (the big one)

The external contract the new platform must reckon with is three ASP.NET endpoints: the MVC web app (/Products/..., ~46 web + 29 admin controllers, mostly server-rendered + AJAX JSON), and two OWIN OAuth Web APIs consumed by mobile and third parties.

4a. Web MVC — selected controller → action map (enumerated from source)

All under /Products/{controller}/{action}; verbs are [HttpGet]/[HttpPost] where attributed, else MVC default (GET). Controllers carry [Authorize], [SessionExpire], [HandleException]; Admin adds [AdminOnly]. (Full action lists exist for every controller; representative high-value ones below.)

Auth / shell

ControllerActions (verb)
LoginIndex (GET/POST), validateuser (POST), checkSession (GET), logout (GET), ProcessOTP (POST), VerifyOtp (GET), Azuread/AzureCode (GET)
MainIndex/MapManager (GET), GetEntityInfo (POST), GetEntitySearchResult (GET), getGeometryDetail (POST), GetNearByEntities/GetNearByCables (GET), SaveEditGeometry/UpdateOtherGeometry/EditCableTPDetail (POST), DeleteEntityFromInfo (POST), GetLayerDetail/GetLayerMapping (GET), ValidateEntityGeom/ValidateParentEntityGeom/ValidateLBEntityGeom (GET), ComputeHomePass (POST), getDependentChildElements (GET)
DashboardIndex (GET), HierachyList (GET), DashboardResult (GET), ExportDashboardDataDump (GET)

Inventory / entity CRUD — each entity type has an Add<Entity> (GET form) + Save<Entity> (POST) + Delete<Entity>ById (POST):

ControllerRepresentative actions
LibraryAddArea/SaveArea, AddSubArea/SaveSubArea, AddDSA/SaveDSA, AddCSA/SaveCSA, AddSurveyArea/SaveSurveyArea, AddBuilding/SaveBuilding (+GetBuildingRFSStatus,isValidRFSStatus), AddStructure/SaveStructure, AddADB/SaveADB, GetBarCode, UploadBuildingData
ISPAddHTB/FDB/BDB/CDB/Splitter/Room+Save*+Delete*ById, StructureInfo, FloorInfo/UpdateFloorInfo, ShaftInfo/UpdateShaftInfo, saveWithRiser, getElementTemplate
LandBaseLayerAddLandBase/SaveLandBaselayer, GetLandbaseEntityInfo, BindLandbaseDropdown, GetLBLayerSearchResult, DeleteLandbaseEntityFromInfo
Wireless/*AddTower/SaveTower(+POP association), AddSector/SaveSector, AddAntenna/SaveAntenna(+VSAT), AddMicrowaveLink/SaveMicrowavelink
ItemTemplateIndex, <Entity>Template/Save<Entity>Template, GetVendorList, GetCatSubcatData, GetBrand/GetModel
AuditGetHistory, GetGeometryHistory, GetSiteHistory, GetLMCHistory, GetFiberLinkHistory, GetLandBaseLayerHistory (+ Download/Export each)

Connectivity / splicing

ControllerRepresentative actions
SplicingIndex (GET), CableToCable/CPEToCustomer/ODFToCable (GET forms), SaveConnectionInfo (POST), deleteConnection (POST), GetAvailabePorts (GET), ConnectionPathFinder (GET), SchematicView/GetStreamWiseSchematic (GET), GetEquipmentPortInfo (POST), EntityLogicalView, GetLinkBudgetDetails, UploadConnectionData (POST), viewlossdetails
FiberAllocationToolIndex, GetConnectionDetails, CreateSplicing (POST), ExportTempSplicing, RefreshMessage/DeleteMessage
FiberCutTracingindex, getFiberTracingPath, getFiberCutDetails, getFiberNodeType
CommonPathFinderCommonPathFinder, CustomerFiberLinkPathFinder, getCableListByLinkIds, getCableListByCustomerId
WorkSpaceGetWorkSpace/GetWorkSpaceById (GET), SaveWorkSpace/DeleteWorkSpace (POST) — equipment/rack workspace incl. OLT patching
FiberLinkShowFiberLinkDetails, AddFiberLink/SaveFiberLink, AssociateCustomer, AssociateFiberLinkWithCable, KML/PDF export

Planning / BOM

ControllerRepresentative actions
PlanShowPlanTool/ShowBulkPlanTool, processPlan (GET), Point2PointPlan, GetBomData, SaveProcess (POST → commit plan), GetNetworkForMap, SaveLoop (POST), DeletePlanByPlanId
SmartPlannerroute optimisation / demand / design (large module)
BOMBOQBomBoqReport/Summary/Export, PrintBOMBOQ (POST), BOMBOQView/SaveBOMBOQView (POST), savebomlogic/Validatebomformula (POST), ConstructionBOMDetail, UnlockFSA
IntegrationShowPlannerIntegration, ProcessIntegrationSuperset (POST), GetAllPlans, DeleteProcessedIntegrationSuperset

SmartOps / WFM

ControllerRepresentative actions
WorkforceAssignJobOrder/ViewAssignJobOrder/ViewTTAssignJobOrder (POST), ManagerRouteIssueApprove/SaveRouteIssueStatus/AssingContractorRouteIssue (POST), OpenTicket/Closeticket (POST), ViewNotification, GetNotification (observed POST), route reports
TicketManagerShowTicketManager, AddTicket/SaveTicket (POST), EditTicket/DeleteTicket (POST), GetCustomerByCanId, UploadTicketData, AddHPSMTicket/SaveHPSMTicket (POST)
SurveyAreaSurveyAssignment, SaveAssignedUser (POST), FreezeSurveyarea (POST), BulkApproved (POST), location-tracking & building-survey grids + exports
RosterManagementViewUserTimeSheet, SaveUserTimeSheet (POST), EditUserTimeSheet (POST), DeleteUserTimeSheet (POST)
JobPack / KPIMasterjob-pack create/assign; KPI templates/charts/export

Ingestion / files

ControllerRepresentative actions
DataUploaderUploadFiles (POST), getColumnMappping, SaveMappingTemplate (POST), ValidateData (POST), ProcessData (POST), getUploadSummary, downloadTemplate, GetStatus (SignalR progress)
BulkUpdateUploadData, UploadFile (POST), getUploadSummary, downloadUpdateTemplate
FileUploadUploadOtherFile (POST — TAB/Shapefile/DXF), UploadKMLZFile (POST), external-data list/download, UploadProfileImage
FileDownloadDownloadUploadLogs, DownloadTemplate, checkLogFileExist

4b. SmartInventoryServices — OWIN OAuth Web API (mobile + web client)

  • Token endpoint: POST /tokenOAuth2 Resource-Owner-Password-Credentials (ROPC), opaque Bearer tokens (not JWT). Provider SmartInventoryServices/Providers/OAuthProvider.cs; App_Start/Startup.cs. Token TTL = ApplicationSettings.mobileAppLogoutTimeInSec (configurable); refresh tokens via an in-memory SimpleRefreshTokenProvider. AllowInsecureHttp = true, CORS *. Grant validation supports Forms / ADFS / Azure AD / LDAP / ADO-ID / 2FA, license checks, and a hardcoded master-password bypass (security finding). Route base api/{controller}/{action}/{id} + attribute routes.
  • Representative endpoints (all POST, Bearer-protected, body wrapped in ReqInput):
ControllerEndpointsPurpose
User/SignIn/OTPValidateUser, UserLogout, SaveUserLocation, SaveUser, GetOTP/VerifyOTPauth, self-registration, location ping, 2FA
Main/OfflineGetDropDownItems, GetAllVendorSpecifications, GetAllVendors, GetAllDropdownData, GetAllLayerMapping, GetProvinceDetail, getLegendDetailoffline-first sync of static/config data
VectorLayerGetVectorData, GetVectorDataByGeom, GetVectorDelta, GetVectorDeltaByGeomfetch/sync network layers + delta sync
Building/SurveyAreaGetBulidingInfo, insertbuilding, updatebuildinginfo, updatebuildinggeometry, Checknearbybuilding, SurveyareaInfomobile survey capture
ISP/Library/Splicing/ConnectionEntityOperations, SaveISPDevices, GetDeviceDetails, splicing opsdevice/equipment CRUD (the web Wireless/* controllers call api/Library/EntityOperations)
FE (wfm/mobile/v1.0)getJobList, getTTJobList, UpdateJobOrder, getCustomerDetail, UploadAttachment, UpdateStatus, activatecpe, reschedule, closeTicket (~55)field-engineer WFM app
CRM/Report/GoogleMapAPI (api/mapsapi)ticket queries; export reports; Maps proxy (geocode/reversegeocode/directions/distancematrix/placesearch)CRM, reporting, Google Maps proxy

4c. IntegrationServices — OWIN OAuth Web API (third-party OSS/BSS)

  • Token endpoint: POST /GenerateToken — ROPC bearer; validated against api_consumer_master via BLAPIConsumerMaster.ValidateIntegrationServiceConsumer. Params: base64 username, password, Source (third-party id, required), optional ClientIP, ExpireTime (per-call TTL override; default 86400 s). No 2FA. AllowInsecureHttp=true, CORS *. Provider IntegrationServices/Providers/OAuthProvider.cs; Swagger present.
  • Endpoints (all Bearer-protected; carry a source_ref_type token claim):
Controller (RoutePrefix)EndpointsPurpose
Ticket (api/v1)getAppointmentSlots, reserveAppointmentSlot, createJobOrder/createJobOrdernew, createTTJobOrder, appointmentDetails, cancel/rescheduleAppointmentSlot, cancelJobOrder, updateCpeStatus, updateConnectedDevice, GetStatusDetailByJobOrderIdWFM/BSS appointment & job-order integration
Service (serviceability/v2.0)GetServiceability, GetAPIsettings, UpdateAPIsettingsservice-qualification (GPON NAP availability by lat/lng)
OSSIntegration (api/v1)entityLocation (GET), intermediateEntities (GET), updateAlarmStatus, serviceability, updateDiscoveredEntity, reserveFatPort/releaseFatPort, ontActivationStatusUpdate, entitySearchGIS↔OSS: location lookup, fiber-path trace, FAT/OLT port reserve/release, ONT activation, discovery
Search (api/entity)GetAvailableDevices, UpdatePortStatus, GetFaultTracedevice/port queries, fiber-cut trace
DaFiFeasibility (api/v1)darkFiberFeasibility, feasibilityKML, reserveFeasibilityRoute/releaseFeasibilityRoutedark-fiber routing (SmartSQ)
LocationDelta (api/v1)locationDelta, locations, faultLocation, fttxFeasibilitylocation sync & FTTx feasibility
ProjectSpecification (api/v1)SaveProjectCode/SavePlanningCode/SaveWorkorderCode/SavePurposeCode, GetNetworkTicketSummaryproject-code integration
FiberLink / Distance (v1.0) / Health (api)linkOwnerShip; getnewcustomerdistance/getcustomerdistance; healthlink ownership; customer distance; liveness

The DB exposes a parallel fn_api_* function family (63 functions, docs/database/08) that these API controllers ultimately call (e.g. fn_api_get_fault_location_detail, fn_api_nwt_insert_update_ticket).


5. Map rendering pipeline

Pipeline: Google Maps JS basemap + MapServer WMS overlay images, where each map layer is a PostGIS view (vw_*_map) over the master+att_details tables, styled by attribute expressions and codification status.

  1. Client. Content/js/googlewms.min.js + mapCore.js (OSP bundle) overlay MapServer WMS tiles on the Google base layer, filtered by the layer tree (visibility flags from layer_details) and by user province (%provinceFilter%).
  2. MapServer mapfiles (Source/MapFiles/). The active files are NetworkEntitiesLabel.map / NetworkEntitiesNoLabel.map (~60 LAYER blocks each) plus -Scale2 (200×200, doubled fonts/symbols/widths for high zoom), *Mobile variants, LandBaseEntities*.map (point/polygon/line landbase), OrthoImage.map (raster), Legend.map, jiolayers.map. All share datashare.inc.
  3. Connection. datashare.inc hardcodes a PostGIS connection: CONNECTIONTYPE postgis / CONNECTION "dbname='Smartinventory_qa' host=192.168.1.40 port=5014 user='postgres' password='Lepton@#2022'"a plaintext DB superuser credential committed in the repo (add to the security remediation list).
  4. DATA = PostGIS views. Each LAYER reads a vw_*_map view, e.g. DATA 'sp_geometry FROM "vw_region_boundary_map" USING UNIQUE region_id USING srid=4326', DATA 'sp_centroid FROM vw_att_details_building_MAP USING UNIQUE system_id USING srid=4326', DATA 'center_line_geom FROM vw_att_details_row_map ...'. ~55 distinct vw_att_details_<entity>_map views are referenced (pole, cable, duct, trench, manhole, building, structure, splitter, spliceclosure, ADB/BDB/CDB/FDB, POD/MPOD, FMS, HTB, equipment, rack, cabinet, vault, ONT, customer, fault, area/dsa/csa/subarea/surveyarea/networkticket boundaries, …) — matching the ~60 map views in docs/database/01. These views join <geom>_master ⋈ att_details_<entity> on system_id and compute presentation fields (icon_path, color_code, label_column = network_id, upload_id = db_flag).
  5. Projection / WMS. PROJECTION 'proj=longlat' 'datum=WGS84' (EPSG:4326). WEB.METADATA sets ows_srs 'EPSG:4326', ows_enable_request '*' (so GetMap, GetFeatureInfo, GetCapabilities are all enabled), wms_allow_getmap_without_styles 'true'; output PNG/RGBA. (Note the SRID-0-vs-4326 mismatch from docs/database/01: the views compensate with explicit ST_GeomFromText(...,4326).)
  6. Attribute-driven styling. CLASS/EXPRESSION blocks key off DB columns: ('[network_status]' eq 'P') Planned / 'A' As-built / 'D' Dormant (mapping to icon folders icons/Planned|AsBuild|Dorment/), [entity_category] (Feeder/Distribution/Drop), [pole_type], [building_status], and bind SYMBOL [image_icon] / COLOR [color_code] directly from view columns. VALIDATION/FILTER blocks accept runtime params (provinceFilter, label filters) from the WMS URL — i.e. per-request, per-user scoping without recompiling the mapfile.
  7. GetFeatureInfo / identify. The map identify (“info” tool) is served by GetFeatureInfo against the same views (the mapfile sets TEMPLATE 'fooOnlyForWMSGetFeatureInfo'), but the richer attribute panel in the UI is the MVC path Main/GetEntityInfofn_get_entity_info (§6.3), not raw WMS.
  8. Resources. MapFiles/{conf,fonts,symbols,icons} hold EPSG defs, label fonts (Arial/Segoe/icomoon/flaticon), symbol defs, and ~68 status-categorised entity PNGs.

6. End-to-end traces (UI → Controller → BL → DA → fn_* → tables)

fn_* names are quoted from the DA*.cs source (authoritative). Tables use the authoritative DB names from docs/database/ (the masters are point_master/line_master/polygon_master + att_details_*, not per-entity *_master).

6.1 Login / auth

Login/Index (POST) → BLUser.ValidateUser(user,pwd,type)DAUser.ValidateUser(...)fn_check_user_details → tables user_master (+ user_login_history via BLUserLogin.UpdateLogOutTime, user_permission_area for scope). Reversible-AES password (not hashed) per docs/database/07/08. Files: BusinessLogics/BLUser.cs, DataAccess/DAUser.cs, Controllers/LoginController.cs, Global.asax.cs.

6.2 Load layer features (map)

Layer tree build → BLLayer.GetNetworkLayers(userId,groupId,roleId)DALayer.GetNetworkLayers(...)fn_get_network_layerslayer_details + layer_group_mapping (+ role_permission_entity for per-layer rights). Geometry tiles themselves come via WMS over vw_att_details_*_map (§5), not this call. Files: DataAccess/DALayer.cs. Then per-feature identify → §6.3.

6.3 Open / edit an entity’s attributes (att_details + layer_details-driven form)

Main/GetEntityInfo(systemId,entityType,geomType) (POST) → BLMisc.getEntityInfo(...)DAMisc.getEntityInfo(...)fn_get_entity_info → reads att_details_<entity> ⋈ master, with the form/columns driven by layer_details (layer_form_url, info/search column config) and layer_details_column. Additional/dynamic attributes via DAAdditionalAttributes (→ entity_additional_attributes / other_info jsonb / osp_attribute_* per docs/database/02). GIS crosstab attributes via fn_get_gis_attribute. Files: DataAccess/DAMisc.cs, DataAccess/DAAdditionalAttributes.cs.

6.4 Save / codify an entity (parent via ST_WITHIN + network code)

Library/SaveBuilding (or Save<Entity>) (POST) → BL<Entity>.Save<Entity>(...)DA<Entity>.Save<Entity>(...):

  1. spatial parent resolution — DAGeom.CheckGeomWithinfn_Within (ST_WITHIN), backing the DB’s fn_get_parent_info parent-by-containment logic;
  2. network code — DAMisc.getNetworkCodeDetailsfn_get_network_code + fn_Save_New_Network_Code (writes att_details_<entity>.network_id, formatted via layer_mapping.network_code_format);
  3. persist geometry to point_master/line_master/polygon_master + attributes to att_details_<entity> (source_ref_type='WEB');
  4. refresh map cache — DAMisc.updateGeojsonEntityAttributefn_geojson_update_entity_attribute<entity>_geojson_master. The heavy GIS-design-ID path (fn_auto_codification) is admin/batch, rarely run (docs/database/01). Re-codification UI = Admin Miscellaneous/ChangeNetworkCodefn_get_new_networkcode / fn_save_change_network_codeentity_network_code_history. Files: DataAccess/DAMisc.cs, DataAccess/DAGeom.cs, DataAccess/DACable.cs/DABuilding.cs.

6.5 Splicing / OLT patching

Splicing/SaveConnectionInfo (POST) (or FiberAllocationTool/CreateSplicing, or WorkSpace OLT patching) → BLOSPSplicing / DAOSPSplicing:

  • permission — fn_Check_Splicing_Permission;
  • save — fn_splicing_save_connections (JSON payload) → writes the directed edge table connection_info (source/destination entity_type+system_id+port_no, tray, through-connection);
  • OLT/ODF port statusfn_splicing_update_port_statusisp_port_info.port_status + (via fn_trg_update_core_port_status) flips att_details_cable_info strand status;
  • read/trace — fn_splicing_get_connection, fn_get_schematic_view + fn_get_connection_info_path (the procedural cursor-walk + recursive CTE), fn_get_logical_view, butterfly via fn_get_vis_butterfly_network;
  • FAT auto-splice — fn_fat_generate_splicing (2,895-line geometry-derived splicer) → fat_connection_info → promoted to connection_info;
  • delete — fn_splicing_delete_connection. Files: DataAccess/DAOSPSplicing.cs, DAFATConnection.cs, DAWorkSpace.cs. Tables: connection_info, isp_port_info, att_details_cable_info, att_details_spliceclosure/_splice_tray, isp_model_* (docs/database/04).

6.6 Data upload (datauploader → temp_du_* → fn_uploader_*)

DataUploader/UploadFiles (POST) → create upload_summary job (fn_uploader_getuploadid) → bulk-insert raw rows into temp_du_<entity> (all-VARCHAR staging, named by layer_details.data_upload_table). Column map from data_uploader_template (DataUploader/getColumnMapppingfn_uploader_get_entity_template). DataUploader/ValidateDatafn_uploader_validate_parent_details (+ _validate_point/line/polygon, _check_termination_points) sets is_valid/error_msg in place; fn_uploader_get_invalid_record_count. DataUploader/ProcessDatafn_uploader_insert_<entity> (one per entity) → commits to att_details_<entity> + master (db_flag=upload_id, source_ref_type='DU') + fn_geojson_update_entity_attribute. Results grid via fn_uploader_getuploadlogs. Progress pushed over SignalR (DataUploader/GetStatusSmartInventoryHub.BroadCastUploadStatus). SQL-injection risk in the uploader procs (docs/database/06). Files: Controllers/DataUploaderController.cs, DataAccess/TempUpload/DAUploadSummary.cs, DATempCable.cs, DataAccess/DAMisc.cs; project DataUploader/.

6.7 WFM ticket

TicketManager/SaveTicket (POST, Network_Ticket) → BLTicketManager.SaveTicketDANetworkTicket.SaveNetworkTicketfn_nwt_insert_update_ticket (API path: fn_api_nwt_insert_update_ticket) → att_details_networktickets (+ ticket_status_master, ticket_type_master, ticket_type_role_mapping, ticket_steps_master state machine). Customer tickets → ticket_master; HPSM → hpsm_ticket_master. Entity edits from a ticket → fn_nwt_update_entity_info (writes master + att_details_*). Field execution via Workforce/* and the mobile FE API (getJobList/UpdateJobOrder). docs/database/07 covers the three parallel ticket subsystems. Files: BusinessLogics/BLTicketManager.cs, DataAccess/DANetworkTicket.cs.

6.8 Admin config edits

  • Layer ConfigurationAdmin/LayerSettings/saveLayerConfigurationSettings (+ SaveLayerDetail) → BLLayerMaster.SaveLayerSettingsDALayerMaster.SavelayerSettingDetailsfn_save_layer_settings_detailslayer_details (then ApplicationSettings.InitializeGlobalSettings() reloads). Read = fn_layer_details_column_data / fn_get_layer_setting_details.
  • Vendor Specification (BOQ/costing)Admin/VendorSepcification/SaveVendorSpecificationBLVendorSpecificationDAVendorSpecification (insert/update) + fn_insert/update_specification_service_data; read fn_get_vendor_specification_details, fn_get_allvendor_list. Tables: item_template_master (cost/RFS catalog) + item_template_<entity> + vendor_master. Price-change triggers a notification email.
  • Equipment Builder (model hierarchy)Admin/Equipment/SaveModel+SaveModelMapping+SaveRuleBLISPModelInfoDAisp_model_info / isp_model_mapping / isp_model_rules / isp_model_type_master (the Equipment→Chassis→Slot→Card→Port→Tray parent/child rules). Files: BusinessLogics/Admin/BLVendorSpecification.cs, DataAccess/Admin/DALayerMaster.cs, DataAccess/Admin/DAVendorSpecification.cs, Areas/Admin/Controllers/{LayerSettings,VendorSepcification,Equipment}Controller.cs.

7. How the data model surfaces to users

The web client is essentially a thin renderer over the layer_details registry and the DB stored functions — almost every UI behaviour is config in a table or logic in a fn_*.

  • Config-driven layer/entity model. The left layer tree, every Add/Edit form, the map styling, search, info panel, upload availability, mobile visibility, and report/history columns are all read from layer_details (66 rows × 114 cols — ~80 capability booleans + table/view/URL pointers). Admin → Layer Settings / OSP Settings / Advanced Settings edit those columns; the app dereferences layer_form_url/save_entity_url/layer_table/layer_view at runtime. New entity type ≈ a new layer_details row (plus its att_details_* table) — “config-not-code,” exactly the model the rewrite generalises.
  • Geometry ↔ attribute decoupling. The map shows point_master/line_master/polygon_master (via vw_*_map); the info/edit panel shows the paired att_details_<entity> joined by system_id. Users never see the split — fn_get_entity_info re-joins it.
  • Equipment hierarchy. Equipment Builder exposes the physical Equipment → Chassis → Slot → Card → Port → Tray model (isp_model_*) with parent/child placement rules and port layouts; OLT/ODF/rack are equipment models. This is what makes OLT patching and ISP splicing port-aware.
  • Vendor spec / BOQ. Vendor Specification + Item Templates surface item_template_master/item_template_* as the costing/spec catalogue (cost per unit/metre, service cost, port/fibre info, sub-categories, A/B/C-RFS flags) that pre-fills placement forms and feeds BOM/BOQ.
  • Port-status vocabulary. Miscellaneous → ViewPortStatus exposes the port-status enum (Status, Color Code, Is Active, Is Manual, Is Splicing Allowed) that governs splicing and the att_details_cable_info core-status codes (1=available … 6) used by feasibility/utilization.
  • Codification. Saving an asset auto-generates network_id (fn_get_network_code, parent resolved by ST_WITHIN); Miscellaneous → ChangeNetworkCode re-codes with dependency checks. The hierarchical GIS-design-ID (fn_auto_codification) is a heavier admin/batch path.
  • Connectivity as an explicit graph. Splicing/FAT/OLT-patching write connection_info edges and flip port/strand status — the cleanest graph-shaped structure in the DB (docs/database/04).

8. Implications for the new platform

What a modern web client needs from the new API, vs the current coupling:

  1. A clean, versioned REST/GraphQL contract to replace ~75 server-rendered MVC controllers that return Razor partials + ad-hoc JSON, and the AGENTS-described pattern of controllers calling BL → DA → fn_* directly (logic in 2,210 stored functions). The two OAuth APIs (/token, /GenerateToken) already define the external contract third parties depend on — preserve those semantics (slot/job-order, serviceability, FAT/OLT port reserve, dark-fiber feasibility, ticket/codes) behind a stable façade while re-implementing internals.
  2. Schema-driven entity model as a first-class API, not 80 boolean columns + per-entity tables + per-entity fn_get_template_detail branches. Expose entity-type/attribute-schema metadata (the layer_details + osp_attribute_def idea) so the client renders forms generically.
  3. Drop the MapServer + 60 vw_*_map + 60 geojson-cache dependency for modern vector tiles (single spatial source, GIST-indexed, declared SRID 4326), with attribute-driven styling done client-side from a typed style spec rather than .map EXPRESSION blocks. Remove the plaintext DB superuser credential in datashare.inc.
  4. Connectivity/topology as a native graph API. connection_info maps 1:1 to typed graph edges (port/strand nodes); replace the procedural fn_get_schematic_view cursor-walk with native traversal so schematic / fiber-trace / OTDR / feasibility are real graph queries.
  5. One generic ingestion service (template-driven, parameterised SQL, idempotent, transactional, auto-purged staging) replacing 44 temp_du_* tables + ~45 fn_uploader_insert_* clones; keep the data_uploader_template + upload_summary concepts.
  6. Realtime via a modern channel (the SignalR upload/utilization push is genuinely useful) but decoupled from session/Forms-auth; keep a single, JWT-based identity with real MFA (the current OTP is configured-but-off; ADFS/AAD/LDAP/SSO multiplicity and the hardcoded master-password bypass must go).
  7. First-class multi-tenancy & integrity (the DB has no tenant key, 84 FKs, reversible passwords, a cross-customer postgres_fdw link) — the API must enforce tenant scope, typed keys, and audited codification/connectivity rather than relying on string network_id + ST_WITHIN recomputation.

Status: complete. Live UI capture grounds usage; controller/action/fn_*/table names are source- and DB-doc-derived. Table-name discrepancies between the .NET return-type inference and the authoritative smartinventory_qa schema were reconciled to the DB docs.


Appendix A — Live visual UI walkthrough (captured 2026-06-16)

Screenshots in references/ui-exploration/shots/ (W-main, W-toolbar, W-nelibrary, F-createmodel, F-layerconfig, adm-*, 02-dashboard). The full client action surface (4,081 distinct tooltip/onclick entries) is in references/ui-exploration/TOOL_INVENTORY.txt. All actions live in a single global JS namespace si.* (= SmartInventory), confirming a server-rendered jQuery monolith, not a componentized SPA.

A.1 Map workspace (/Products/main) layout

  • Top blue bar: SMARTINVENTORY logo · centered “Enter a location” geocoder (Google) · a dense ~30-icon command toolbar · notification bell (SignalR count) · workspace/user menu · Admin dropdown (si.getWorkSpaces, si.getChangePassword, si.uploadProfileImage, si.SignOut).
  • Left “NETWORK LAYERS” panel: “Select All” + “Advanced Filters” (si.GetProjecSpeciFilter/ClearProjectSpeciFilter), then a grouped layer tree (groups: Transmedia, Structure1, Structure, SPAN, Equipment, …) — each layer row has toggle columns (visibility / select / edit / label) + a live feature count. Layer rows are driven by layer_details.
  • Map canvas: Google Maps base; feature layers as MapServer WMS image overlays; basemap toggles (si.toggleBaseMap, toggleWhiteMap “No Map”). Bottom status bar: Coordinates · Version · Zoom · Legend.

A.2 The command toolbar — action inventory (grouped by si.* namespace)

  • Create/edit entities: NE Library palette (si.getNeLibrary) with the full entity creation palette (Wall Mount, Pole, PDP, Manhole, Central_Office, Building, Tree, CDB, Handhole, Cable, Trench, Duct, CPE, FDP, Cabinet, ATB, Tower, FDC, CSA/DSA boundary, SurveyArea, Fault, Customer, FAT, Splice Closure, ROW, CX, GX, Coupler, Loop, Patch Cord, GI Pipe, SubArea …); Single vs Group clone (si.GroupClone); Entity Along The Direction (si.entityAlongDirection); Layout auto-draw (si.toggleLayout); Merge Tool for cables (si.MiscellaneousTools.MergeTool); point Buffer (si.EnablePointBufferRadius).
  • Connectivity/splicing: Manual Splicing (splicing.spliceHere), Bulk Splicing (splicing.toggleConnectionUpload), Connection Path Finder (splicing.SinglePathFind) — the live fiber-trace tool over connection_info.
  • Workforce (SmartOps): si.WorkForceManagement.* — Assign / View Assigned / View Unassigned Job Order (+RM/reporting-manager variants), Save/View Roster, WFM Dashboard (+RM), View User Permission Area.
  • Tickets: si.Networkticket.* — Ticket Dashboard, Add Network Ticket, Draw Ticket Area.
  • Redline/markup: si.Redline.* (Point/PolyLine/Polygon + dashboard).
  • Reports (each with draw-area Polygon/Rect/Circle): Entity Export Report, Entity Association Report, Utilization Report, Audit Log Report, Split Report, BOM/BOQ Report (+“FSA-wise overhead logics”), LMC (Last-Mile Connectivity) Report, ROW Report, VSAT Report, GeoTagged Images Report, Potential/homepass (initiateDrawingsPotential), Menu Report. Each has an async export-log companion (*ExportReportLog).
  • Survey & upload: Survey Assignment (Opensurveyassignment), Survey Building (OpenSurveyBuilding), Upload Buildings (si.toggleBuildingUpload), data upload (si.toggleUpload), Bulk Update (si.toggleBulkUpdate), XML Builder dashboard (si.xmlbuilderdashboard).
  • Map/print: Layer Manager (showLayerManager), Print/Export with draw-area (si.togglePrint), search (si.performSearch).
  • Region navigator: a full India province→district tree (~2,544 si.EditRegionProvinceDetails(...,'SHOWONMAP',...) entries — every state & district), used to zoom/scope the map by administrative area (the “circle”/region dimension in UI form).

A.3 Admin / configuration area (/Products/admin/Home/index)

Left-nav modules: OLT Patching · Users · Dashboard · Layer Settings · Vendor Specification · Rights Management · Equipment Builder · Miscellaneous Feature · OSP Settings · Vendor · LandBase Layer Settings · Advanced Settings · API Consumer Master · Accessories · Help & FAQ’s. Key screens observed:

  • Equipment Builder → Create Model: a CAD-style visual grid designer (“Scale: 1M grid = 50 mm”, grid-color palette, Model/Type dropdowns, Create/Save Model) for drawing the Equipment → Chassis → Slot → Card → Port → Tray model — plus View Model / View Model Images. This is how OLT/ODF/rack equipment templates (e.g. “22 Port OLT”, “96 Port ODF”) are authored.
  • Layer Settings → Layer Configuration: edits layer_details — but only exposes 5 fields (Layer Name, Minimum Zoom Level, Is Mobile Layer, Is Visible In Mobile Library, Is Visible On Mobile Map). ⇒ ~75 of the ~80 registry flags are NOT editable in the UI; they’re set at the DB/deployment level. “Config-not-code” is only partially realized for end users — deep entity behavior still requires DB changes (a key driver of per-customer forking).
  • Vendor Specification: the BOQ/costing catalog (Entity Type, Specification, Vendor, Item Code, Cost/unit, Service Cost, Port/Fiber Info, SubCat 1-3, Item Type, Unit, is A/B/C-RFS item).
  • Rights Management: Roles + Role Module Mapping (role × module/layer grid → role_module_mapping).
  • Miscellaneous: Core/Port Status Settings (Status, Color Code, Is Active, Is Manual, Is Splicing Allowed), Change Network Code (codification re-code), Ortho Image, User Activity Log.
  • Users: Add/View User, User Login History, Bulk User Upload, User Tools (FE tools).
  • API Consumer Master: registers third-party IntegrationServices clients (this is where the empty-password API-consumer finding lives).

UI takeaways for the rewrite: (1) the toolbar is an enormous flat set of modal tools driven by one global si.* object — the new UI wants a composable, permissioned action model; (2) entity creation is map-palette + clone-based — preserve, but back it with the typed schema; (3) reports are all “draw area → export + poll log” — a generic async export/job framework replaces ~12 bespoke report tools; (4) the visual Equipment Builder is a genuinely good feature worth re-imagining; (5) the admin UI exposes only a sliver of the config model — the new platform must make the whole entity/attribute schema safely tenant-editable.