NAPA Portal

Network Analytics & Planning Assistant · POC Demo
OR
Quick demo logins (no password)
Salman Hossain · salman.h@edotco.com
Admin
Ilya Rahim · ilya.r@edotco.com
EDOTCO Admin
Harith Liyanagamage · harith.l@edotco.com
Commercial
Fardin Nasir · fardin.n@bs-23.com
KAM
Aisha Tan · analyst.a@edotco.com
Analyst
📋 Dev Notes
All 32 acceptance criteria · API endpoints · Data sources

Each screen, chart, KPI, and table in this mock has inline dev notes (click i icons or use the toggle button). This panel summarizes the full implementation blueprint.

§1 Vector Tile Map — 6 criteria

1.1 2D map render, warm <3s
GET /v1/map/tiles/{z}/{x}/{y}.mvt · cached · 1.2M features · MapLibre GL
1.2 2D map render, cold <8s
CDN purge → ST_AsMVT on cold cache · 8s p95
1.3 Multi-layer ≥4 layers, no freeze
Single MVT layer, multiple tables · clustering via MapLibre clustering
1.4 Millions of points, no crash, pan/zoom <1.5s
postgis.sites (14K) + coverage_points (1.2M) · hash partition by state_id · GIST index
1.5 Tile API latency <300ms warm
Redis 1h cache · CDN 24h · p95 200ms
1.6 15 concurrent users (30 stretch)
k6 load test · 1 app VM = 200 concurrent

§2 Dashboards — 4 criteria

2.1 Load cached <2s
GET /v1/dashboards/{id}/widgets/{wid}/data · Redis 5min TTL
2.2 Load uncached <5s
Materialized views (mv_market_share_4g, mv_mno_sites, mv_coverage_trend, mv_top_states)
2.3 Drill-down <1.5s
GET /v1/dashboards/{id}/drill?level=state&parent=...
2.4 Widget config persists
PUT /v1/dashboards/{id}/layout · postgis.user_widget_config (JSONB)

§3 ETL & Lineage — 5 criteria

3.1 Scheduled run, no manual
Airflow 2.7 · DAGs: coverage_ingest, sites_master_ingest · cron */6h
3.2 Bad data quarantined
Great Expectations · etl_rules table · postgis.etl_quarantine
3.3 Retry on transient failure
Airflow retries=3, retry_delay=5min · S3 connection timeout auto-recovery
3.4 Lineage visible in UI
OpenLineage events → Marquez → ReactFlow DAG visualization
3.5 Publish → frontend, no manual
PostgreSQL NOTIFY frontend_refresh channel · WebSocket push to map

§4 Polygon Export — 3 criteria

4.1 Reference query match
Independent ST_Intersects query · count + geometry hash match
4.2 Multi-format output
CSV, XLSX (openpyxl), GeoJSON, KML (simplekml) · ZIP bundle
4.3 Export <30s for large AOI
BullMQ job queue · 3-5 workers · async with 202 + polling

§5 AI Assistant — 6 criteria

5.1 Accuracy ≥80% on 50 queries
Qwen-2.5-7B AWQ 4-bit · vLLM 0.4 · A100 80GB · RAG (Qdrant)
5.2 Grounding, no hallucination
System prompt forbids fabrication · SQL re-validation · refusal/caveat intents
5.3 RBAC positive test
User scopes → SQL filter inject · "WHERE operator_id = 'OP-A'"
5.4 RBAC negative test, adversarial
Pattern matching (regex) + SQL re-validation + output filter · BLOCKED response
5.5 Audit trail (user, ts, q, scope)
postgis.ai_messages + audit_log · 90d hot, 1y cold
5.6 Azure AD SSO + MFA
MSAL.js + OIDC + PKCE · Microsoft Authenticator push · JWT 15min

§6 Coverage Prediction — 8 criteria

6.1 Physical inputs consumed
sionna.Scene(sites, dem, buildings, antenna_patterns) · input manifest logged
6.2 Physical plausibility (LOS/NLOS)
NVIDIA Sionna RT v0.14 · BulletShootAndBounce · 14 ray bounces
6.3 RMSE ≤8-10 dB, bias ±3 dB
vs crowdsourced RSRP (held-out 20%) · scripts/ray-trace/rmse.py
6.4 Output 5-25m grid, full AOI
Zarr raster · GeoTIFF for QGIS · postgis.coverage_runs.output_*_path
6.5 Portal integration <3s warm
Heatmap layer in MapLibre · tile cached by scenario hash
6.6 Scenario re-run, plausible delta
Diff-based scenarios · base_scenario_id + parameters JSONB
6.7 Runtime ≤4h per AOI
A100 80GB · 5-10 km² · 14 bounces · 2-3.5h
6.8 Reproducible pipeline
Git repo · poetry install · python -m napa.raytrace run · seed=42

Cross-cutting

Auth · Azure AD OIDC + PKCE · MSAL.js · 5min user cache
DB · PostgreSQL 15 + PostGIS 3.4 · hash partition by state_id (16) · time partition for coverage_points (monthly)
Cache · Redis 7 · tiles 1h, dashboard 5min, AI 24h, session 8h
Object storage · MinIO/S3 · raw 30d, processed 90d, exports 7d, coverage permanent
Observability · ELK 90d + Prometheus + Jaeger 10% sampling · Sentry for FE
Tencent Cloud · POC: 1 app VM, 1 DB, 1 GPU · 2h 47m sim on A100