Architecture

The diagram source is the draw.io file at
images/software/developer/estate/systems/gkl/architecture.drawio. To change the diagram, edit that source in draw.io, re-export it as PNG to architecture.png in the same folder, and commit both.Three Lambdas
The API Lambda is a normal ASP.NET Core application wrapped for Lambda, which is why the same code runs locally as an ordinary web API. It holds all the business logic; the other two exist only to take slow work off the request path.
Why The Work Is Split
An email send or a CRM call is slow, can fail, and must not make a customer wait or a Vivenu webhook time out. So the API Lambda does not do either itself. It publishes to an SNS topic and returns. Each topic feeds an SQS queue, and each queue triggers a worker Lambda. That gives retries and a visibility timeout without the API knowing anything about SES or HubSpot.
Messages are routed by SNS subject, which is set per environment, so the worker inspects the subject to decide what it is dealing with.
Why The Notification Lambda Calls Back
The notification worker does not need to read the database. Everything it needs to render an email arrives in the SNS message. What it cannot do is sign a token. Password reset and email confirmation links carry a JWT with a special claim (RESET_PASSWORD or VERIFY_EMAIL), and only the API holds the signing key. So the worker posts to the API’s jwt endpoint, gets a token back, and builds the link itself.
That is the reason the private gateway exists. It is restricted by resource policy to a VPC endpoint, so this internal hop never crosses the public internet, and it is authenticated with an internal API key separate from the one the web apps carry.
The Two API Gateways
The WAF is associated with the public gateway’s stage, not placed in front of any one caller, so everything reaching the public gateway passes through it: both web apps, Vivenu’s webhooks and the telemetry converter. It applies a rate limit and the AWS managed rule sets. The private gateway has no WAF.
What Sits Around It
MongoDB holds everything, on the shared EC2 instance provisioned by the infrastructure repository rather than by this one. See The Domain Model. Secrets Manager holds the internal and external API keys, which the API Lambda reads at runtime. An SSM parameter publishes the public API URL, which is how the two web app repositories and the telemetry repository discover where the API lives. See Deployment and Environments. Five CloudWatch alarms across the three Lambdas and the WAF deliver to an SNS topic that emails the team.Notes
- All three Lambdas share one IAM role, and it is broader than any of them needs.
- The API Lambda runs in the VPC because MongoDB is only reachable from inside it.
