Building JalDrishti: A Serverless Water Decision-Support Platform with AWS Lambda and DynamoDB
Discover how I built JalDrishti, a serverless water decision-support platform using AWS Lambda, DynamoDB, and Next.js. Explore transparent water-balance forecasting, interactive scenario simulations, secure cloud persistence, and the engineering challenges behind deploying a real-world environmental technology project.
Water security starts with a question that sounds simple: how long will the available water last? For a campus or community, the answer depends on storage, consumption, supply interruptions and the reserve that must remain available. A regional rainfall forecast adds context, but it cannot tell us how much water is in an individual tank.
I built JalDrishti to make those distinctions visible. It combines a transparent water-balance engine, interactive intervention scenarios, traceable operational inputs and protected cloud persistence. The aim is decision support with inspectable assumptions, not an unexplained prediction or a claim of proven water savings.
I built JalDrishti to make those distinctions visible. It combines a transparent water-balance engine, interactive intervention scenarios, traceable operational inputs and protected cloud persistence. The aim is decision support with inspectable assumptions, not an unexplained prediction or a claim of proven water savings.

JalDrishti brings transparent forecasting, scenario comparison and traceable inputs into one workspace.
Explore JalDrishti .
The public Sample Demo lets visitors explore an illustrative Pune example without credentials. Its inputs are explicitly synthetic. Edits and scenarios remain in browser memory and reset on reload; anonymous exploration does not write cloud records or invoke privileged environmental providers.
The public Sample Demo lets visitors explore an illustrative Pune example without credentials. Its inputs are explicitly synthetic. Edits and scenarios remain in browser memory and reset on reload; anonymous exploration does not write cloud records or invoke privileged environmental providers.

Sample Demo uses synthetic operational inputs; these values are not campus measurements.
Real Analysis starts empty. Users enter readings or import validated CSV records, specify demand baselines and reserve policies, and retain input provenance. Synthetic demo provenance is rejected in the real decision path. Hosted cloud operations require an operator session.

Real Analysis begins with actual site inputs. Protected cloud persistence is optional and requires operator access.
These are authentic application screenshots. Their displayed sample values are illustrative, not measurements from a real campus.
The browser and backend share the same calculation engine. In simplified notation, each time step applies:
All flows are evaluated over the engine's time step. The chart shows the resulting trajectory and the first warning or critical reserve crossing under the selected assumptions. Users can inspect 7-, 14- and 30-day horizons.
This is deterministic forecasting: the same validated inputs and model version produce the same result. It is not a machine-learning model, statistical confidence interval or validated prediction-accuracy claim. Constant rates and explicit additional-loss assumptions limit what the trajectory can establish.
All flows are evaluated over the engine's time step. The chart shows the resulting trajectory and the first warning or critical reserve crossing under the selected assumptions. Users can inspect 7-, 14- and 30-day horizons.
This is deterministic forecasting: the same validated inputs and model version produce the same result. It is not a machine-learning model, statistical confidence interval or validated prediction-accuracy claim. Constant rates and explicit additional-loss assumptions limit what the trajectory can establish.

The same validated inputs and model version produce the same modeled trajectory; this is not a statistical accuracy claim.
Rainfall does not automatically become water in the tank. That would require a justified physical model with known catchment area, capture efficiency and connections to storage. JalDrishti does not yet have that verified relationship.

The System workspace exposes the operational water balance and editable assumptions. All values pictured here belong to synthetic Sample Demo.
The Scenario Simulator transforms operational inputs and reruns the shared engine. It can compare demand reduction, supplementary volume, supply delays, demand multipliers and repair of an explicitly assumed additional loss.
For example, I can select a supply interruption, inspect the earlier reserve crossing, then compare a recommended scenario. The change in the chart is a modeled consequence of the changed assumptions, not evidence that the intervention has already saved water.
For example, I can select a supply interruption, inspect the earlier reserve crossing, then compare a recommended scenario. The change in the chart is a modeled consequence of the changed assumptions, not evidence that the intervention has already saved water.

Scenario differences are modeled consequences of changed assumptions, not evidence of measured water savings.
Supplementary water is added once at the starting time and capped by tank capacity. Delayed supply resumes without compensating for missed deliveries. The rainfall intervention remains disabled. These details prevent the interface from implying capabilities the model does not have.

