Personal Todo Architecture Case Study

Authenticated personal task app built into the static portfolio with an Astro SPA frontend, Cognito Hosted UI, API Gateway JWT authorization, Python Lambda, DynamoDB, Terraform, local DynamoDB development, and GitLab CI.

The Todo app extends the static portfolio with a real authenticated workflow while keeping the public site simple to host. The frontend is still served through the static-site deployment, but task data is loaded through API calls to an AWS serverless backend.

The project is intentionally small, but it exercises production-like boundaries: identity, API authorization, input validation, persistence, infrastructure as code, local integration tests, and CI separation by responsibility.

Frontend

Astro page with a TypeScript Todo controller, focused API helper, Cognito auth helper, autosave editing, mobile layout, and dedicated Todo CSS.

Authentication

Cognito user pool and Hosted UI with authorization-code plus PKCE login for the browser client.

API

API Gateway HTTP API routes for listing, creating, updating, and deleting tasks, protected by a Cognito JWT authorizer.

AWS Lambda

Python Lambda handler with small repository and validation boundaries, packaged by Terraform for AWS deployment.

Storage

DynamoDB on-demand table for task records, with DynamoDB Local in Docker for local development and integration testing.

CI

GitLab CI runs lint, security, frontend tests, backend tests, integration tests, Terraform validation, and platform checks.

Astro page with a small SPA controller

The Todo app stays inside the existing static site, but the interactive behavior lives in a focused TypeScript controller and API helper modules instead of spreading request logic through the Astro markup.

Cognito Hosted UI for authentication

Cognito handles login, token issuance, logout, and callback URLs. The frontend stores the session locally and sends the access token to API Gateway as a bearer token.

HTTP API with JWT authorization

API Gateway validates Cognito JWTs before invoking Lambda, which keeps unauthenticated traffic out of the Python handler and makes the backend contract explicit.

Python Lambda for a small CRUD backend

Python keeps the Lambda implementation compact and easy to test with unittest. The handler owns request validation, status normalization, and DynamoDB mapping.

DynamoDB on-demand table

DynamoDB fits the simple key-value access pattern, avoids server management, and keeps cost low for personal-use traffic. Local DynamoDB in Docker covers integration testing before AWS deployment.

CI split by responsibility

Frontend, backend, integration, Terraform, security, and platform checks run as separate GitLab jobs so failures point at the right ownership area.

  1. The user opens `/todo/` from the static Astro site.
  2. Cognito Hosted UI signs the user in and redirects back.
  3. The browser stores the token session and calls the Todo API.
  4. API Gateway validates the Cognito JWT before invoking Lambda.
  5. Lambda validates the request and reads or writes DynamoDB.
  6. The frontend renders tasks, autosaves edits, and sorts locally.