feat(#291): Loja do Baluarte — /loja (Shopify, print-on-demand)#293
Draft
Lucas-Belucci-Bellini wants to merge 9 commits into
Draft
feat(#291): Loja do Baluarte — /loja (Shopify, print-on-demand)#293Lucas-Belucci-Bellini wants to merge 9 commits into
Lucas-Belucci-Bellini wants to merge 9 commits into
Conversation
Aplica a migration do contador de acessos (0002_site_stats) no projeto Supabase oficial via MCP: a tabela site_stats e a funcao bump_visits() passam a existir, entao a celula "N visitas ao Baluarte" no Home mostra numero real (antes a migration so estava versionada, nao aplicada). Verificado ponta-a-ponta como anonimo pela REST publica: - GET site_stats -> 200 (leitura publica) - POST rpc/bump_visits -> 200 (escrita anonima SEGURA via SECURITY DEFINER) - POST site_stats (direto) -> 401 (RLS bloqueia escrita direta) Contador zerado ao final (visitas reais comecam limpas). Adiciona docs/SUPABASE.md como fonte unica do backend: projeto/credenciais (publicas por design), postura RLS, estado das migrations, 3 jeitos de aplicar (dashboard/MCP/CLI), SQL copy-paste de 0001/0002, verificacao por curl e o passo do login OTP (#288). Atende ao pedido da #291 (secao 2). Advisor registrado pra revisar: funcao pre-existente rls_auto_enable() (SECURITY DEFINER, executavel por anon) que nao vem das migrations do repo. Claude-Session: https://claude.ai/code/session_01WVGexdsK5EK86CD3QWkHoQ Co-authored-by: Claude <noreply@anthropic.com>
Adiciona uma seção "Meu Acervo" no topo da /musicas onde o usuário adiciona os PRÓPRIOS arquivos de áudio (arrastar ou escolher). Eles ficam guardados só no aparelho (IndexedDB) e tocam OFFLINE, em qualquer rede — inclusive nas que bloqueiam Spotify/YouTube. Cumpre o objetivo norteador do operador (#291 §3): ouvir em qualquer lugar, independente do WiFi, o que embed de servico externo nunca garante. - src/utils/offline-audio.js: store IndexedDB (add/list/get/remove/clear), sem dependencias; os bytes ficam no aparelho, nada pesa no bundle (#238). - src/pages/musicas.js: player nativo <audio> com playlist, proxima/ anterior, repetir lista e remover; lista e loop persistem. - src/styles/musicas.css: estilos no padrao dos tokens. Verificado no navegador (Playwright): a secao renderiza apos o heroi e o round-trip no IndexedDB funciona (adicionar -> listar -> ler blob 4096 B -> remover). Build limpo. Claude-Session: https://claude.ai/code/session_01WVGexdsK5EK86CD3QWkHoQ Co-authored-by: Claude <noreply@anthropic.com>
…_auto_enable
Auditoria do banco (Supabase) via MCP revelou que public.rls_auto_enable()
é uma FUNCAO DE EVENT TRIGGER (gatilho ensure_rls, em ddl_command_end) que
liga RLS automaticamente em toda tabela nova do schema public — bom trilho
de seguranca. Mas, por ser SECURITY DEFINER no schema public, o PostgREST a
expunha como RPC (/rest/v1/rpc/rls_auto_enable) chamavel por anon. A chamada
direta e inocua (so funciona em contexto de event trigger), mas e exposicao
desnecessaria e o linter alertava (0028/0029).
Migration 0003_db_hardening: revoga EXECUTE de anon/authenticated/public.
Nao quebra o event trigger (roda como dono). Aplicada e verificada:
has_function_privilege('anon', 'rls_auto_enable()') -> false; os 2 avisos
do advisor pra ela sumiram (5->3 lints). bump_visits mantem o anon (by-design).
docs/SUPABASE.md atualizado (migration 0003 + SQL + explicacao do event
trigger + status dos advisors).
Claude-Session: https://claude.ai/code/session_01WVGexdsK5EK86CD3QWkHoQ
Co-authored-by: Claude <noreply@anthropic.com>
Conta views por pagina no banco oficial (reusa site_stats com chaves
view:/rota) e exibe no Home (linha "PAGINAS · N paginas vistas · top
/rota") e numa tile do /perfil. Numero real, global e duravel.
- Migration 0004_page_views: funcao bump_view(rota) SECURITY DEFINER,
escrita anonima SEGURA, com VALIDACAO da rota (^/[a-z0-9/_-]{0,63}$)
pra nao criar chave-lixo. Aplicada e verificada por REST: incrementa
(1->2), rota invalida -> 400, escrita direta -> 401 (RLS).
- src/utils/page-views.js: countPageView (1x/rota/sessao via RPC) +
readPageViews (top rotas + total).
- main.js: conta a view no route:change (best-effort, nao bloqueia).
- home.js + perfil.js: exibem o total (degradam em silencio se o banco
nao responder).
web leve (#238): ~1 KB no boot; os dados ficam no banco. Build limpo.
docs/SUPABASE.md atualizado (migration 0004 + bump_view + chaves view:).
Claude-Session: https://claude.ai/code/session_01WVGexdsK5EK86CD3QWkHoQ
Co-authored-by: Claude <noreply@anthropic.com>
Nova rota /banco (sidebar > Sistema) que le numeros reais do Supabase por leitura publica (RLS) e os mostra num painel: visitas, paginas vistas (total + distintas), top paginas (com barras) e posts no mural. Faz a fundacao do banco aparecer no proprio site, sem abrir o dashboard. - src/pages/banco.js + src/styles/banco.css (read-only, sem deps; chunk 3.2 kB / 1.4 kB gz, lazy). Degrada em silencio se o banco nao responder (tiles viram "—" + aviso). - main.js: registra a rota. icons.js: /banco -> icone de linha database. sidebar.js: entrada "Painel do Banco" no grupo Sistema. Verificado no navegador: header/tiles/secoes renderizam; estado de indisponivel confirmado (o browser do sandbox nao alcanca o banco — popula em producao, igual ao contador de acessos). Build limpo. Claude-Session: https://claude.ai/code/session_01WVGexdsK5EK86CD3QWkHoQ Co-authored-by: Claude <noreply@anthropic.com>
…vem) Base pra cada visitante ter a SUA estética (tema + skin de universo) e favoritos salvos na nuvem, via Supabase Auth (Google) — escolha do operador. Banco (migration 0005_profiles, aplicada e verificada): - tabela profiles (id = auth.users.id, display_name, theme, universe, favorites jsonb, prefs jsonb) com RLS DONO-SO (auth.uid() = id). - trigger handle_new_user cria o perfil no cadastro; EXECUTE da funcao de trigger revogado (higiene, igual 0003). - verificado: policies/trigger/RLS on; anon GET -> []; anon insert -> 401. Cliente sem SDK (web leve #238): - src/core/supabase-auth.js: login Google (/auth/v1/authorize), sessao em localStorage + refresh, handleAuthRedirect() captura o retorno OAuth no boot tratando o hash-routing. Verificado offline: parse do retorno + decode do JWT + limpeza do hash; smoke do boot OK. - src/core/user-prefs.js: loadProfile/saveProfile (RLS pelo token do user). Falta (proxima fatia, precisa do setup do Google no painel): botao "Entrar com Google" no /perfil + sincronizar tema/universo/favoritos. Passos do Google documentados em docs/SUPABASE.md. Claude-Session: https://claude.ai/code/session_01WVGexdsK5EK86CD3QWkHoQ Co-authored-by: Claude <noreply@anthropic.com>
Seção "Conta" no /perfil: deslogado mostra o botão "Entrar com Google" (cria/conecta a conta Google ao site); logado mostra nome/e-mail/avatar + "Sair". Usa o cliente supabase-auth.js (login via /auth/v1/authorize). Estética por usuário sincroniza na nuvem (user-prefs.js): - trocar tema ou skin de universo logado -> saveProfile. - abrir /perfil logado -> aplica a estetica salva (volta em qualquer dispositivo); inicializa o perfil com a estetica atual se vazio. Verificado no navegador: secao Conta + botao com o "G" colorido do Google renderizam; build limpo. O round-trip real do Google depende do setup do provider no painel do Supabase (passos em docs/SUPABASE.md). Claude-Session: https://claude.ai/code/session_01WVGexdsK5EK86CD3QWkHoQ Co-authored-by: Claude <noreply@anthropic.com>
Nova rota /loja (sidebar > Inicio) que le o catalogo do Shopify pela Storefront API (token publico, sem SDK) e mostra os produtos com capa/preco; "Comprar" leva ao checkout seguro do Shopify. Modelo print-on-demand / dropshipping: vender sem estoque, fornecedor produz e envia sob demanda. - src/core/shopify.js: cliente Storefront (shopifyConfigured/shopifyProducts), GraphQL via fetch, config por env (VITE_SHOPIFY_DOMAIN/STOREFRONT_TOKEN). - src/pages/loja.js + src/styles/loja.css: grade de produtos, estado "Loja em configuracao" quando sem token (zero regressao). chunk ~1.1 kB. - main.js (rota), icons.js (icone de linha 'cart'), sidebar.js (entrada Loja). Verificado no navegador: header/estado/sidebar renderizam; build limpo. Falta conectar a loja Shopify (loja + app POD + token) pros produtos aparecerem. Claude-Session: https://claude.ai/code/session_01WVGexdsK5EK86CD3QWkHoQ Co-authored-by: Claude <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🛒 Loja do Baluarte — página
/lojaInício da loja (você pediu: vender itens/acessórios pro site se pagar, sem estoque). Modelo: print-on-demand / dropshipping — o fornecedor (ex.: Printful/Printify) produz e envia só quando alguém compra; você é o intermediário.
O que entrou
/loja(sidebar → Início): lê o catálogo do Shopify (Storefront API, token público feito pra navegador) e mostra os produtos (capa, título, preço). Comprar → checkout seguro no Shopify.fetch, sem SDK/dependências (chunk 1.1 kB). Cliente emsrc/core/shopify.js.VITE_SHOPIFY_DOMAIN+VITE_SHOPIFY_STOREFRONT_TOKEN.Verificação
Build limpo (chunk
loja1.1 kB / 2.2 kB css). No navegador: header + estado "em configuração" + entrada Loja na sidebar renderizam. ✅⏳ Falta (sua parte, no painel) pra os produtos aparecerem
Criar a loja Shopify + um app de print-on-demand (Printful/Printify) + 1–2 produtos + um Storefront API token. Te passo um roteiro pronto pro "Claude do Chrome" fazer (igual fiz no Google). Depois é só plugar
VITE_SHOPIFY_DOMAIN/VITE_SHOPIFY_STOREFRONT_TOKENna Vercel.🤖 Generated with Claude Code
https://claude.ai/code/session_01WVGexdsK5EK86CD3QWkHoQ
Generated by Claude Code