The decision brief turns the scenario into an inspectable summary with assumptions and verification steps; it does not guarantee an outcome.
Environmental data is kept separate from local operational storage. The typed data layer normalizes Open-Meteo variables and retains units, requested and grid locations, source names, valid and retrieval times, and freshness or unavailable states.
The fixed-region integration uses DWD ICON regional estimates and forecasts. Real Analysis supports selected coordinates with ECMWF modeled variables and delayed ERA5 historical comparisons. These products describe regional conditions, not individual buildings, tanks or wells. Three comparison years are not a climatological normal.
The public Data workspace starts in explicitly labeled offline mode with illustrative fixtures. Missing live data never silently becomes synthetic data labeled as live. Provider failure does not disable the operational engine.
The fixed-region integration uses DWD ICON regional estimates and forecasts. Real Analysis supports selected coordinates with ECMWF modeled variables and delayed ERA5 historical comparisons. These products describe regional conditions, not individual buildings, tanks or wells. Three comparison years are not a climatological normal.
The public Data workspace starts in explicitly labeled offline mode with illustrative fixtures. Missing live data never silently becomes synthetic data labeled as live. Provider failure does not disable the operational engine.

This image shows an explicitly labeled offline fixture, not downloaded observations or local tank measurements.
NASA POWER and SMAP were evaluated but are not integrated. Groundwater supports source-qualified user imports; there is no automatic CGWB ingestion, satellite tank-storage measurement or IoT telemetry.
The deployed application uses a small application architecture in the Sydney region:
The architecture graphic illustrates these boundaries. It is an explanatory diagram, not a screenshot of infrastructure settings.
The frontend runs Next.js 16.4 standalone on Node.js 24 x86_64 with AWS Lambda Web Adapter. The pinned adapter layer allows the existing HTTP application to run inside Lambda. The Linux package includes the standalone server, public files and Next.js static assets. A Unix startup script launches the server on port 8080; the adapter checks readiness at /.
There is no CloudFront, WAF, VPC/NAT or extra database in the current application delivery path. Ordinary platform logging remains necessary. A retained IAM-protected HTTP API is a legacy entry point; current frontend persistence uses direct backend Lambda invocation.
The frontend's HTTPS Function URL is public so visitors can explore Sample Demo. Protected server handlers still require the signed operator session. Mutations enforce the exact configured origin, body limits, schema and provenance. CORS is not authorization.
The frontend execution role can invoke only the specific backend function and write its own logs. It has no direct DynamoDB or administrator permissions. Temporary execution-role credentials and SigV4 authorize server-to-server calls; AWS credentials never go to the browser. Real Analysis adds a server-side token gate.
Operator cookies are HttpOnly, Secure on hosted HTTPS and SameSite=Strict. The access code, session-signature secret and backend token stay in trusted runtime configuration and are excluded from browser assets and release packages. Errors become sanitized unavailable states rather than internal diagnostics.
DynamoDB uses separate demo and real record keys. Real schema-v2 state preserves accepted records, reserve policy, provenance, model metadata and revision information. Consistent reads and expected-revision conditional writes protect against lost updates. A missing real record remains missing rather than becoming sample data. Raw CSV, rejected rows and unsaved scenario controls remain session-local.
Development happened on Windows, with project files, dependencies, caches and builds kept on the A: drive. A Windows build was not treated as a valid Lambda release.
The deployment used WSL2 Ubuntu 24.04, Linux Node.js 24.21.0 and x86_64 packaging. Validation checked dependency closure, native libraries, LF line endings, executable permissions, static assets, ZIP integrity and secret exclusion before upload. The verified public release package was about 13.67 MiB, with roughly 42.56 MiB expanded including the adapter.
The practical lesson was to validate the actual deployment artifact, not only the development server. A production favicon response issue found during browser verification was corrected and the release checked again before public delivery.
The public-launch evidence records:
The deployed application uses a small application architecture in the Sydney region:
The architecture graphic illustrates these boundaries. It is an explanatory diagram, not a screenshot of infrastructure settings.
The frontend runs Next.js 16.4 standalone on Node.js 24 x86_64 with AWS Lambda Web Adapter. The pinned adapter layer allows the existing HTTP application to run inside Lambda. The Linux package includes the standalone server, public files and Next.js static assets. A Unix startup script launches the server on port 8080; the adapter checks readiness at /.
There is no CloudFront, WAF, VPC/NAT or extra database in the current application delivery path. Ordinary platform logging remains necessary. A retained IAM-protected HTTP API is a legacy entry point; current frontend persistence uses direct backend Lambda invocation.
The frontend's HTTPS Function URL is public so visitors can explore Sample Demo. Protected server handlers still require the signed operator session. Mutations enforce the exact configured origin, body limits, schema and provenance. CORS is not authorization.
The frontend execution role can invoke only the specific backend function and write its own logs. It has no direct DynamoDB or administrator permissions. Temporary execution-role credentials and SigV4 authorize server-to-server calls; AWS credentials never go to the browser. Real Analysis adds a server-side token gate.
Operator cookies are HttpOnly, Secure on hosted HTTPS and SameSite=Strict. The access code, session-signature secret and backend token stay in trusted runtime configuration and are excluded from browser assets and release packages. Errors become sanitized unavailable states rather than internal diagnostics.
DynamoDB uses separate demo and real record keys. Real schema-v2 state preserves accepted records, reserve policy, provenance, model metadata and revision information. Consistent reads and expected-revision conditional writes protect against lost updates. A missing real record remains missing rather than becoming sample data. Raw CSV, rejected rows and unsaved scenario controls remain session-local.
Development happened on Windows, with project files, dependencies, caches and builds kept on the A: drive. A Windows build was not treated as a valid Lambda release.
The deployment used WSL2 Ubuntu 24.04, Linux Node.js 24.21.0 and x86_64 packaging. Validation checked dependency closure, native libraries, LF line endings, executable permissions, static assets, ZIP integrity and secret exclusion before upload. The verified public release package was about 13.67 MiB, with roughly 42.56 MiB expanded including the adapter.
The practical lesson was to validate the actual deployment artifact, not only the development server. A production favicon response issue found during browser verification was corrected and the release checked again before public delivery.
The public-launch evidence records:
- 163 passing automated tests, including the existing baseline and public-access checks.
- Successful ESLint, TypeScript and Linux standalone production build.
- 13 local packaged-runtime checks.
- 44 responsive checks across public and Real Analysis workspaces at 1440, 1024, 768 and 390 pixels.
- Anonymous protected requests denied and mutation-origin/payload checks enforced.
- Real Analysis save/load surviving reload with accepted records, reserves, provenance and model versions preserved.
- Concurrent revision conflict handling and backend-unavailable behavior preserving local work.
- Shared-engine forecast agreement and rejection of synthetic provenance in Real Analysis.
- Zero detected configured-secret or AWS credential-pattern matches in the scanned release entries.
Persistence verification used explicitly labeled temporary test fixtures, not genuine environmental measurements. Cleanup restored the original missing-record state without altering pre-existing records. These tests establish software behavior; they do not validate environmental prediction accuracy or prove real-world savings. The counts describe the recorded launch validation, not a fresh test run for this article.
JalDrishti is a single-operator demonstration, not a multi-tenant production service. Process-local throttling is not global abuse protection or a financial cap; public requests incur Lambda usage and share regional concurrency.
The decision-support index is a versioned engineering heuristic, not an official drought standard. Median/MAD anomaly flags are not confirmed leak diagnoses. Alerts, Actions and Impact are placeholders. There is no AI assistant, calibrated geospatial forecasting or validated harvesting model.
Next steps are validation against measured site records, evaluation of variable demand and supply assumptions, a physically justified harvesting model, and a reviewed access/cost strategy before broader adoption. These are future improvements, not existing features.
AI-assisted development used OpenAI Codex. Frameworks, adapter and environmental providers retain their respective licenses and terms. No license for original project source has been selected. - AWS Lambda Web Adapter
- Lambda Function URL authorization
- Open-Meteo documentation
- Open-Meteo historical weather
- Environmental Hacks official rules
The project repository remains private. This article does not assert hackathon eligibility, compliant development dates, awards or registration. The aim is to show an inspectable engineering approach to water decisions and be clear about what still needs scientific validation.
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article