RSSAmplifier

Blog

Now I Get It! Blog

Development blog for NowIGetIt — upload a scientific PDF, get back a shareable interactive web page

nowigetit.usRSS feed ↗64 posts

Latest posts

LLM post-processing

Claude's response is never the final answer. Between the model's last token and the HTML that lands in S3, Now I Get It! runs a pipeline that filters, augments, and instruments the page. Here's what's in it and why each piece earned its spot.

Curated design styles, no deploy required

A dropdown now lets customers pick a visual style for their generated page -- Academic Editorial, Vintage Travel Poster, Brutalist, and more. The interesting part was making the styles editable by an operator without touching code.

Inline editing now available!

Sometimes, AI-generated web pages contain small errors. These are now fixable by using the built-in HTML and KaTeX editor.

Bulk-translating papers with Anthropic's Message Batches API

Adding an admin-only bulk endpoint that uses Anthropic's batch API for cheaper, async processing -- plus the regression review that found a latent bug nobody knew was there, and the 504 that wasn't actually a failure.

TIME BOMB BUG!!

A latent CloudFront key-rotation bug went off in test four days before I noticed, and prod was a few hours away from the same fate. Three layered bugs lined up to half-complete a scheduled rotation silently.

Two galleries, side by side

A small UX cleanup with an outsized discoverability win, plus a thumbnail-403 red herring during smoke testing that I attributed to a benign cookie expiry.

From 50/day to 50,000/day: real Cognito email verification

AWS approved SES production access, so the auto-confirm hack from launch night came off and Cognito started sending real verification codes.

Closing the SES abuse window: bounce and complaint handling

The thousand-fold SES headroom that came with production access also opens a real attack surface. Detection-and-recording lands today; prevention is filed separately.

Launch night!

Now I Get It! went live tonight -- 60K lines of code, 39 Lambda functions, 807 tests, and one person working part-time for seven weeks.

Pre-launch audit of the test suite

A full audit of the test suite before launch surfaced fixture rot, two real bugs in existing tests, and coverage gaps on the modules added most recently.

Translation mode as a pre-filled tag

Making translation mode filterable by reusing the tag system instead of building a parallel badge mechanism.

Sparse GSI and edge caching for the public gallery

Replacing a scan-then-filter DynamoDB query with a sparse GSI and CloudFront edge caching, then measuring what actually improved.

Gift codes for promotional campaigns

A general-purpose gift code system whose first job is giving five free credits to the earliest 200 waitlist signups at launch.

Tag filtering for the private gallery

Adding free-form tags to personal galleries, and why the interesting design question wasn't the feature shape but where to put the data.

Geo-restricting credit purchases via Stripe Radar

Enforcing Anthropic's supported-countries list at checkout without adding a single line of frontend code, by delegating to Stripe.

A missing heartbeat, a false timeout

A staleness detector from the previous day's queue refactor was declaring long-running papers dead at 5 minutes because nothing was updating the progress timestamp while Opus was streaming.

Adding a job queue

Adding an SQS queue between upload confirmation and PDF processing, sized against real production data, with retries that don't block other jobs.

Zero-downtime updates

Replacing sequential Lambda updates with an atomic alias flip, and the five bugs that only showed up when I actually ran the new deploy script end to end.

Deleting the daily processing limit

Removing a pre-user-accounts safety valve that credit-based pricing made redundant, and enjoying the rare pleasure of a PR that's almost all deletions.

Automating the fraud response pipeline

Rebuilding Now I Get It!'s fraud response from manual admin buttons into an async auto-executing pipeline, and the verification walkthrough that found bugs the automated tests didn't.

Stripe disputes, refunds, and chargebacks

Building out the full dispute, refund, and chargeback lifecycle for Now I Get It! ahead of commercial launch.

A Stripe audit that caught a double-credit bug

Auditing Now I Get It!'s Stripe integration against Stripe's own best-practices docs surfaced a subtle idempotency flaw that would have doubled user credits on any webhook retry.

Terms of Service at signup, without duplicating the terms

Adding a legally-required Terms of Service checkbox at signup while keeping a single source of truth for the terms text.

Adding cookie consent

Now I Get It! gets a GDPR-compliant cookie consent banner -- consent-gated Google Analytics, updated privacy policy, and a lesson about deploying feature branches.

Pre-launch bug squash party

