https://github.com/teles/gitkut
https://github.com/teles/gitkut
Last synced: 24 days ago
JSON representation
- Host: GitHub
- URL: https://github.com/teles/gitkut
- Owner: teles
- Created: 2026-05-10T08:10:15.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-05-11T00:05:28.000Z (2 months ago)
- Last Synced: 2026-05-11T02:18:58.608Z (2 months ago)
- Language: TypeScript
- Size: 234 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Gitkut
Gitkut e uma pagina social retro para devs, usando dados publicos do GitHub.
Esta implementacao inicial roda localmente com:
- `api/`: Cloudflare Worker + Hono + TypeScript + Wrangler, OAuth com GitHub e cookies `httpOnly`
- `web/`: Nuxt, tela de login e pagina retro do perfil
## Estrutura
```text
gitkut/
├─ api/
└─ web/
```
## Criar OAuth App no GitHub
1. Acesse GitHub > Settings > Developer settings > OAuth Apps.
2. Clique em "New OAuth App".
3. Use estes valores para desenvolvimento local:
- Application name: `Gitkut Local`
- Homepage URL: `http://localhost:5173`
- Authorization callback URL: `http://localhost:8787/auth/github/callback`
4. Copie o `Client ID`.
5. Gere um `Client secret`.
Para producao, use outro OAuth App ou atualize o app de producao com:
- Application name: `Gitkut`
- Homepage URL: `https://gitkut.com`
- Authorization callback URL: `https://api.gitkut.com/auth/github/callback`
GitHub OAuth Apps aceitam apenas uma callback URL cadastrada. Por isso, o fluxo
mais simples e ter um OAuth App para local e outro OAuth App para producao. Se o
GitHub mostrar que o `redirect_uri` nao esta associado ao app, confira se o
`Client ID` usado no Cloudflare pertence ao app cuja callback URL e
`https://api.gitkut.com/auth/github/callback`.
## Configurar ambiente
Backend:
```bash
cd api
cp .env.example .env
```
Edite `api/.env`:
```env
GITHUB_CLIENT_ID="seu_client_id"
GITHUB_CLIENT_SECRET="seu_client_secret"
GITHUB_CALLBACK_URL="http://localhost:8787/auth/github/callback"
FRONTEND_URL="http://localhost:5173"
CORS_ALLOWED_ORIGINS="http://localhost:5173,http://127.0.0.1:5173"
COOKIE_SECURE="false"
COOKIE_SAME_SITE="Lax"
```
O backend usa somente `api/.env` no desenvolvimento local. Nao mantenha um
segundo arquivo `api/.dev.vars`, para evitar configuracoes divergentes.
`CORS_ALLOWED_ORIGINS` aceita uma lista separada por virgula quando houver
mais de uma origem web autorizada a chamar a API com cookies.
Frontend:
```bash
cd web
cp .env.example .env
```
O front usa apenas a URL publica da API local:
```env
NUXT_PUBLIC_API_URL=http://localhost:8787
NUXT_PUBLIC_USE_MSW=false
```
## Instalar dependencias
Na raiz do projeto:
```bash
pnpm install
```
Isso instala as dependencias de `api/` e `web/`.
Se preferir instalar separadamente:
```bash
pnpm --dir api install
pnpm --dir web install
```
## Rodar localmente
Terminal 1:
```bash
pnpm dev:api
```
API local: `http://localhost:8787`
Terminal 2:
```bash
pnpm dev:web
```
Web local: `http://localhost:5173`
Depois abra `http://localhost:5173` e clique em "Entrar com GitHub".
## Frontend tooling
O frontend usa Nuxt em modo hibrido no Cloudflare Pages: a home autenticada
continua client-side e os perfis publicos de um segmento, como `/teles`, podem
ser renderizados com SSR na edge.
Storybook:
```bash
pnpm storybook:web
```
Storybook local: `http://localhost:6006`
Build do frontend:
```bash
pnpm build:web
```
Build do Storybook:
```bash
pnpm build-storybook:web
```
Qualidade:
```bash
pnpm format:check
pnpm test:web
pnpm typecheck:web
```
Para simular a API no frontend local com MSW:
```bash
cd web
NUXT_PUBLIC_USE_MSW=true pnpm dev
```
Sem `NUXT_PUBLIC_USE_MSW=true`, o frontend continua usando a API real em
`NUXT_PUBLIC_API_URL`.
## Backend Worker
O backend roda como Cloudflare Worker local via Wrangler.
Healthcheck:
```bash
curl http://localhost:8787/health
```
Typecheck:
```bash
pnpm typecheck:api
```
Testes:
```bash
pnpm test:api
```
D1 migrations:
```bash
pnpm db:migrations:local
pnpm db:migrations:remote
```
Deploy futuro:
```bash
pnpm deploy:api
```
Quando o Worker estiver conectado ao GitHub pelo Cloudflare Builds usando a
raiz do monorepo, configure o comando de deploy como:
```bash
pnpm run deploy
```
ou:
```bash
pnpm deploy:api
```
Nao use `npx wrangler deploy` na raiz do repositorio: o Wrangler nao consegue
detectar qual aplicacao do workspace deve ser publicada. Tambem evite
`pnpm deploy` sem `run`, porque esse e um comando nativo do pnpm, nao o script
do projeto. Se preferir configurar o root directory do build como `api/`, use
`pnpm deploy` dentro desse diretorio.
Deploy do frontend no Cloudflare Pages:
```bash
pnpm build:web:prod
pnpm deploy:web
```
O build Nuxt para Cloudflare Pages gera a saida em `web/dist`, que e o
diretorio publicado no deploy direto. Headers de seguranca para assets
estaticos ficam em `web/public/_headers`; respostas SSR tambem recebem esses
headers por `web/server/middleware/security-headers.ts`.
URLs atuais:
- Frontend: `https://gitkut.com`
- Perfil publico exemplo: `https://gitkut.com/teles`
- Backend Worker: `https://api.gitkut.com`
- Callback OAuth de producao: `https://api.gitkut.com/auth/github/callback`
Em producao, configure as variaveis no Cloudflare e use secrets para valores
sensiveis:
```bash
cd api
pnpm wrangler secret put GITHUB_CLIENT_ID
pnpm wrangler secret put GITHUB_CLIENT_SECRET
```
Veja tambem `api/README.md` para os detalhes do Worker.
## Banco D1
O backend usa um banco Cloudflare D1 chamado `gitkut-db`, exposto no Worker
pelo binding `DB`.
A primeira migration cria a base social do Gitkut:
- `users`: vinculo local com o usuario do GitHub.
- `profiles`: dados editaveis do perfil Gitkut.
- `featured_repos`: repositorios fixados pelo usuario.
- `scraps`: recados entre perfis.
- `communities` e `user_communities`: comunidades e participacao.
- `badges` e `user_badges`: trofeus e conquistas.
- `profile_views_daily`: views agregadas por dia.
Durante o callback OAuth, o Worker sincroniza o usuario autenticado em
`users` e cria um `profiles` inicial quando ainda nao existir.
## Perfis publicos
Cada perfil publico usa o `slug` salvo em `profiles.slug`.
Exemplo:
```text
https://gitkut.com/teles
```
O frontend trata URLs com um unico segmento como perfil publico, exceto slugs
reservados do produto como `api`, `auth`, `settings`, `communities`,
`profile`, `repos`, `privacy` e `terms`.
Com SSR habilitado no Nuxt, essas rotas publicas sao atendidas pela propria
rota `web/src/pages/[slug].vue`, sem fallback de SPA em `_redirects`.
## Rotas da API
- `GET /health`: retorna `{ "ok": true }`.
- `GET /auth/github`: redireciona para o login do GitHub.
- `GET /auth/github/callback`: recebe o `code`, troca por `access_token`, salva o token em cookie `httpOnly` e volta para o front.
- `POST /auth/logout`: remove o cookie local de autenticacao.
- `GET /api/me`: retorna dados basicos do usuario autenticado.
- `GET /api/profile`: retorna o perfil Gitkut salvo no D1 para o usuario autenticado.
- `GET /api/profiles/:slug`: retorna um perfil publico salvo no D1 e repos publicos recentes do GitHub.
- `GET /api/repos`: retorna repositorios publicos recentes do usuario autenticado.
O `GITHUB_CLIENT_SECRET` fica somente no backend. O frontend nunca recebe nem envia esse valor.