Architecture

Baha Manila — what is deployed, not what was designed.

Verified against the live AWS account · ap-southeast-1 · 2026-08-09

Reference only. This page is a public snapshot of an internal document from the private repository thejustinjames/baha-alert (visible to collaborators only). The authoritative sources are the CDK in IaC/aws and the settings rationale in IaC/DEPLOYED.md, both in that repo. Everything here was read back from the live account rather than from the code. The agency data-access request letters are public in data-access/.

The pipeline

Rain becomes a reading, a reading becomes an event, an event becomes a warning.

Public internet
PAGASARiver gauges, dam bulletins, rainfall
OCD CALABARZONUpper Wawa — adapter built, no live feed
scheduled pull
Collectors · outside the VPC
pmt_waterevery 5 min
warning_postsevery 5 min
rainfallevery 10 min
damsevery 15 min
archive first, then parse
S3 baha-raw-archiveVersioned · Object Lock COMPLIANCE · every response kept before parsing
SQS baha-raw-observationsbatch 10 · partial failure reporting
DLQ + alarma reading that could not be parsed
consume
VPC · public subnets · no NAT gateway
baha-normalizerValidate, persist, run the event engine
RDS PostgreSQL 16.14 + PostGISdb.t4g.micro · single AZ · SSL forced
baha-apiFastify · HTTP API
baha-notifyResolve who is downstream, apply policy, write the delivery ledger
derived events
SQS baha-notifications1-day retention · a stale warning is worthless
DLQ + alarma warning that was never delivered
synchronous invoke · via Lambda VPC endpoint
Outside the VPC · needs the internet
baha-push-senderNo database, no state. PUSH_ENABLED = false
Expo → APNs / FCMtimeSensitive interruption level
Baha ManilaiOS · Android · web preview

Why delivery is split in two. baha-notify needs Postgres, which is in the VPC. Expo needs the internet, which this VPC deliberately cannot reach. Rather than buy a route between them for about $32/month, the notifier resolves recipients and writes the ledger, then synchronously invokes a sender that has no database access and does nothing but send. The call is synchronous on purpose: fire-and-forget would be cheaper and would ruin the audit trail, because "handed to another function" is not an outcome anybody can act on after a flood.

Stacks

Six, all CDK. cdk diff --all reports no differences against deployed state.

StackRegionContains
BahaArchive-devap-southeast-1Raw archive bucket, tiles bucket
BahaDns-devap-southeast-1Route 53 zone phflood.agrisphere.asia
BahaIngest-devap-southeast-1Collectors, schedules, both queues, DLQs, alarms, ops topic
BahaData-devap-southeast-1VPC, RDS, normalizer, notify, push sender, VPC endpoints
BahaApi-devap-southeast-1HTTP API and Fastify Lambda
BahaBilling-devus-east-1Budget and cost alarms — billing metrics exist only there

Compute

FunctionRuntimeMemTimeoutIn VPC
baha-collector-pmt_waternodejs22 arm6451290 sno
baha-collector-warning_postsnodejs22 arm6451290 sno
baha-collector-rainfallnodejs22 arm6451290 sno
baha-collector-damsnodejs22 arm6451290 sno
baha-normalizernodejs22 arm6451260 syes
baha-apinodejs22 arm6451230 syes
baha-notifynodejs22 arm6451290 syes
baha-push-sendernodejs22 arm6425620 sno

Guardrails

AlarmFires when
baha-collector-*-failingA collector fails repeatedly — four of them, one per source
baha-raw-observations-dlqA reading could not be parsed
baha-notifications-dlqA warning was not delivered

All route to SNS baha-ops-alerts-dev. Budget baha-alert-monthly is $150, with a separate account-wide cost topic in us-east-1.

Added 2026-08-09. The notifications DLQ had no alarm. It was the only queue without one, and it is the one carrying flood warnings — a derived event could fail delivery three times and sit there with nobody told. The observations queue, carrying readings, was alarmed from the start.

Not managed by CloudFormation

cdk diff will never mention these.

ResourceCreated byNote
Amplify baha-previewIaC/scripts/deploy-amplify-preview.sh Password-protected preview environment. Manual zip deploy rather than a Git connection, to avoid holding a GitHub token
Android signing assetsIaC/scripts/build-android.sh Release signing material is created by script rather than CDK

Outside AWS

ThingWhere
www.agrisphere.asiaCloudflare Pages project manila-flood-monitor
agrisphere.asia DNSGoDaddy — not Cloudflare, not Route 53
phflood.agrisphere.asiaRoute 53, delegated from GoDaddy by NS records
iOS builds, push keysEAS (Expo)

One DNS hazard. The NS records delegating phflood to Route 53 live at GoDaddy, not in Route 53 itself. Lose them and the API domain goes with them — both api.phflood.agrisphere.asia and the Amplify preview.

The www CNAME was corrected on 2026-08-09 and now names manila-flood-monitor.pages.dev everywhere. The old manilia-flood-monitor project is no longer load-bearing and can be deleted. The apex has no records and does not resolve; GoDaddy cannot CNAME an apex, so reaching the site without www needs GoDaddy Forwarding.

Known gaps