Ecommerce Template
Next.js·React 등으로 만든 최신 전자상거래 템플릿
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Alexandre-Luft-Duarte/QueroKf-
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Marketplace agregador de cafés especiais. O QueroKafé não vende café: ele reúne, em um só lugar, os produtos de várias torrefações e marcas, permitindo que o usuário descubra, compare e filtre opções por tipo de grão, torra, processo, região de origem, método de preparo, notas sensoriais e faixa de preço. Ao encontrar o café certo, o usuário é redirecionado para a loja parceira, onde a compra acontece. • Valor para o consumidor: economizar tempo e decidir com mais clareza, sem visitar dezenas de sites. • Valor para a torrefação: visibilidade e tráfego qualificado.README 전문 보기 ↗
Marketplace agregador de cafés especiais. O QueroKafé não vende café: ele reúne, em um só lugar, os produtos de várias torrefações e marcas, permitindo que o usuário descubra, compare e filtre opções por tipo de grão, torra, processo, região de origem, método de preparo, notas sensoriais e faixa de preço. Ao encontrar o café certo, o usuário é redirecionado para a loja parceira, onde a compra do café selecionado acontece.
Escopo deste MVP: camada de descoberta (catálogo, filtros e redirecionamento) + painel administrativo com CRUD completo das entidades. Evoluir para um e-commerce com checkout próprio é uma fase futura.
| Camada | Tecnologia |
|---|---|
| Frontend | Next.js 16 (App Router, React 19, Server Components e Server Actions) + TypeScript + Tailwind CSS 4 |
| Backend | NestJS 12 + TypeScript, validação com class-validator e documentação com Swagger |
| ORM | Prisma 7 com driver adapter @prisma/adapter-pg |
| Banco de dados | PostgreSQL |
| Testes | Vitest (unitários no backend) |
| Monorepo | npm workspaces |
┌──────────────────────┐ HTTP/JSON ┌──────────────────────┐ SQL ┌────────────┐
│ apps/web │ ────────────────────▶ │ apps/api │ ──────────▶ │ PostgreSQL │
│ Next.js (Vercel) │ │ NestJS (Vercel) │ (Prisma) │ (Supabase) │
│ │ ◀──────────────────── │ │ ◀────────── │ │
│ • catálogo público │ │ • CRUD REST │ └────────────┘
│ • painel admin │ │ • validação de DTOs │
│ • Server Actions │ │ • Swagger em /docs │
└──────────────────────┘ └──────────────────────┘
O frontend nunca fala com o banco diretamente: toda leitura e escrita passa pela API REST, através do cliente tipado em apps/web/src/lib/api.ts. As mutações do painel administrativo usam Server Actions do Next.js, que chamam a API no servidor e revalidam o cache das páginas.
Quatro entidades, com relações 1-N e N-N:
Roaster (torrefação) ──1:N──▶ Coffee (café) ──N:N──▶ FlavorNote (nota sensorial)
│
└────N:N──▶ BrewMethod (método de preparo)
| Entidade | Descrição | Campos principais |
|---|---|---|
| Roaster | Torrefação/marca parceira | name, slug, websiteUrl, city, state |
| Coffee | Café anunciado; é o item comparável do catálogo | name, priceCents, weightGrams, beanType, roastLevel, process, origin, scaScore, storeUrl, clickCount |
| FlavorNote | Descritor de sabor (chocolate, caramelo...) | name, slug |
| BrewMethod | Método de preparo (espresso, V60...) | name, slug, description |
Detalhes em apps/api/prisma/schema.prisma. Decisões de modelagem:
Int) evita erros de arredondamento de ponto flutuante.slug único dá URLs legíveis (/cafes/bourbon-amarelo-natural) e filtros compartilháveis.clickCount registra quantos usuários seguiram o link para a loja — a métrica que interessa a um agregador.onDelete: Cascade em Coffee.roaster: remover uma torrefação remove seus anúncios.Catálogo público
Painel administrativo (/admin) — CRUD completo
| Entidade | Criar | Listar | Editar | Excluir |
|---|---|---|---|---|
| Cafés | ✅ | ✅ | ✅ | ✅ |
| Torrefações | ✅ | ✅ | ✅ | ✅ |
| Notas sensoriais | ✅ | ✅ | ✅ | ✅ |
| Métodos de preparo | ✅ | ✅ | ✅ | ✅ |
git clone <url-do-repositorio>
cd QueroKafe
npm install
O npm install na raiz instala as dependências dos dois apps (npm workspaces).
# Backend
cp apps/api/.env.example apps/api/.env
# Frontend
cp apps/web/.env.example apps/web/.env.local
Edite apps/api/.env com as duas URLs do seu banco. No Supabase, clique no botão Connect (topo da página) e abra o card Direct — Connection string:
DATABASE_URL → aba Transaction pooler (porta 6543), usada pela API em runtime;DIRECT_URL → aba Session pooler (porta 5432), usada pelas migrations e pelo seed.Em ambas, troque [YOUR-PASSWORD] pela senha do banco definida na criação do projeto.
npm run db:migrate # cria as tabelas a partir do schema do Prisma
npm run db:seed # popula o banco com torrefações e cafés de exemplo
npm run dev # sobe a API (:3333) e o frontend (:3000) juntos
| Serviço | URL local |
|---|---|
| Frontend | http://localhost:3000 |
| Painel administrativo | http://localhost:3000/admin |
| API | http://localhost:3333/api |
| Documentação Swagger | http://localhost:3333/api/docs |
Para subir os apps separadamente: npm run dev:api e npm run dev:web.
apps/api/.env
| Variável | Obrigatória | Descrição |
|---|---|---|
DATABASE_URL | ✅ | Conexão usada pela API (Transaction pooler, porta 6543) |
DIRECT_URL | — | Conexão usada por migrations e seed (Session pooler, porta 5432). Sem ela, o Prisma usa a DATABASE_URL |
PORT | — | Porta da API (padrão 3333) |
CORS_ORIGIN | — | Origens liberadas, separadas por vírgula. Em produção, a URL do frontend |
apps/web/.env.local
| Variável | Obrigatória | Descrição |
|---|---|---|
NEXT_PUBLIC_API_URL | ✅ | URL base da API, incluindo /api |
Rodados a partir da raiz do projeto:
| Script | O que faz |
|---|---|
npm run dev | Sobe frontend e backend simultaneamente |
npm run build | Compila os dois apps para produção |
npm run test | Executa os testes unitários do backend |
npm run lint | Roda os linters dos dois apps |
npm run db:migrate | Aplica as migrations em desenvolvimento |
npm run db:seed | Popula o banco com dados de exemplo |
npm run db:studio | Abre o Prisma Studio para inspecionar os dados |
npm run db:generate | Regera o Prisma Client |
Base: /api · Documentação interativa (Swagger): /api/docs
| Método | Rota | Descrição |
|---|---|---|
GET | /api/health | Verifica API e conexão com o banco |
GET | /api/coffees | Lista cafés com filtros e paginação |
GET | /api/coffees/:idOrSlug | Detalha um café |
POST | /api/coffees | Cria um café |
PATCH | /api/coffees/:id | Atualiza um café |
DELETE | /api/coffees/:id | Remove um café |
POST | /api/coffees/:idOrSlug/redirect | Contabiliza o clique e devolve a URL da loja |
GET POST | /api/roasters | Lista / cria torrefações |
GET PATCH DELETE | /api/roasters/:id | Detalha / atualiza / remove uma torrefação |
GET POST | /api/flavor-notes | Lista / cria notas sensoriais |
GET PATCH DELETE | /api/flavor-notes/:id | Detalha / atualiza / remove uma nota |
GET POST | /api/brew-methods | Lista / cria métodos de preparo |
GET PATCH DELETE | /api/brew-methods/:id | Detalha / atualiza / remove um método |
Filtros aceitos em GET /api/coffees: search, beanType, roastLevel, process, roaster, brewMethod, flavorNote, minPrice, maxPrice, sort, onlyActive, page, perPage.
Exemplo:
curl "http://localhost:3333/api/coffees?roastLevel=CLARA&maxPrice=7000&sort=nota"
O banco fica no Supabase e os dois apps vão para a Vercel, como dois projetos separados criados a partir deste mesmo repositório — cada um apontando para uma pasta diferente.
apps/api. A configuração vem de apps/api/vercel.json.DATABASE_URL → Transaction pooler do SupabaseDIRECT_URL → Session pooler do SupabaseCORS_ORIGIN → a URL do frontend (preencha depois do projeto 2 existir)prisma migrate deploy antes de compilar, aplicando as migrations pendentes em produção.https://<sua-api>.vercel.app/api/health — deve responder {"status":"ok"}.apps/web.NEXT_PUBLIC_API_URL = https://<sua-api>.vercel.app/api.CORS_ORIGIN com a URL final do frontend, refazendo o deploy dela.A Vercel não mantém um processo ligado: cada requisição invoca uma função. Por isso a API tem
dois pontos de entrada sobre a mesma configuração (app.factory.ts):
src/main.ts — servidor tradicional, usado em desenvolvimento e em qualquer host Node;api/index.js — função da Vercel; um rewrite no vercel.json encaminha todo o /api/* para ela.A instância do Nest é criada uma vez e reaproveitada pelas invocações seguintes da mesma função, o que mantém a conexão com o banco aberta e derruba a latência após a primeira chamada.
Como o backend é um servidor Node comum via
main.ts, ele também roda sem alterações em Render, Railway ou Fly.io — basta usarnpm run buildenpm run start:prod.
QueroKafe/
├── apps/
│ ├── api/ # Backend NestJS
│ │ ├── api/ # Função serverless da Vercel (rota catch-all)
│ │ ├── prisma/
│ │ │ ├── schema.prisma # Modelo de dados
│ │ │ ├── migrations/ # Histórico de migrations
│ │ │ └── seed.ts # Dados de exemplo
│ │ ├── vercel.json # Deploy do backend
│ │ └── src/
│ │ ├── coffees/ # CRUD de cafés + filtros
│ │ ├── roasters/ # CRUD de torrefações
│ │ ├── flavor-notes/ # CRUD de notas sensoriais
│ │ ├── brew-methods/ # CRUD de métodos de preparo
│ │ ├── prisma/ # PrismaService (conexão)
│ │ ├── health/ # Health check
│ │ ├── app.factory.ts # CORS, validação e Swagger (compartilhado)
│ │ └── main.ts # Servidor local
│ │
│ └── web/ # Frontend Next.js
│ ├── vercel.json # Deploy do frontend
│ └── src/
│ ├── app/
│ │ ├── page.tsx # Catálogo com filtros
│ │ ├── cafes/[slug]/ # Detalhe do café
│ │ ├── torrefacoes/ # Torrefações parceiras
│ │ └── admin/ # Painel CRUD + Server Actions
│ ├── components/ # Componentes de UI
│ └── lib/ # Cliente da API, tipos e formatadores
│
└── package.json # Workspaces e scripts
Projeto acadêmico desenvolvido para a disciplina de desenvolvimento web.