No description
  • TypeScript 59.5%
  • JavaScript 22.2%
  • Python 7.3%
  • PLpgSQL 4.3%
  • Astro 3.9%
  • Other 2.8%
Find a file
2026-03-26 12:28:12 -03:00
.github/workflows changes coming 2026-03-24 15:23:12 -03:00
apps use native terminal ansi viewer and soften web meta persist 2026-03-26 11:07:34 -03:00
docs use native terminal ansi viewer and soften web meta persist 2026-03-26 12:28:12 -03:00
e2e better render 2026-03-25 20:17:11 -03:00
infra better render 2026-03-25 20:17:11 -03:00
packages use native terminal ansi viewer and soften web meta persist 2026-03-26 11:16:56 -03:00
supabase better render 2026-03-25 20:17:11 -03:00
.editorconfig fix lint 2026-03-24 16:00:10 -03:00
.env.example fix lint 2026-03-24 16:00:10 -03:00
.env.install.example changes coming 2026-03-24 15:23:12 -03:00
.gitattributes fix lint 2026-03-24 16:00:10 -03:00
.gitignore still working on 2026-03-24 13:24:36 -03:00
biome.json fix lint 2026-03-24 16:00:10 -03:00
package.json changes coming 2026-03-24 15:23:12 -03:00
playwright.config.cjs changes coming 2026-03-24 15:23:12 -03:00
pnpm-lock.yaml avoid \\u0000 in ansi source upload 2026-03-26 10:43:34 -03:00
pnpm-workspace.yaml fix lint 2026-03-24 16:00:10 -03:00
README.md squarix 2026-03-24 19:38:09 -03:00
tsconfig.base.json first commit 2026-03-23 20:04:16 -03:00
turbo.json changes coming 2026-03-24 15:23:12 -03:00

runv-square

Monorepo terminal-first para “squares” (praças) públicas/privadas no ecossistema runv.club.
Fonte canónica: Markdown + frontmatter + blocos fenced (ascii, ansi, links, note). ANSI/HTML são alvos de render, não o modelo de dados.

Stack

  • pnpm workspaces + Turborepo (turbo.json com envMode: "loose" para .env chegar aos dev tasks, p.ex. webServer do Playwright)
  • Supabase (Postgres + Auth + Storage) — sem SQLite/Prisma para dados de negócio
  • apps/api: Fastify
  • apps/web: Astro (SSR, leitura pública)
  • apps/worker: jobs de render + snapshots
  • apps/cli: Commander + @runv-square/sdk + @runv-square/linux-identity (resolução de utilizador Linux)
  • @runv-square/identity-adapters: portas tipadas (stub) para um futuro runv-server / bridge SSH
  • @runv-square/i18n: UI pt-BR en + mensagens API/CLI (conteúdo de posts multilingue não é obrigatório em v1)
  • Biome + Vitest + TypeScript strict

