World Vibe Web
The distributed app store for vibe-coded projects. Browse, discover, and install open-source apps from across GitHub.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證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.