Two bugs that slipped through AI-planned, AI-tested development: private page thumbnails returning 403s, and auth cookies silently blocked on Safari, iOS, and Firefox. One was a logic oversight, the other was a fundamental architecture mistake that Claude should have caught.

User galleries and private pages

Turning Now I Get It! from a wholly public site into one where every new paper belongs to its uploader, and the architecture that makes private pages actually private.

Sometimes your AI needs to phone a friend

The homepage carousel was crashing mobile browsers. Fixing it took paginating the API, gutting the DOM, and -- after five failed guesses -- having Claude debug itself with a second Claude.

Are engineers still needed?

There's too much noise about whether software engineers are still needed now that AI can write code. At this point, the answer is yes. This post shows an example of the significant number of design decisions needed to add a single feature to an app.

Defense in Depth: Securing an LLM App Against Its Own Users

Now I Get It! accepts user-uploaded PDFs and user-written instructions, then hands them to Claude. Here's how I built four layers of defense to keep that from going sideways — and how it compares to what Anthropic recommends.

Regex Won't Save You

I replaced Now I Get It!'s regex-based prompt injection filter with a Haiku LLM classifier -- and the difference in catch quality is night and day.

When Users Upload Textbooks

A 449-page machine learning textbook broke Now I Get It!'s upload flow. The fix: stop doing expensive work in a synchronous Lambda.

Adding a Help Page

Now I Get It! has a help page now -- with product info, usage guide, and a support contact form backed by DynamoDB and SNS.

Singleton footer

Now I Get It! had 11 pages with 11 copy-pasted footers. I replaced them with a single JavaScript file -- and learned more about CSS centering than I ever wanted to.

Let Users Drive

Now I Get It! users can now customize how the AI explains a paper -- and the results range from genuinely useful to completely wild.

The Logs That Said Nothing

When Anthropic's API returns an error, you want to know exactly what happened. Now I Get It! was throwing away every useful detail before it reached CloudWatch.

Adding MFA in an Afternoon

Multi-factor authentication used to be a week-long project. With AI-assisted development, I added full TOTP 2FA -- enrollment, recovery codes, multi-device support -- to Now I Get It! in a single session.

Open Coding for AI Evals

Before you can build evals for an AI application, you need to understand how it fails. Now I Get It! now has tooling for systematic open coding of generated pages.

The Chart That Ate the Page

A Chart.js chart grew to 29,000 pixels tall and destroyed an entire page layout. The fix was four lines in a prompt.

Building an Operational Dashboard

Now I Get It! has real users and real data now, but no way to see it all at a glance. Time for a dashboard -- and time for four bugs I didn't expect.

Scrubbing PII from Takedown Notifications

Our takedown notification emails were sending claimants' personal data in plaintext. A quick fix with a bigger lesson about default-open vs. default-closed data handling.

1M Context: Now I Get It! Can Read Bigger Papers

Claude Opus 4.6 now supports 1M tokens at standard pricing, which means Now I Get It! can process much larger scientific papers -- but the screening step needed a workaround.

Adding an RSS Feed (Without Adding Anything)

Now I Get It! blog now has an RSS feed -- and the implementation didn't require a single new AWS resource.

Modularized Deployments

Refactoring two 500-line deploy scripts into modular subcommands -- because waiting through a Docker build to change an HTML page is nobody's idea of fun.

Closing the Takedown Loop

Building an admin dashboard for reviewing copyright takedown requests, then a public status page so reporters can track what happened -- closing both sides of the takedown workflow.

Build Robust BCDR Plan

Now I Get It! had no backups, no deletion protection, and no rollback capability. Here's what it took to make a production app actually recoverable.

Building the Legal Foundation

Privacy policy, terms of service, and DMCA copyright management -- building the legal infrastructure to make science accessible while protecting copyright holders.

Building a Blog, Then Automating It

Adding a full blog system to Now I Get It! and then building a Claude Code skill to automate the entire devlog-to-blog pipeline.

My First Hacker (Before I Even Launched)

Someone found an API endpoint and hit it with a fake request. Here's what I found when I audited everything — and how I fixed it.

Getting Closer to Launch

What goes into launching a product?

Standard Footer and Feedback Thumbs

Adding consistent branding to generated pages and a full feedback widget with thumbs up/down, category selection, and a security-conscious approach to user input sanitization.