Jimmy Joy Taste Lab
Built for product development and QA at a nutrition brand. Try the demo, no sign-in ↗ · What the demo shows
🔍 Overview
Taste Lab replaces the spreadsheet round of product tasting. An organiser prepares a tasting, gives each sample a blind code, and either assigns colleagues or shares a participation link. Participants rate the samples on their phone, can revise an answer until they submit, and see their own results only. When the organiser closes the round, the app writes a fixed report snapshot: the numbers can no longer move after the fact, and the report exports to CSV or print.
What started as one tasting screen now holds three workspaces that share the same products, templates and member list: new product development, QA comparisons, and a shelf life archive.
👀 Have a look yourself
The app itself needs a company account, but the participant screen is open to anyone at /demo. It is the real tasting interface on a made-up round: five blind samples of one product, five attributes each, rated from 0 to 10.
- Rate the samples, skip one, then open Review answers and jump back to anything you want to change.
- Skip a sample or give an unusual score and the form asks you to say why before you continue.
- Your draft is kept in that browser, so you can close the tab and come back to it.
- Open it in two tabs and the second one warns you instead of overwriting the first.
Nothing in the demo touches the real database. There is no account, no tasting record and no organiser on the other side; everything stays in your own browser and resets when you clear it.
🧪 The three workspaces
- Development tastings: blind samples with automatic sample codes, a shared product list, named templates, and a compare view for 2 to 6 closed rounds of the same product.
- QA tests: a fixed comparison format with odour, appearance, colour, flavour, sweetness and texture on a five level difference scale, plus comparison photos stored privately in the database.
- Shelf life: an archive of stored versus control samples with dates, batch, storage and timepoint, a 0 to 100 severity index per attribute, and trend comparison across tests.
📊 Reports people can actually read
Closing a tasting snapshots only the submitted answers. Blank answers stay blank, zero stays a valid score, and skips are left out of the summary instead of being counted as a low rating. Every report keeps its own ALL, Amsterdam and Malta view, so a difference between the two offices stays visible instead of being averaged away.
An organiser can also publish one AI report on a random public link. Claude writes the narrative; every number comes from the app's own calculation, not from the model. Only titles, products, sample codes, scale labels and aggregated scores go into the public payload. Source rows, participant fields and raw comments do not. Known names, emails and URLs are removed from comment fragments before analysis and from the narrative afterwards, and the text is labelled as AI generated.
🔒 Access and safety
- Management screens need a verified Google identity plus an explicitly granted, active membership. There is no open sign-up.
- A tasting can separately allow guests through a link with a self reported name. Guests submit their own answers and see nothing else. Turning the link off revokes their reads and writes.
- Every write is validated and audited in PostgreSQL, under row level security, with an assignment wide revision and a serial browser queue so two tabs cannot overwrite each other.
- Public report links can be revoked, and a reopened tasting marks its published report as historical.
🛠️ How it is built
Next.js on Vercel in front of Supabase, with the real logic in SQL functions and row level security rather than in the client. Database tests run against an isolated PostgreSQL engine with mock auth identities, so permissions and lifecycle rules are tested under actual database roles. Browser tests cover both the organiser and the participant side, including rejection of unauthenticated API and export requests.
Background work is persisted in PostgreSQL: report jobs take a three minute worker lease, checkpoint per location, count attempts and keep a safe error history, so a terminated invocation resumes where it stopped instead of starting a fresh billable run.
The full app ↗ needs a company account, so it opens on the sign-in screen.