Desenvolvimento local e segurança

  • O stack supabase start usa chaves JWT conhecidas e expõe Studio / pgMeta / APIs sem o mesmo modelo de auth que produção — trata como máquina de dev apenas; ver Segurança do Supabase local em docs/local-dev.md.
  • API e Astro dev escutam por defeito em 127.0.0.1; API_HOST=0.0.0.0 só quando precisares de LAN ou contentores.
  • db reset com erro 502 após migrações: ver a tabela Troubleshooting em docs/local-dev.md.
  • pnpm smoke:local: o .env na raiz deve apontar para o stack local (SUPABASE_URL=http://127.0.0.1:54321 e chaves de supabase status); ver .env.example. Evita trabalhar só em /mnt/z/... ou outros mounts lentos no WSL — preferir clone em ~/... (detalhes em docs/local-dev.md).
  • pnpm install corre um postinstall na raiz que garante o Chromium do Playwright (necessário para pnpm test:e2e / pnpm smoke:local) além do CLI local do Supabase.

Chaves Supabase (env)

Ambiente Variáveis Uso
Hosted (produção) SUPABASE_PUBLISHABLE_KEY, SUPABASE_SECRET_KEY Alinhado às chaves “anon” / “service role” do dashboard
Local (supabase start) SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY Saídas de supabase status
  • Nunca colocar SUPABASE_SECRET_KEY / SUPABASE_SERVICE_ROLE_KEY no frontend ou bundles client.
  • Web só chama leituras públicas (ex.: API_URL + endpoints GET).

Comandos (raiz)

Script Descrição
pnpm dev turbo dev (API, worker, web em paralelo)
pnpm build Build de todos os pacotes
pnpm lint Biome
pnpm typecheck TypeScript
pnpm test Vitest (parser/renderers)
pnpm db:start supabase start (CLI instalado pelo pnpm install; não precisa de supabase global)
pnpm db:stop supabase stop
pnpm db:restart supabase stop && supabase start (útil após db:reset falhar com 502 apesar do SQL ter corrido)
pnpm db:reset Reset com retry: se falhar (ex. 502 no storage após reiniciar contentores), faz stop → start e volta a tentar
pnpm db:reset:raw supabase db reset sem retry (uma única tentativa)
pnpm db:reset:debug Igual ao db:reset mas com --debug no CLI Supabase em cada tentativa
pnpm db:typegen:local Gera packages/db-types/src/database.types.ts a partir do stack local
pnpm db:typegen:project Gera tipos a partir do projeto hosted (SUPABASE_PROJECT_REF)
pnpm test:e2e Playwright E2E (requer Supabase local + .env completo; ver docs)
pnpm smoke:local db:start + db:reset + typegen + E2E (Docker acessível); a API do smoke usa 3011 por defeito (SMOKE_API_PORT). O runner playwright-smoke.mjs define ENABLE_DEV_PROTOTYPE=true por defeito (global-setup cria boletim-da-escada, Astro mostra o herói na home). Para smoke sem protótipo: ENABLE_DEV_PROTOTYPE=false pnpm smoke:local
pnpm smoke:local:debug Igual ao smoke, mas db:reset com --debug (Supabase); não confundir com pnpm smoke:local --debug (só Playwright)
pnpm smoke:prototype Equivalente ao fluxo de smoke:local com modo desenvolvimento explícito (ENABLE_DEV_PROTOTYPE=true no ambiente antes do pnpm); mantido como atalho legível
pnpm prototype:seed Só corre com ENABLE_DEV_PROTOTYPE=true: insere o square de protótipo e posts (service role); caso contrário sai sem tocar na BD
pnpm prototype:bootstrap db:start + db:reset + db:typegen:local + seed de protótipo (flag ligada só no passo do seed)

Ver Dev prototype — nunca definir ENABLE_DEV_PROTOTYPE em produção.

Test readiness

Critérios para considerar o projeto pronto para testes de integração local (todos devem passar):

  1. pnpm build — build do monorepo
  2. pnpm lint — Biome
  3. pnpm typecheck — TypeScript
  4. pnpm test — testes unitários (incl. Vitest na API)
  5. pnpm test:e2e — E2E (com supabase start + chaves no .env; com stack local também SUPABASE_JWT_SECRET para HS256; hosted pode omitir — JWKS; ver docs/local-dev.md)
  6. Fluxo seed E2E (e2e/global-setup.cjs) — perfil, square pública, draft, publicado, job de render
  7. Worker processa publish/render (snapshot HTML/ANSI disponível via API)
  8. Rotas web localizadas (/en/..., /pt-br/...) mostram conteúdo publicado
  9. Rotas API mutáveis exigem JWT verificado (não stub)

Resumo da implementação: did2.md.

Typegen

Após pnpm db:reset ou com o stack local a correr:

pnpm db:typegen:local

Isto mantém packages/db-types como fonte única de tipos de linhas SQL para API, worker e SDK.

Identidade local (Debian / Linux)

  1. API com RUNV_LOCAL_IDENTITY_SECRET (obrigatório se NODE_ENV=production; em dev a API usa um valor inseguro por defeito — ver docs/local-dev.md).
  2. No mesmo host que a API (ou túnel só para loopback), corre square init (alias: runv-square init) com API_URL, RUNV_LOCAL_IDENTITY_SECRET e stack Supabase acessível. O CLI resolve o utilizador via getent passwd / passwd e chama POST /identity/local/init (só aceite de 127.0.0.1 / ::1 + segredo no header).
  3. Grava a sessão: export RUNV_ACCESS_TOKEN="..." (impresso no stderr após o JSON de resposta).
  4. Comandos autenticados: square whoami, square profile:sync, square square:personal, square square:create, square posts:*.

O CLI é instalado com dois nomes:

  • square para uso diário
  • runv-square como nome explícito/compatível

Ao correr apenas square, o CLI mostra um onboarding colorido e localizado, explicando o que é um square, o square pessoal de cada utilizador e o fluxo básico para publicar pelo terminal.

Fluxo rápido de publicação por ficheiro:

square nota.md --publish
square nota.ans --square mural-da-oficina --visibility public --publish
square squares:view mural-da-oficina
square posts:read mural-da-oficina nota
square posts:list
square posts:update ID --title "Novo título"
square posts:delete ID

Fluxo rápido de administração local do host:

square admin:profiles:list
square admin:squares:list
square admin:posts:list --status draft
square admin:posts:read POST_ID
square admin:posts:update POST_ID --publish
square admin:jobs:list --status failed
square admin:jobs:requeue POST_ID --target all

Ver também docs/future-runv-server-identity.md (não implementado).

Documentação

Licença

runverse