DEV Community

Cover image for Building BrewCore: Espresso Tracking on Vercel, DynamoDB, and Amazon Bedrock
Hima
Hima

Posted on

Building BrewCore: Espresso Tracking on Vercel, DynamoDB, and Amazon Bedrock

Beyond the Timer: How I Built BrewCore for the H0 Hackathon

Home espresso is a paradox. Baristas obsess over the micro-details the gram weight, the seconds on the clock, the pressure profile-but we usually track it all on sticky notes or fragmented mental maps. When that morning shot turns sour, we don’t have a database to query; we have a bad cup of coffee and a Reddit thread from 2019.

For the H0 Hackathon, I wanted to bridge that gap. I've built BrewCore: a full-stack coffee companion that treats an espresso setup like the precision instrument it is.

The Problem: Espresso is Data, Not Just Caffeine

Most coffee apps are glorified timers. I wanted a system that understands the variables:

  • The Inventory: How many grams of that Ethiopian light roast are left?

  • The Science: What happened last Tuesday when a barista ground finer but lowered the temp?

  • The Coach: How do you fix a sour shot using a specific machine and history?

I set out to build a platform that turns home baristas into data scientists. And I wanted to do it with a stack that is as robust as it is clean: Next.js 15, Vercel, Amazon DynamoDB, and Amazon Bedrock.


The Serverless Architecture

To achieve absolute zero-infrastructure management during development, I mapped out a clean separation of concerns between my hosting platform and cloud data layers.

End-to-End Data Flow

As detailed in my system architecture, the application relies on four core stages to handle traffic securely and efficiently:

  1. Browse & Log Shots: The end-user interacts with a responsive React PWA hosted on Vercel. All client interactions communicate via secure HTTPS directly to Next.js 15 Server Actions.

  2. Authenticate: Security is managed entirely at the edge. The Amplify client SDK handles secure user sign-ins and session tokens via an Amazon Cognito User Pool.

  3. Persist Data: Server Actions eliminate the need for a separate API Gateway or dedicated Lambda layer. The application uses the AWS SDK v3 to read and write records directly into my specialized data tables.

  4. AI Coaching: When a user requests dial-in assistance, the app bundles their historical brewing data and utilizes the Amazon Bedrock Converse API to invoke the high-performance nova-micro model.


DynamoDB: Multi-Table Design Principles

Most people reach for SQL when they need data relationships. I went the other way, modeling my storage strictly around how the UI actually behaves.

Instead of dealing with resource-heavy scans, I created eight dedicated tables optimized for $O(1)$ key-value lookups and targeted queries using Global Secondary Indexes (GSIs):

  • users - Profiles and customizable setup preferences.
  • beans - Granular tracking of inventory grams remaining, roaster data, and low-stock indicators.
  • shots - Fully detailed extraction parameters (grind, dose, yield, time, and flavor profiles).
  • interactions & comments - Handles social metrics like likes and feedback counters on the community feed.
  • user_stats - Pre-aggregated counter arrays to avoid expensive runtime calculations.
  • follows & product_states - Manages the social graph and handles client-side state flags for UI element dismissal.

The Developer Workflow: Mock vs. Real Cloud

The biggest bottleneck in hackathons is usually waiting for cloud infrastructure to provision. I solved this with a dual-backend interface. I built a local localStorage mock that perfectly mirrors my structural DynamoDB types. I developed the entire UI offline, and when I was ready, I flipped one environment variable to shift traffic to my production AWS tables.


Teaching AI to Pull a Perfect Shot

Generic AI tips are useless for espresso-"grind finer" is completely unhelpful advice if the model doesn't know a barista's starting baseline.

By feeding my Bedrock (Nova Micro) model a structured context payload of the user's explicit profile-bean history, machine parameters, and recent extraction logs, I transformed generic LLM behavior into a personalized barista coach. It doesn't guess; it performs direct trend analysis on the database entries.


Technical Lessons Learned

  • Next.js Server Actions need robust global error handling
    When bypassing an API Gateway/Lambda layer to call DynamoDB directly from Next.js Server Actions, traditional HTTP status code safety nets disappear. If a write fails or an IAM credential expires, the Server Action can silently fail or crash the client components if the rejection isn't caught cleanly. I learned to wrap my DatabaseOperations client in a strict, uniform error-handling wrapper that gracefully maps AWS SDK exceptions to typed, user-friendly UI alerts without leaking sensitive cloud configuration details.

  • DynamoDB GSIs demand strict primitive data types
    I hit an immediate roadblock when setting up the community feed query: global secondary index (GSI) keys in Terraform natively expect string (S), number (N), or binary (B) data types. Because I originally modeled shot visibility (isPublic) as a standard boolean, my infrastructure provisioning failed on the first apply. I had to pivot and normalize my schema to store booleans as "true" or "false" strings, teaching me that NoSQL design means your infrastructure constraints strictly dictate your application logic.

  • LLMs require rigid prompt grounding, not just long system instructions
    My early iterations with Amazon Bedrock (Nova Micro) frequently suffered from recipe hallucinations; when asked how to fix a sour espresso pull, the model would guess generic parameters rather than looking at what the user actually did. I realized that a massive, descriptive system prompt is useless without rigid data grounding. The fix was structured JSON context injection: I began querying the user's specific extraction history and passing a serialized payload of their last 3 shots directly into the prompt context, forcing the AI to act as a data analyst rather than a generic text generator.


Resources & Repositories

Whether you are a coffee enthusiast or an engineer seeking a production template for matching Vercel with deep AWS serverless integrations, BrewCore shows that you don't need a massive footprint to ship powerful, cloud-native applications.

Happy brewing. β˜•


Hackathon Submission Disclosure

This article was created and published for the purposes of entering the H0 Hackathon - Hack the Zero Stack with Vercel and AWS Databases. #H0Hackathon

Top comments (0)