AWS Builder Center
Air Guardian: Turning an Air Number into a School-Day Plan People Actually Review

Air Guardian: Turning an Air Number into a School-Day Plan People Actually Review

Team Cipher · Harshika Thopte (Team leader) and Ishan Sonwane (Team member) Environmental Hacks (Bharat Builds Tour, Event 02) Track 01: Air Repo: https://github.com/Hari-Thopte/Air-Guardian

The problem we picked

Bad air days in India are not abstract. They are the 7:30 a.m. moment when a school principal has to decide: assembly outdoors or indoors? PE outside or in the hall? And then the harder part — actually telling teachers, staff, and six hundred parents, and knowing who received and acted on it.
We found that the hard part isn't the AQI number. It's the operational loop after the number. A pollution reading alone does not coordinate assembly, PE, or pickup. Someone publishes a decision, teachers act on it in specific rooms, parents need to trust it — and nobody can prove the message actually completed the loop. That gap is what Air Guardian closes.

What we built

Air Guardian is a school air-day planning tool that puts a reviewed, provenance-checked plan between a reading and an action:
  • A school administrator sees the current reading with its source and freshness evidence, a planning flag, and a suggested instruction — then edits the wording and publishes it.
  • Teachers confirm the notice, the room arrangement, supervision, and what they told their class — a working checklist, not a broadcast.
  • Parents review the school plan and mark it as read. The admin dashboard counts unique adult review receipts, not page views. At publication, the demo shows the count move from 0 of 6 to 1 of 6.
  • Staff receive only a short duty instruction — staff accounts never receive child records.
  • Kids get a simplified learning panel with a mascot, bigger choices, and browser read-aloud, collecting no personal information.
A concrete example from our own policy engine: with a fictional timetable of assembly 20 minutes, PE 30, break 15, and pickup 20, moving PE and assembly indoors at an orange/red planning flag changes planned outdoor time from 85 to 35 minutes — a planning estimate, clearly labeled as such, never a claim of measured exposure avoided.
The UI is deliberately honest about uncertainty. Every reading shows its observation time and retrieval time. A reading older than two hours becomes "unknown" and blocks publication — a stale draft cannot be sent to parents. The interface ships in English, Hindi, and Marathi with self-hosted Figtree and Noto Sans Devanagari fonts, works offline as a PWA, and passed targeted contrast checks of 5.37:1 and 7.96:1 on primary text.

The stack, and where AWS fits

The frontend is plain HTML, CSS, and vanilla JavaScript. The backend is Python serverless, defined entirely in a SAM template ( template.yaml ):
  • AWS Lambda (Python 3.12, arm64, active X-Ray tracing) behind API Gateway HTTP APIs with JWT authorization and throttling.
  • Powertools for AWS Lambda — the AWS open-source project at the core of our eligibility story.  cloud/local_engine.py  uses the real  APIGatewayRestResolver  to dispatch  /engine , and  Logger  decorates the handler without logging request bodies. The same pure-Python planning rules power both the school workspace and the public landing-page examples, so the landing page can never quietly invent different thresholds than the school tool. You can hit this real resolver slice locally at  /local-engine  — it's a working open-source integration, not an AWS logo on a slide.
  • Amazon DynamoDB — two tables (application + readings) with time-to-live, encryption at rest, point-in-time recovery, and transactional writes in  cloud/store.py .
  • Amazon Cognito for membership authorization: PKCE sign-in, verified-email-bound single-use invitations that expire after 24 hours, school membership enforced in the database — signup alone grants no school access.
  • Amazon SQS with a durable outbox pattern and dead-letter queues: notification jobs are one-per-recipient with a lease/receipt mechanism to survive retries, relayed from a minute-level outbox erasure pipeline.
  • Amazon SES for email, plus Web Push (VAPID keys held in AWS Systems Manager Parameter Store as SecureStrings), and SMS/WhatsApp adapters gated behind operator configuration.
  • Amazon EventBridge Scheduler drives ingestion every 15 minutes from Open-Meteo/CAMS (keyless for this noncommercial build), with adapters ready for OpenAQ, OpenWeather, CPCB, WAQI, and IQAir — provider credentials live only in SSM SecureStrings under  /airguardian/ , never in code or frontend config.
  • Amazon CloudFront in front of a private S3 origin for static hosting, with Amazon CloudWatch alarms, a dashboard, logs, and an optional AWS Budgets alarm at a USD 10/month threshold.
  • Optionally, AWS IoT Core for school sensors: per-device certificates publishing to their own exact topics, with staleness, flatline, and jump checks — experimental readings never automatically replace the regional planning input.
Guardrails are in the code, not just the docs: every notification channel requires saved consent, respects quiet hours and per-channel daily caps, and fails closed if a phone number isn't Cognito-verified. Retention is explicit — readings and receipts 90 days, telemetry and delivery records 30 days.

What fought back

Ambiguity, everywhere. An instantaneous particle estimate is not official daily AQI. A regional model is not a measurement at a school gate. A parent review receipt is not a health outcome. An indoor plan still needs a room assessment. Each of these distinctions now appears in the UI exactly where a person makes the decision — and where it couldn't be pushed into the UI, we said it in plain text instead of blurring it.
A tempting three-hour freshness rule. Our two-hour staleness cutoff was stricter than a nicer-looking three-hour UI status suggestion we considered. We kept two hours; stale drafts are blocked, not warned about.
Verifying what we couldn't reach. SAM CLI and Docker weren't available in our build environment, so while the SAM template validates ( sam validate --lint ) and the same Lambda handler is exercised directly in tests and through the local preview, the container invocation and live deployment remain unverified. We chose to document exactly that — implemented vs. verified vs. not claimed — rather than imply a deployment that never ran. Our test suite (48 backend tests using moto for DynamoDB/SQS, Playwright with axe-core for browser accessibility, and a preview smoke check covering publication, unique parent review, role privacy, and stale-data rejection) proves the workflow locally; it does not prove live AWS operation, and we say so.

What's next

The intended rollout order: deploy the one-school pilot in  ap-south-1  with CAMS and in-app delivery and smoke-test every role boundary; activate verified email and Web Push; accumulate 7–30 days of source-labeled history and evaluate forecasts against independent observations; then add one licensed measured provider and one physically calibrated sensor. The next real milestone is a small school pilot — verify nearby measurements, review policy and rooms with school adults, and observe whether the plan is actually understandable. We have not measured exposure reduction or health outcomes, and we won't claim any until we have.



Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article