E-commerce do Agro

- STUDIO
- MILWEB
- TYPE
- DIGITAL PRODUCT
- STATUS
- STUDY PROTOTYPE
02 / THE IDEA
Full web system · e-commerce + dashboards
An agribusiness needed far more than a store: sales, payments, deliveries and role-based management.
01 / 01
Route → controller → service → repository with raw SQL via mysql2; Sequelize only runs migrations via CLI.

02 / 02
Admin, store, broker and producer each with their own HttpOnly cookie, coexisting in the same browser, with impersonation.

03 / 03
Contracts closed via ClickSign v3, HMAC-validated webhook, provider swappable via environment variable.

04 / 04
Coffee Market module with 4-role RBAC per broker and SaaS plans billed through Asaas.

01
02
03
04
04 / UNDER THE HOOD
01The project is split into two repositories (frontend and backend) that only talk over HTTP, with no cross-imports and no shared package. The…+
The project is split into two repositories (frontend and backend) that only talk over HTTP, with no cross-imports and no shared package. The backend is a Node.js/Express REST API with a strict layered architecture: thin route, controller, service and repository, no exceptions. Data access uses a raw mysql2 pool, and Sequelize is in the project exclusively to run migrations via CLI (db:migrate, db:status). There isn't a single Model.findAll() in application code: it's direct SQL by a documented, deliberate project decision, so future contributors don't reach for an ORM that isn't there. Every HTTP response follows one contract ({ ok, data, code, message, meta }) and every expected error becomes an AppError caught by a global handler, never a bare res.json() or an inline res.status(4xx).
02The domain goes far beyond cart and checkout. There are four fully independent authentication contexts, each with its own HttpOnly cookie, m…+
The domain goes far beyond cart and checkout. There are four fully independent authentication contexts, each with its own HttpOnly cookie, middleware and login endpoint: admin, store customer, coffee broker ("corretora") and rural producer. All four coexist in the same browser, so an admin can enter impersonation mode inside a broker's panel without losing their own session. The producer doesn't even use a password: they sign in via a magic link with an HMAC-signed, short-TTL token, a flow designed for a rural audience with low digital familiarity. On top of the traditional store (products, drones, cart, Mercado Pago checkout) sits an entire B2B module, the "Coffee Market", with an internal 4-role RBAC inside each broker account (owner/manager/sales/viewer), SaaS plans billed through Asaas, and bot protection (Turnstile) on the public lead-capture forms.
03Contracts between broker and producer are closed with real electronic signature: integration with ClickSign's v3 API, a webhook validated by…+
Contracts between broker and producer are closed with real electronic signature: integration with ClickSign's v3 API, a webhook validated by an HMAC secret, and a swappable provider set via environment variable (CONTRATO_SIGNER_PROVIDER=stub in staging, clicksign in production). It's one switch instead of stub logic scattered through the code. Security carries real weight on the backend: CSRF via double-submit cookie, adaptive rate limiting with Redis and an in-memory fallback if Redis goes down, and a deliberately non-obvious middleware order in server.js. Helmet sets Cross-Origin-Resource-Policy: same-origin by default, and the override that serves cross-origin media under /uploads has to come after it, or assets simply stop loading from another domain.
04On the frontend, Next.js 15 (App Router) separates public data fetching into server-only fetchers under src/server/data/ (RSC, cache: no-sto…+
On the frontend, Next.js 15 (App Router) separates public data fetching into server-only fetchers under src/server/data/ (RSC, cache: no-store) from anything tied to a user session, which is resolved in Client Components through a custom apiClient that fully replaced Axios. It auto-injects the x-csrf-token header on mutations and centralizes errors as a typed ApiError. Media uploads flow through a single backend mediaService that abstracts local disk, S3 and GCS behind an environment variable, and the frontend never hand-builds an image URL: it always goes through absUrl(), which normalizes whatever path shape the backend returns. Tests cover both sides (Jest and Supertest on the backend with a dedicated test database; Vitest and Testing Library on the frontend). The project is openly a self-study prototype and doesn't run in production for a real client, but it was built with the architectural discipline of a system that would need to scale across multiple brokers and real coffee-producing regions.
BUILT WITH — Next.js · Node.js · Express · MySQL · DockerCODE ↗CODE ↗
06 / RESULT
Akatsuki
