MILWEB®
MILWEB®
MW/026E-COMMERCE DO AGROSTUDIO

E-commerce do Agro

E-commerce do Agro — home screen
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.

03 / EXPERIENCE
  1. 01 / 01

    Route → controller → service → repository with raw SQL via mysql2; Sequelize only runs migrations via CLI.

    E-commerce do Agro — 01
  2. 02 / 02

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

    E-commerce do Agro — 02
  3. 03 / 03

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

    E-commerce do Agro — 03
  4. 04 / 04

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

    E-commerce do Agro — 04
Full web system · e-commerce + dashboards

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 WITHNext.js · Node.js · Express · MySQL · DockerCODECODE

06 / RESULT

5 role-based panels · documented API

STUDY PROTOTYPE

[ I WANT SOMETHING LIKE THIS ]

NEXT EXPERIENCE20 / AKATSUKI

Akatsuki

Akatsuki

ALL WORK

ALL WORK