AWS Builder Center
Weekend Productivity Challenge: WeekWrap

Weekend Productivity Challenge: WeekWrap

How I built WeekWrap - an AI-powered work log that maps daily notes to annual goals and generates self-review narratives using Amazon Bedrock Nova models.

This is my submission to build an AI-powered productivity app on AWS over a weekend.
There is a gap I run into at every performance review cycle: I know I did a lot, but I cannot reconstruct it clearly. Notes are scattered across tools, wins are underdocumented, and the connection between daily work and annual goals is invisible until someone asks you to prove it. WeekWrap is my fix for that.
The idea is simple - log a short note about what I did, and the app structures it into a tagged accomplishment mapped to one of my annual goals. At review time, hit Generate and get a first-draft narrative grouped by goal. No more blank-page problem.

Vision and what the app does

WeekWrap is a personal work log with three functions:
  • Log - type a raw note ("shipped the migration script, unblocked the team for two weeks") and Bedrock structures it into a specific accomplishment with topic tags and a goal mapping
  • Goals - set your annual goals once; every entry gets mapped to the closest one automatically
  • Rollup - pick a date range, generate a self-review narrative grouped by goal, copy it straight into your performance doc
The Log tab after submitting a note. Bedrock has structured the raw input into a one-sentence accomplishment, tagged it, and mapped it to a goal. The entry appears below the input immediately.
The Goals tab. Annual goals saved here are what Bedrock maps every new entry against. Add or remove goals at any time - the next entry you log picks up the updated list.
The Rollup tab after hitting Generate - Bedrock Nova Micro has written a first-draft self-review narrative from the stored entries, grouped by goal. Copy it straight into a performance doc.

How I built it

The idea is to build this in a weekend on free tier only. That ruled out ALB, API Gateway, and Fargate. The stack:
  • Backend: FastAPI (Python) wrapped with mangum  to run as a Lambda handler, exposed via a Lambda Function URL. No API Gateway needed - Function URLs support CORS natively and are free within Lambda's free tier. The app has no auth - it is public by design, scoped to personal use at a URL.
  • Storage: Two DynamoDB tables on on-demand billing - weekwrap-entries for logged notes and weekwrap-goals for the user's annual goals. Both use a single-table-style pk/sk pattern: entries keyed on USER#default with an ISO timestamp sort key, goals keyed on GOALS#default with GOAL#001, GOAL#002 sort keys.
  • AI: Amazon Bedrock with two Nova models:
    • amazon.nova-lite-v1:0 for structured extraction - takes the raw note and returns a JSON object with accomplishment, tags, and goal_id
    • amazon.nova-micro-v1:0 for the rollup narrative - cheaper model, sufficient for prose generation from structured input
Both calls go through the Bedrock Converse API, which gives a consistent interface across models. An extraction prompt asks Nova Lite to return JSON only. Nova occasionally wraps output in markdown code fences, so the handler strips those before json.loads().
  • Frontend: Vanilla HTML/CSS/JS - no framework, no build step. Three tabs (Log, Goals, Rollup) in a single index.html, stored in S3 and served over HTTPS via CloudFront. S3 static website hosting is HTTP-only, so CloudFront sits in front of it as a CDN layer - users get HTTPS, CloudFront fetches from S3 over HTTP internally. The Function URL is injected at deploy time.
  • IaC: CDK v2 Python. One stack (WeekWrapStack) provisions everything - Lambda, Function URL, two DynamoDB tables, S3 bucket with frontend deployment. The CDK patterns here - bootstrapping, stack structure, IAM scoping are well established.

AWS services used

ServiceRole
Lambda (Python 3.12)Backend - FastAPI app via mangum
Lambda Function URLHTTP endpoint with CORS, no API Gateway
DynamoDB (on-demand)weekwrap-entries and weekwrap-goals tables
S3 (static website hosting)Frontend - HTML/CSS/JS
CloudFrontHTTPS CDN in front of S3 - fixes HTTP-only limitation of S3 website endpoints
Amazon Bedrock - Nova LiteStructured JSON extraction from raw notes
Amazon Bedrock - Nova MicroSelf-review narrative generation
IAMTask role scoped to the two DynamoDB tables and two Bedrock model ARNs
CDK v2 PythonIaC - single stack deploys everything
Everything except Bedrock inference tokens is within the AWS Free Tier. The Nova model costs per 1,000 tokens are low enough that personal use stays under a dollar a month.

Architecture Overview

  • The frontend is stored in S3 and served over HTTPS via CloudFront - S3 website endpoints are HTTP-only, so CloudFront provides the HTTPS termination.
  • All API calls go directly from the browser to the Lambda Function URL over HTTPS - no API Gateway, no load balancer.
  • Lambda handles every route: DynamoDB reads/writes for entries and goals, and synchronous Bedrock calls for the two AI steps.
  • The two DynamoDB tables are independent; entries accumulate, goals are overwritten on each save.
1
2
3
4
5
6
7
8
9
Browser
|
|-- HTTPS --> CloudFront --> S3 bucket (static frontend)
|
'-- HTTPS --> Lambda Function URL
|
+-- DynamoDB (entries + goals)
+-- Bedrock Nova Lite (POST /entries)
+-- Bedrock Nova Micro (POST /rollup)

What I learned

  1. Use the Bedrock Converse API, not invoke_model
    I started using an Anthropic-specific body format, then switched to Nova models. The Converse API is model-agnostic - the same bedrock.converse() call works for Nova Lite, Nova Micro, and any other model that supports it. Switching models is a one-line environment variable change.
  2. Nova models handle structured JSON extraction cleanly
    The extraction prompt asks for JSON only, and Nova Lite returns it reliably. The code-fence stripping is a minor defensive measure, not something that fires often.
  3. Lambda Function URLs remove a lot of friction for personal tools
    No API Gateway stage to manage, no extra cost, CORS configuration is a first-class option on the Function URL construct. If you don't need WAF or usage plans, Function URLs save you the API Gateway setup entirely.
  4. IAM ARNs for Nova foundation models differ from inference profiles
    Cross-region inference profiles (used with some Claude models) have an ARN that includes the account ID. Nova foundation model ARNs don't - they follow the pattern arn:aws:bedrock:*::foundation-model/amazon.nova-lite-v1:0 with a double colon and no account segment. Getting this wrong produces a silent IAM deny at runtime.
  5. mangum makes Lambda + FastAPI seamless
    Wrap the FastAPI app with Mangum(app, lifespan="off") and the handler just works. Local dev runs with uvicorn main:app, Lambda runs with main.handler - same code, no adapter logic to maintain.

Link to the live app


Notes

  1. All AWS services used are within the Free Tier at personal usage volumes. Bedrock Nova inference costs are minimal - under $1/month for typical daily logging.
  2. The two-model split (Nova Lite for extraction, Nova Micro for narrative) keeps costs lower than using a single larger model for both tasks.
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