Project · Antimony
Fruugle
Untamed truth, for buyers who refuse to be fooled twice.
Essence
For the people who use it
Fruugle is a consumer-reporting platform for South Africa — the place where misleading ads, fake discounts and false product claims live in the open instead of being buried in private chat groups or one-star reviews nobody reads. The point is reach: a Fruugle report surfaces where the next buyer is already looking — Google.
Submitting takes about thirty seconds. Three required fields — product, store, what happened — and the system auto-tags the category and normalises the retailer name. Pages are SEO-engineered so that when somebody searches the product name a few hours later, the report is there. Vote "this happened to me too" to push the most common issues up. Add a comment, attach a photograph of the receipt or the packaging.
Existing review sites are either company-focused (HelloPeter), siloed inside a single marketplace (Takealot), or built for global commerce nowhere near the SA market. Fruugle is built for the South African shopper, on the South African retailer landscape, designed to be found by Google at the moment of decision.
- 30-second submissions — three fields, AI auto-tags the rest.
- SEO-engineered report pages designed to rank for product names.
- Sitemaps + IndexNow — Bing and Yandex notified the moment a report publishes.
- Full-text search with store and category filters across thousands of reports.
- Community voting — "this happened to me too" surfaces the most common issues.
- Threaded comments with nested replies.
- Image proof uploads — receipts, packaging, before/after screenshots.
- Mobile-first design for phone-based reporting while still in the store.
- Google / Facebook OAuth sign-in to keep submissions accountable.
Construction
For the engineers
Stack
- Frontend
- Next.js 16 · React 19 · TypeScript · Tailwind v4 (PostCSS)
- API
- ASP.NET Core 10 minimal API on .NET 10 · C#
- Data access
- Dapper — raw, parameterised SQL
- Database
- MS SQL Server with native full-text search
- Auth
- Google & Facebook OAuth · JWT (HMAC)
- Host
- Windows · IIS + Kestrel · Node reverse proxy for the SSR app
- Testing
- xUnit + Moq on the API · Vitest on the frontend
Architecture
Two-app monorepo. src/api (the .NET backend) and src/web
(the Next.js frontend) live side by side under one repo but deploy independently — each has its own
pipeline and its own version stamp. They share nothing at the language level; the contract between
them is the OpenAPI document the API publishes.
.NET Minimal APIs without controllers. Endpoints are static methods grouped by domain
in Endpoints/*.cs files and registered through extension methods in Program.cs.
No controller classes, no implicit routing magic — every route is one method, found in one place,
debugged in seconds.
Dapper, raw SQL, schema as code. No EF Core; nothing migrated from a model. SQL
lives in numbered files under database/migrations/. A DbConnectionFactory
singleton hands out connections; scoped repositories use them and map rows to records. The schema
in source control is the schema.
SEO automation as a first-class concern. AutoTagService normalises
store names against a South African retailer alias table and auto-assigns categories.
SeoMetadataService builds schema.org markup for every report. SlugService
produces stable URL slugs. On publish, the site pings IndexNow so Bing and Yandex index immediately;
the sitemap regenerates incrementally rather than wholesale.
Next.js App Router, dual fetch. serverFetch() drives ISR
(60-second revalidation) for public report pages so they're fast and cheap to serve;
apiFetch() handles authenticated client-side calls. A custom JWT middleware on the API
side puts UserId into context.Items for endpoints to read.
Notable details
- SA retailer alias normalisation — "PnP", "Pick n Pay", "Pick-n-Pay" all resolve to one store.
- Rate-limited auth endpoints prevent spam submissions.
- Structured
AppErrorhelpers keep error responses consistent and discoverable. - ISO 8601 timestamps throughout — no timezone ambiguity, ever.
- Image storage on disk, served through a dedicated
ImageEndpointsgroup. - MS SQL native full-text indexes on product name, store and description.
- Entity / DTO separation — C# records for DTOs, classes for entities.
- Automatic SEO metadata generation on every report creation.