From e198eb3b0983609781a2fc5534e161a6a89b9ff8 Mon Sep 17 00:00:00 2001 From: Marcos Date: Sun, 22 Mar 2026 21:55:34 -0300 Subject: [PATCH] Refactor: Cleaned up Vercel, Netlify, and other platform traces. Prepared for VPS deploy. --- .github/SECRETS_SETUP.md | 110 -- .github/workflows/auto-sync-deploy.yml | 263 ---- .github/workflows/deploy.yml | 64 - .trae/documents/Analise_Otimizacao_RDO.md | 352 ------ .../documents/Arquitetura_BD_RDO_Completa.md | 1106 ----------------- .trae/documents/Arquitetura_Tecnica_RDO.md | 815 ------------ .trae/documents/PRD_RDO_Mobile_App.md | 129 -- .vercel/project.json | 1 - CHECKLIST_NETLIFY.md | 162 --- CONFIGURACAO_EXATA_RDO.md | 172 --- CONFIGURAR_SUPABASE_VERCEL.md | 119 -- CORRECAO_NETLIFY_AUTH.md | 211 ---- CORRIGIR_VERCEL_AGORA.md | 128 -- DEPLOY_VERCEL.md | 291 ----- TROUBLESHOOT_VERCEL.md | 186 --- TS_RDO.code-workspace | 8 + VERCEL_QUICK_START.md | 65 - netlify.toml | 21 - package.json | 6 +- railway.json | 22 - render.yaml | 47 - scripts/push_gitea.py | 19 + vercel.json | 8 - 23 files changed, 28 insertions(+), 4277 deletions(-) delete mode 100644 .github/SECRETS_SETUP.md delete mode 100644 .github/workflows/auto-sync-deploy.yml delete mode 100644 .github/workflows/deploy.yml delete mode 100644 .trae/documents/Analise_Otimizacao_RDO.md delete mode 100644 .trae/documents/Arquitetura_BD_RDO_Completa.md delete mode 100644 .trae/documents/Arquitetura_Tecnica_RDO.md delete mode 100644 .trae/documents/PRD_RDO_Mobile_App.md delete mode 100644 .vercel/project.json delete mode 100644 CHECKLIST_NETLIFY.md delete mode 100644 CONFIGURACAO_EXATA_RDO.md delete mode 100644 CONFIGURAR_SUPABASE_VERCEL.md delete mode 100644 CORRECAO_NETLIFY_AUTH.md delete mode 100644 CORRIGIR_VERCEL_AGORA.md delete mode 100644 DEPLOY_VERCEL.md delete mode 100644 TROUBLESHOOT_VERCEL.md create mode 100644 TS_RDO.code-workspace delete mode 100644 VERCEL_QUICK_START.md delete mode 100644 netlify.toml delete mode 100644 railway.json delete mode 100644 render.yaml create mode 100644 scripts/push_gitea.py delete mode 100644 vercel.json diff --git a/.github/SECRETS_SETUP.md b/.github/SECRETS_SETUP.md deleted file mode 100644 index 32d4268..0000000 --- a/.github/SECRETS_SETUP.md +++ /dev/null @@ -1,110 +0,0 @@ -# Configuração de Secrets para GitHub Actions - -Para que a automação funcione corretamente, você precisa configurar os seguintes secrets no seu repositório GitHub: - -## Como Configurar Secrets - -1. Vá para o seu repositório no GitHub -2. Clique em **Settings** (Configurações) -3. No menu lateral, clique em **Secrets and variables** > **Actions** -4. Clique em **New repository secret** -5. Adicione cada secret listado abaixo - -## Secrets Necessários - -### 🔑 REMOTE_REPO_TOKEN -**Descrição:** Token de acesso pessoal para o repositório remoto `https://github.com/Reifonas/TS_RDO.git` - -**Como obter:** -1. Vá para GitHub Settings > Developer settings > Personal access tokens > Tokens (classic) -2. Clique em "Generate new token (classic)" -3. Selecione as permissões: - - `repo` (acesso completo a repositórios) - - `workflow` (atualizar workflows) - - `write:packages` (se usar packages) -4. Copie o token gerado -5. Cole no secret `REMOTE_REPO_TOKEN` - -### 🌐 NETLIFY_AUTH_TOKEN (Opcional) -**Descrição:** Token de autenticação do Netlify para deploy automático - -**Como obter:** -1. Faça login no Netlify -2. Vá para User settings > Applications > Personal access tokens -3. Clique em "New access token" -4. Dê um nome e clique em "Generate token" -5. Copie o token e cole no secret `NETLIFY_AUTH_TOKEN` - -### 🆔 NETLIFY_SITE_ID (Opcional) -**Descrição:** ID do site no Netlify - -**Como obter:** -1. No dashboard do Netlify, clique no seu site -2. Vá para Site settings > General > Site details -3. Copie o "Site ID" -4. Cole no secret `NETLIFY_SITE_ID` - -## Verificação da Configuração - -Após configurar os secrets, você pode testar a automação: - -1. **Teste Manual:** - - Vá para Actions no seu repositório - - Clique em "Auto Sync and Deploy" - - Clique em "Run workflow" - - Marque "Force deploy" se quiser forçar - -2. **Teste Automático:** - - Faça qualquer alteração no código - - Commit e push para a branch main - - A action será executada automaticamente - -## Estrutura dos Secrets - -``` -Repository Secrets: -├── REMOTE_REPO_TOKEN # Token para repositório remoto (OBRIGATÓRIO) -├── NETLIFY_AUTH_TOKEN # Token Netlify (opcional) -├── NETLIFY_SITE_ID # ID do site Netlify (opcional) -└── GITHUB_TOKEN # Automático (não precisa configurar) -``` - -## Troubleshooting - -### ❌ Erro: "Authentication failed" -- Verifique se o `REMOTE_REPO_TOKEN` está correto -- Confirme se o token tem as permissões necessárias -- Verifique se o token não expirou - -### ❌ Erro: "Repository not found" -- Confirme se o repositório `Reifonas/TS_RDO` existe -- Verifique se o token tem acesso ao repositório - -### ❌ Erro de Deploy Netlify -- Verifique se `NETLIFY_AUTH_TOKEN` e `NETLIFY_SITE_ID` estão corretos -- Confirme se o site existe no Netlify - -## Logs e Monitoramento - -Para acompanhar a execução: -1. Vá para **Actions** no seu repositório -2. Clique na execução desejada -3. Expanda os jobs para ver os logs detalhados - -## Segurança - -⚠️ **IMPORTANTE:** -- Nunca compartilhe seus tokens -- Use tokens com permissões mínimas necessárias -- Revogue tokens antigos quando não precisar mais -- Monitore o uso dos tokens regularmente - -## Frequência de Execução - -A action executa: -- ✅ A cada push na branch main ou develop -- ✅ A cada pull request para main -- ✅ A cada 30 minutos (agendado) -- ✅ Manualmente quando solicitado - -Para alterar a frequência, edite o arquivo `.github/workflows/auto-sync-deploy.yml` \ No newline at end of file diff --git a/.github/workflows/auto-sync-deploy.yml b/.github/workflows/auto-sync-deploy.yml deleted file mode 100644 index a97f592..0000000 --- a/.github/workflows/auto-sync-deploy.yml +++ /dev/null @@ -1,263 +0,0 @@ -name: Auto Sync and Deploy - -# Triggers para execução da action -on: - push: - branches: [ main, develop ] - pull_request: - branches: [ main ] - schedule: - # Executa a cada 30 minutos - - cron: '*/30 * * * *' - workflow_dispatch: - inputs: - force_deploy: - description: 'Force deploy even without changes' - required: false - default: 'false' - type: boolean - target_branch: - description: 'Target branch for deployment' - required: false - default: 'main' - type: string - -env: - NODE_VERSION: '18' - PNPM_VERSION: '8' - TARGET_REPO: 'Reifonas/TS_RDO' - -jobs: - # Job para verificar mudanças - check-changes: - runs-on: ubuntu-latest - outputs: - has-changes: ${{ steps.changes.outputs.has-changes }} - changed-files: ${{ steps.changes.outputs.changed-files }} - steps: - - name: Checkout código - uses: actions/checkout@v4 - with: - fetch-depth: 2 - - - name: Verificar mudanças - id: changes - run: | - if [ "${{ github.event_name }}" = "schedule" ] || [ "${{ inputs.force_deploy }}" = "true" ]; then - echo "has-changes=true" >> $GITHUB_OUTPUT - echo "changed-files=scheduled-run" >> $GITHUB_OUTPUT - else - CHANGED_FILES=$(git diff --name-only HEAD~1 HEAD || echo "") - if [ -n "$CHANGED_FILES" ]; then - echo "has-changes=true" >> $GITHUB_OUTPUT - echo "changed-files<> $GITHUB_OUTPUT - echo "$CHANGED_FILES" >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - else - echo "has-changes=false" >> $GITHUB_OUTPUT - echo "changed-files=" >> $GITHUB_OUTPUT - fi - fi - - # Job para build e testes - build-and-test: - needs: check-changes - if: needs.check-changes.outputs.has-changes == 'true' - runs-on: ubuntu-latest - steps: - - name: Checkout código - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - cache: 'npm' - - - name: Setup pnpm - uses: pnpm/action-setup@v2 - with: - version: ${{ env.PNPM_VERSION }} - - - name: Instalar dependências - run: pnpm install --frozen-lockfile - - - name: Executar linting - run: pnpm run lint - continue-on-error: true - - - name: Executar testes - run: pnpm run test - continue-on-error: true - - - name: Build do projeto - run: pnpm run build - - - name: Upload build artifacts - uses: actions/upload-artifact@v4 - with: - name: build-files - path: dist/ - retention-days: 1 - - # Job para sincronização com repositório remoto - sync-to-remote: - needs: [check-changes, build-and-test] - if: needs.check-changes.outputs.has-changes == 'true' - runs-on: ubuntu-latest - steps: - - name: Checkout código atual - uses: actions/checkout@v4 - with: - token: ${{ secrets.GITHUB_TOKEN }} - fetch-depth: 0 - - - name: Configurar Git - run: | - git config --global user.name "Auto Sync Bot" - git config --global user.email "auto-sync@rdo-app.com" - - - name: Download build artifacts - uses: actions/download-artifact@v4 - with: - name: build-files - path: dist/ - - - name: Preparar arquivos para sincronização - run: | - # Criar diretório temporário - mkdir -p /tmp/sync-repo - - # Copiar arquivos essenciais (excluir node_modules, logs, etc.) - rsync -av --exclude='node_modules' \ - --exclude='.git' \ - --exclude='logs' \ - - --exclude='.env.local' \ - --exclude='*.log' \ - --exclude='.trae' \ - --exclude='android' \ - --exclude='ios' \ - ./ /tmp/sync-repo/ - - - name: Clonar repositório remoto - env: - REMOTE_TOKEN: ${{ secrets.REMOTE_REPO_TOKEN }} - run: | - cd /tmp - git clone https://${REMOTE_TOKEN}@github.com/${{ env.TARGET_REPO }}.git remote-repo - cd remote-repo - git checkout ${{ inputs.target_branch || 'main' }} || git checkout -b ${{ inputs.target_branch || 'main' }} - - - name: Sincronizar arquivos - run: | - cd /tmp/remote-repo - - # Remover arquivos antigos (exceto .git) - find . -mindepth 1 -maxdepth 1 ! -name '.git' -exec rm -rf {} + - - # Copiar novos arquivos - cp -r /tmp/sync-repo/* . - cp -r /tmp/sync-repo/.* . 2>/dev/null || true - - # Adicionar todos os arquivos - git add . - - - name: Commit e Push para repositório remoto - env: - REMOTE_TOKEN: ${{ secrets.REMOTE_REPO_TOKEN }} - run: | - cd /tmp/remote-repo - - # Verificar se há mudanças - if git diff --staged --quiet; then - echo "Nenhuma mudança para sincronizar" - exit 0 - fi - - # Criar mensagem de commit - COMMIT_MSG="Auto-sync from RDO-C: $(date '+%Y-%m-%d %H:%M:%S')" - if [ "${{ needs.check-changes.outputs.changed-files }}" != "scheduled-run" ]; then - COMMIT_MSG="$COMMIT_MSG\n\nChanged files:\n${{ needs.check-changes.outputs.changed-files }}" - fi - - # Commit e push - git commit -m "$COMMIT_MSG" - git push origin ${{ inputs.target_branch || 'main' }} - - # Job para deploy (se necessário) - deploy: - needs: [check-changes, build-and-test, sync-to-remote] - if: needs.check-changes.outputs.has-changes == 'true' && github.ref == 'refs/heads/main' - runs-on: ubuntu-latest - steps: - - name: Checkout código - uses: actions/checkout@v4 - - - name: Download build artifacts - uses: actions/download-artifact@v4 - with: - name: build-files - path: dist/ - - - name: Deploy para Netlify - uses: nwtgck/actions-netlify@v3.0 - with: - publish-dir: './dist' - production-branch: main - github-token: ${{ secrets.GITHUB_TOKEN }} - deploy-message: "Auto-deploy from commit ${{ github.sha }}" - enable-pull-request-comment: false - enable-commit-comment: true - env: - NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} - NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} - timeout-minutes: 10 - - # Job para notificações - notify: - needs: [check-changes, build-and-test, sync-to-remote, deploy] - if: always() && needs.check-changes.outputs.has-changes == 'true' - runs-on: ubuntu-latest - steps: - - name: Notificar sucesso - if: needs.sync-to-remote.result == 'success' - run: | - echo "✅ Sincronização concluída com sucesso!" - echo "Repositório: ${{ env.TARGET_REPO }}" - echo "Branch: ${{ inputs.target_branch || 'main' }}" - echo "Commit: ${{ github.sha }}" - - - name: Notificar falha - if: needs.sync-to-remote.result == 'failure' || needs.build-and-test.result == 'failure' - run: | - echo "❌ Falha na sincronização!" - echo "Verifique os logs para mais detalhes." - exit 1 - - # Job para limpeza - cleanup: - needs: [check-changes, build-and-test, sync-to-remote, deploy, notify] - if: always() - runs-on: ubuntu-latest - steps: - - name: Limpar artifacts - uses: actions/github-script@v7 - with: - script: | - const artifacts = await github.rest.actions.listWorkflowRunArtifacts({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: context.runId, - }); - - for (const artifact of artifacts.data.artifacts) { - if (artifact.name === 'build-files') { - await github.rest.actions.deleteArtifact({ - owner: context.repo.owner, - repo: context.repo.repo, - artifact_id: artifact.id, - }); - console.log(`Artifact ${artifact.name} removido`); - } - } \ No newline at end of file diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml deleted file mode 100644 index 7562839..0000000 --- a/.github/workflows/deploy.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: Deploy to GitHub Pages - -on: - # Executa no push para a branch main - push: - branches: [ main ] - # Permite execução manual - workflow_dispatch: - -# Define permissões necessárias para o GITHUB_TOKEN -permissions: - contents: read - pages: write - id-token: write - -# Permite apenas um deploy por vez -concurrency: - group: "pages" - cancel-in-progress: false - -jobs: - # Job de build - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '18' - cache: 'npm' - - - name: Setup pnpm - uses: pnpm/action-setup@v2 - with: - version: latest - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Build - run: pnpm run build - - - name: Setup Pages - uses: actions/configure-pages@v4 - - - name: Upload artifact - uses: actions/upload-pages-artifact@v3 - with: - path: './dist' - - # Job de deploy - deploy: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - needs: build - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 \ No newline at end of file diff --git a/.trae/documents/Analise_Otimizacao_RDO.md b/.trae/documents/Analise_Otimizacao_RDO.md deleted file mode 100644 index 245b97f..0000000 --- a/.trae/documents/Analise_Otimizacao_RDO.md +++ /dev/null @@ -1,352 +0,0 @@ -# Análise Completa e Plano de Otimização - Aplicativo RDO - -## 1. Resumo Executivo - -Este documento apresenta uma análise detalhada da estrutura atual do aplicativo RDO (Relatório Diário de Obra) e propõe um plano abrangente de otimização, refatoração e modernização do código. O objetivo é melhorar a performance, legibilidade, manutenibilidade e seguir as melhores práticas atuais de desenvolvimento. - -## 2. Análise da Arquitetura Atual - -### 2.1 Pontos Fortes Identificados -- ✅ Uso de TypeScript para tipagem estática -- ✅ Arquitetura baseada em React 18 com hooks modernos -- ✅ Integração com Supabase para backend-as-a-service -- ✅ Implementação de React Query para gerenciamento de estado servidor -- ✅ Uso de Zustand para estado global -- ✅ Configuração de PWA com Capacitor -- ✅ Implementação de modo offline com Dexie -- ✅ Estrutura de pastas organizada - -### 2.2 Problemas Críticos Identificados - -#### 2.2.1 Duplicação de Lógica de Estado -- ❌ **Problema**: Existem dois sistemas paralelos para gerenciamento de obras: - - `src/hooks/useObras.ts` (useState + useEffect) - - `src/hooks/queries/useObras.ts` (React Query) - - `src/stores/useObraStore.ts` (Zustand) -- ❌ **Impacto**: Inconsistência de dados, complexidade desnecessária, bugs potenciais - -#### 2.2.2 Configuração TypeScript Permissiva -- ❌ **Problema**: `tsconfig.json` com `strict: false` e outras verificações desabilitadas -- ❌ **Impacto**: Perda de benefícios da tipagem estática, bugs em runtime - -#### 2.2.3 Estrutura de Rotas Repetitiva -- ❌ **Problema**: Código repetitivo no `App.tsx` com múltiplas rotas similares -- ❌ **Impacto**: Dificulta manutenção e adiciona verbosidade - -#### 2.2.4 Falta de Padronização de Componentes -- ❌ **Problema**: Componentes sem padrão consistente de props e estrutura -- ❌ **Impacto**: Dificuldade de manutenção e reutilização - -## 3. Plano de Otimização Detalhado - -### 3.1 Fase 1: Consolidação da Arquitetura de Estado (Prioridade Alta) - -#### 3.1.1 Migração para Arquitetura Unificada -**Objetivo**: Eliminar duplicações e criar uma única fonte de verdade - -**Ações**: -1. **Manter apenas React Query + Zustand**: - - Remover hooks baseados em useState (`useObras.ts`, `useRdos.ts`, etc.) - - Usar React Query para estado servidor (dados do Supabase) - - Usar Zustand apenas para estado cliente (UI, configurações) - -2. **Reestruturar hooks de queries**: - ```typescript - // Estrutura otimizada - src/hooks/ - ├── queries/ - │ ├── useObrasQuery.ts // React Query apenas - │ ├── useRdosQuery.ts // React Query apenas - │ └── useUsersQuery.ts // React Query apenas - ├── stores/ - │ ├── useUIStore.ts // Estado da UI - │ ├── useConfigStore.ts // Configurações - │ └── useOfflineStore.ts // Estado offline - └── index.ts - ``` - -3. **Implementar padrão de custom hooks compostos**: - ```typescript - // Exemplo: useObra.ts - export const useObra = (id: string) => { - const query = useObraQuery(id); - const mutation = useUpdateObraMutation(); - const uiState = useUIStore(); - - return { - ...query, - update: mutation.mutate, - isUpdating: mutation.isPending, - // Lógica composta - }; - }; - ``` - -#### 3.1.2 Otimização do React Query -**Configurações aprimoradas**: -```typescript -// queryClient.ts otimizado -export const queryClient = new QueryClient({ - defaultOptions: { - queries: { - staleTime: 5 * 60 * 1000, // 5 minutos - gcTime: 10 * 60 * 1000, // 10 minutos - retry: (failureCount, error) => { - if (error?.status === 401) return false; - return failureCount < 3; - }, - refetchOnWindowFocus: false, // Otimização mobile - }, - }, -}); -``` - -### 3.2 Fase 2: Modernização do TypeScript (Prioridade Alta) - -#### 3.2.1 Configuração Strict -```json -// tsconfig.json otimizado -{ - "compilerOptions": { - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true, - "exactOptionalPropertyTypes": true, - "noUncheckedIndexedAccess": true - } -} -``` - -#### 3.2.2 Melhoria dos Tipos -1. **Criar tipos específicos do domínio**: - ```typescript - // types/domain.ts - export type ObraStatus = 'ativa' | 'pausada' | 'concluida' | 'cancelada'; - export type UserRole = 'admin' | 'engenheiro' | 'mestre_obra' | 'usuario'; - - export interface ObraWithRelations extends Obra { - responsavel?: Usuario; - rdos?: RDO[]; - } - ``` - -2. **Implementar branded types para IDs**: - ```typescript - export type ObraId = string & { readonly brand: unique symbol }; - export type UserId = string & { readonly brand: unique symbol }; - ``` - -### 3.3 Fase 3: Refatoração de Componentes (Prioridade Média) - -#### 3.3.1 Sistema de Design Consistente -1. **Criar componentes base reutilizáveis**: - ```typescript - // components/ui/ - ├── Button/ - │ ├── Button.tsx - │ ├── Button.types.ts - │ └── Button.stories.tsx - ├── Input/ - ├── Modal/ - └── Card/ - ``` - -2. **Implementar compound components**: - ```typescript - // Exemplo: Modal compound component - export const Modal = { - Root: ModalRoot, - Header: ModalHeader, - Body: ModalBody, - Footer: ModalFooter, - }; - ``` - -#### 3.3.2 Otimização de Performance -1. **Implementar React.memo estratégico**: - ```typescript - export const ObraCard = React.memo(({ obra }: { obra: Obra }) => { - // Componente otimizado - }); - ``` - -2. **Usar React.lazy para code splitting**: - ```typescript - const ObraDetails = React.lazy(() => import('./pages/ObraDetails')); - ``` - -3. **Implementar virtualization para listas grandes**: - ```typescript - import { FixedSizeList as List } from 'react-window'; - ``` - -### 3.4 Fase 4: Otimização de Rotas (Prioridade Média) - -#### 3.4.1 Configuração Declarativa de Rotas -```typescript -// routes/config.ts -export const routes = [ - { - path: '/', - element: Dashboard, - protected: true, - layout: MainLayout, - }, - { - path: '/obra/:id', - element: ObraDetails, - protected: true, - layout: null, // Tela cheia - }, -] as const; - -// App.tsx simplificado -export default function App() { - return ( - - - - - - - - ); -} -``` - -### 3.5 Fase 5: Otimizações de Performance (Prioridade Média) - -#### 3.5.1 Bundle Optimization -1. **Configurar Vite para otimização**: - ```typescript - // vite.config.ts - export default defineConfig({ - build: { - rollupOptions: { - output: { - manualChunks: { - vendor: ['react', 'react-dom'], - supabase: ['@supabase/supabase-js'], - ui: ['@radix-ui/react-dialog', '@radix-ui/react-select'], - }, - }, - }, - }, - }); - ``` - -2. **Implementar preloading estratégico**: - ```typescript - // Preload de rotas críticas - const prefetchObraDetails = (obraId: string) => { - queryClient.prefetchQuery({ - queryKey: ['obra', obraId], - queryFn: () => getObra(obraId), - }); - }; - ``` - -#### 3.5.2 Otimização de Imagens e Assets -1. **Implementar lazy loading de imagens** -2. **Usar WebP com fallback** -3. **Configurar service worker para cache de assets** - -### 3.6 Fase 6: Melhorias de DX (Developer Experience) - -#### 3.6.1 Ferramentas de Desenvolvimento -1. **Configurar ESLint mais rigoroso**: - ```javascript - // eslint.config.js - export default [ - ...tseslint.configs.strictTypeChecked, - { - rules: { - '@typescript-eslint/no-unused-vars': 'error', - '@typescript-eslint/prefer-nullish-coalescing': 'error', - 'react-hooks/exhaustive-deps': 'error', - }, - }, - ]; - ``` - -2. **Implementar Prettier com configuração consistente** -3. **Configurar Husky para pre-commit hooks** - -#### 3.6.2 Testing Strategy -1. **Implementar testes unitários com Vitest** -2. **Testes de integração com Testing Library** -3. **E2E tests com Playwright** - -## 4. Cronograma de Implementação - -### Sprint 1 (2 semanas) - Fundação -- [ ] Configurar TypeScript strict mode -- [ ] Consolidar arquitetura de estado (Fase 1) -- [ ] Remover hooks duplicados -- [ ] Configurar ferramentas de desenvolvimento - -### Sprint 2 (2 semanas) - Componentes -- [ ] Criar sistema de design base -- [ ] Refatorar componentes principais -- [ ] Implementar compound components -- [ ] Otimizar performance com React.memo - -### Sprint 3 (1 semana) - Rotas e Performance -- [ ] Refatorar sistema de rotas -- [ ] Implementar code splitting -- [ ] Otimizar bundle com Vite -- [ ] Configurar preloading - -### Sprint 4 (1 semana) - Finalização -- [ ] Testes e validação -- [ ] Documentação -- [ ] Deploy e monitoramento - -## 5. Métricas de Sucesso - -### 5.1 Performance -- **Bundle size**: Redução de 30% -- **First Contentful Paint**: < 1.5s -- **Largest Contentful Paint**: < 2.5s -- **Time to Interactive**: < 3s - -### 5.2 Qualidade de Código -- **TypeScript coverage**: 100% -- **ESLint errors**: 0 -- **Test coverage**: > 80% -- **Duplicação de código**: < 5% - -### 5.3 Developer Experience -- **Build time**: Redução de 40% -- **Hot reload**: < 200ms -- **Type checking**: < 5s - -## 6. Riscos e Mitigações - -### 6.1 Riscos Identificados -1. **Breaking changes durante refatoração** - - *Mitigação*: Implementar testes abrangentes antes das mudanças - -2. **Regressões de funcionalidade** - - *Mitigação*: Refatoração incremental com validação contínua - -3. **Resistência da equipe às mudanças** - - *Mitigação*: Documentação clara e treinamento - -### 6.2 Plano de Rollback -- Manter branches de feature para cada fase -- Implementar feature flags para mudanças críticas -- Monitoramento contínuo em produção - -## 7. Conclusão - -Este plano de otimização transformará o aplicativo RDO em uma aplicação moderna, performática e maintível. A implementação incremental garante baixo risco enquanto maximiza os benefícios de cada melhoria. - -A consolidação da arquitetura de estado e a modernização do TypeScript são as prioridades mais altas, pois impactam diretamente na estabilidade e manutenibilidade do código. - -Com a implementação completa deste plano, esperamos: -- **50% de redução** no tempo de desenvolvimento de novas features -- **30% de melhoria** na performance da aplicação -- **90% de redução** em bugs relacionados a tipos -- **Experiência de desenvolvimento** significativamente melhorada \ No newline at end of file diff --git a/.trae/documents/Arquitetura_BD_RDO_Completa.md b/.trae/documents/Arquitetura_BD_RDO_Completa.md deleted file mode 100644 index 1ef92bc..0000000 --- a/.trae/documents/Arquitetura_BD_RDO_Completa.md +++ /dev/null @@ -1,1106 +0,0 @@ -# Arquitetura Completa de Banco de Dados - RDO Mobile App - -## 1. Visão Geral da Arquitetura de Dados - -### 1.1 Estratégia de Banco de Dados - -O sistema RDO Mobile utiliza **Supabase** como solução Backend-as-a-Service (BaaS), fornecendo: -- **PostgreSQL** como banco de dados principal -- **Autenticação** integrada com Row Level Security (RLS) -- **Storage** para arquivos e imagens -- **Real-time subscriptions** para sincronização em tempo real -- **Edge Functions** para lógica de negócio complexa - -### 1.2 Arquitetura de Conexão - -```mermaid -graph TD - A[React Frontend] --> B[Supabase Client SDK] - B --> C[Supabase API Gateway] - C --> D[PostgreSQL Database] - C --> E[Supabase Auth] - C --> F[Supabase Storage] - C --> G[Real-time Engine] - - subgraph "Frontend Layer" - A - H[Zustand Store] - I[TanStack Query Cache] - J[IndexedDB Offline] - end - - subgraph "Supabase Backend" - C - D - E - F - G - K[Row Level Security] - L[Edge Functions] - end - - A --> H - A --> I - A --> J - D --> K - C --> L -``` - -## 2. Modelo de Dados Completo - -### 2.1 Diagrama Entidade-Relacionamento - -```mermaid -erDiagram - USUARIOS ||--o{ OBRAS : gerencia - USUARIOS ||--o{ RDOS : cria - OBRAS ||--o{ RDOS : possui - OBRAS ||--o{ TAREFAS : contem - RDOS ||--o{ RDO_ATIVIDADES : possui - RDOS ||--o{ RDO_MAO_OBRA : registra - RDOS ||--o{ RDO_EQUIPAMENTOS : utiliza - RDOS ||--o{ RDO_OCORRENCIAS : reporta - RDOS ||--o{ RDO_ANEXOS : contem - RDOS ||--o{ RDO_INSPECOES_SOLDA : possui - RDOS ||--o{ RDO_VERIFICACOES_TORQUE : possui - TAREFAS ||--o{ TASK_LOGS : possui - USUARIOS ||--o{ TASK_LOGS : executa - - USUARIOS { - uuid id PK - string email UK - string nome - string telefone - string cargo - string role - boolean ativo - timestamp created_at - timestamp updated_at - } - - OBRAS { - uuid id PK - string nome - string descricao - string endereco - string cep - string cidade - string estado - uuid responsavel_id FK - date data_inicio - date data_prevista_fim - decimal progresso_geral - string status - jsonb configuracoes - timestamp created_at - timestamp updated_at - } - - RDOS { - uuid id PK - uuid obra_id FK - uuid criado_por FK - date data_relatorio - string condicoes_climaticas - text observacoes_gerais - string status - uuid aprovado_por FK - timestamp aprovado_em - timestamp created_at - timestamp updated_at - } - - RDO_ATIVIDADES { - uuid id PK - uuid rdo_id FK - string tipo_atividade - text descricao - string localizacao - decimal percentual_concluido - integer ordem - timestamp created_at - } - - RDO_MAO_OBRA { - uuid id PK - uuid rdo_id FK - string funcao - integer quantidade - decimal horas_trabalhadas - text observacoes - timestamp created_at - } - - RDO_EQUIPAMENTOS { - uuid id PK - uuid rdo_id FK - string nome_equipamento - string tipo - decimal horas_utilizadas - decimal combustivel_gasto - text observacoes - timestamp created_at - } - - RDO_OCORRENCIAS { - uuid id PK - uuid rdo_id FK - string tipo_ocorrencia - text descricao - string gravidade - text acao_tomada - timestamp created_at - } - - RDO_ANEXOS { - uuid id PK - uuid rdo_id FK - string nome_arquivo - string tipo_arquivo - string url_storage - integer tamanho_bytes - text descricao - timestamp created_at - } - - RDO_INSPECOES_SOLDA { - uuid id PK - uuid rdo_id FK - string identificacao_junta - string status_inspecao - string metodo_inspecao - text observacoes - uuid inspecionado_por FK - timestamp created_at - } - - RDO_VERIFICACOES_TORQUE { - uuid id PK - uuid rdo_id FK - string identificacao_parafuso - decimal torque_especificado - decimal torque_aplicado - string status_verificacao - text observacoes - uuid verificado_por FK - timestamp created_at - } - - TAREFAS { - uuid id PK - uuid obra_id FK - string titulo - text descricao - string status - string prioridade - uuid responsavel_id FK - date data_inicio - date data_fim - decimal progresso - jsonb metadados - timestamp created_at - timestamp updated_at - } - - TASK_LOGS { - uuid id PK - uuid task_id FK - uuid usuario_id FK - string tipo_evento - text descricao - jsonb detalhes - timestamp created_at - } -``` - -## 3. Scripts de Criação do Banco de Dados - -### 3.1 Tabelas Principais - -```sql --- Habilitar extensões necessárias -CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -CREATE EXTENSION IF NOT EXISTS "pg_trgm"; - --- Tabela de Usuários -CREATE TABLE usuarios ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - email VARCHAR(255) UNIQUE NOT NULL, - nome VARCHAR(100) NOT NULL, - telefone VARCHAR(20), - cargo VARCHAR(50), - role VARCHAR(20) DEFAULT 'usuario' CHECK (role IN ('admin', 'engenheiro', 'mestre_obra', 'usuario')), - ativo BOOLEAN DEFAULT true, - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - --- Tabela de Obras -CREATE TABLE obras ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - nome VARCHAR(200) NOT NULL, - descricao TEXT, - endereco TEXT, - cep VARCHAR(10), - cidade VARCHAR(100), - estado VARCHAR(2), - responsavel_id UUID REFERENCES usuarios(id), - data_inicio DATE, - data_prevista_fim DATE, - progresso_geral DECIMAL(5,2) DEFAULT 0.00, - status VARCHAR(20) DEFAULT 'ativa' CHECK (status IN ('ativa', 'pausada', 'concluida', 'cancelada')), - configuracoes JSONB DEFAULT '{}', - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - --- Tabela de RDOs -CREATE TABLE rdos ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - obra_id UUID NOT NULL REFERENCES obras(id) ON DELETE CASCADE, - criado_por UUID NOT NULL REFERENCES usuarios(id), - data_relatorio DATE NOT NULL, - condicoes_climaticas VARCHAR(50) NOT NULL, - observacoes_gerais TEXT, - status VARCHAR(20) DEFAULT 'rascunho' CHECK (status IN ('rascunho', 'enviado', 'aprovado', 'rejeitado')), - aprovado_por UUID REFERENCES usuarios(id), - aprovado_em TIMESTAMP WITH TIME ZONE, - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - UNIQUE(obra_id, data_relatorio) -); - --- Tabela de Atividades do RDO -CREATE TABLE rdo_atividades ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - rdo_id UUID NOT NULL REFERENCES rdos(id) ON DELETE CASCADE, - tipo_atividade VARCHAR(100) NOT NULL, - descricao TEXT NOT NULL, - localizacao VARCHAR(200), - percentual_concluido DECIMAL(5,2) DEFAULT 0.00, - ordem INTEGER DEFAULT 1, - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - --- Tabela de Mão de Obra do RDO -CREATE TABLE rdo_mao_obra ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - rdo_id UUID NOT NULL REFERENCES rdos(id) ON DELETE CASCADE, - funcao VARCHAR(100) NOT NULL, - quantidade INTEGER NOT NULL DEFAULT 1, - horas_trabalhadas DECIMAL(4,2) NOT NULL DEFAULT 8.00, - observacoes TEXT, - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - --- Tabela de Equipamentos do RDO -CREATE TABLE rdo_equipamentos ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - rdo_id UUID NOT NULL REFERENCES rdos(id) ON DELETE CASCADE, - nome_equipamento VARCHAR(100) NOT NULL, - tipo VARCHAR(50), - horas_utilizadas DECIMAL(4,2) DEFAULT 0.00, - combustivel_gasto DECIMAL(6,2) DEFAULT 0.00, - observacoes TEXT, - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - --- Tabela de Ocorrências do RDO -CREATE TABLE rdo_ocorrencias ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - rdo_id UUID NOT NULL REFERENCES rdos(id) ON DELETE CASCADE, - tipo_ocorrencia VARCHAR(100) NOT NULL, - descricao TEXT NOT NULL, - gravidade VARCHAR(20) DEFAULT 'baixa' CHECK (gravidade IN ('baixa', 'media', 'alta', 'critica')), - acao_tomada TEXT, - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - --- Tabela de Anexos do RDO -CREATE TABLE rdo_anexos ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - rdo_id UUID NOT NULL REFERENCES rdos(id) ON DELETE CASCADE, - nome_arquivo VARCHAR(255) NOT NULL, - tipo_arquivo VARCHAR(50), - url_storage TEXT NOT NULL, - tamanho_bytes INTEGER, - descricao TEXT, - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - --- Tabela de Inspeções de Solda -CREATE TABLE rdo_inspecoes_solda ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - rdo_id UUID NOT NULL REFERENCES rdos(id) ON DELETE CASCADE, - identificacao_junta VARCHAR(100) NOT NULL, - status_inspecao VARCHAR(20) DEFAULT 'pendente' CHECK (status_inspecao IN ('aprovado', 'reprovado', 'pendente')), - metodo_inspecao VARCHAR(50), - observacoes TEXT, - inspecionado_por UUID REFERENCES usuarios(id), - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - --- Tabela de Verificações de Torque -CREATE TABLE rdo_verificacoes_torque ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - rdo_id UUID NOT NULL REFERENCES rdos(id) ON DELETE CASCADE, - identificacao_parafuso VARCHAR(100) NOT NULL, - torque_especificado DECIMAL(6,2), - torque_aplicado DECIMAL(6,2) NOT NULL, - status_verificacao VARCHAR(20) DEFAULT 'conforme' CHECK (status_verificacao IN ('conforme', 'nao_conforme')), - observacoes TEXT, - verificado_por UUID REFERENCES usuarios(id), - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - --- Tabela de Tarefas -CREATE TABLE tarefas ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - obra_id UUID NOT NULL REFERENCES obras(id) ON DELETE CASCADE, - titulo VARCHAR(200) NOT NULL, - descricao TEXT, - status VARCHAR(20) DEFAULT 'pendente' CHECK (status IN ('pendente', 'em_andamento', 'concluida', 'cancelada')), - prioridade VARCHAR(20) DEFAULT 'media' CHECK (prioridade IN ('baixa', 'media', 'alta', 'urgente')), - responsavel_id UUID REFERENCES usuarios(id), - data_inicio DATE, - data_fim DATE, - progresso DECIMAL(5,2) DEFAULT 0.00, - metadados JSONB DEFAULT '{}', - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - --- Tabela de Logs de Tarefas -CREATE TABLE task_logs ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - task_id UUID NOT NULL REFERENCES tarefas(id) ON DELETE CASCADE, - usuario_id UUID NOT NULL REFERENCES usuarios(id), - tipo_evento VARCHAR(20) NOT NULL CHECK (tipo_evento IN ('inicio', 'pausa', 'retomada', 'conclusao', 'revisao', 'edicao', 'cancelamento')), - descricao TEXT, - detalhes JSONB DEFAULT '{}', - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); -``` - -### 3.2 Índices para Performance - -```sql --- Índices para otimização de consultas -CREATE INDEX idx_usuarios_email ON usuarios(email); -CREATE INDEX idx_usuarios_role ON usuarios(role); -CREATE INDEX idx_usuarios_ativo ON usuarios(ativo); - -CREATE INDEX idx_obras_responsavel ON obras(responsavel_id); -CREATE INDEX idx_obras_status ON obras(status); -CREATE INDEX idx_obras_data_inicio ON obras(data_inicio); - -CREATE INDEX idx_rdos_obra_data ON rdos(obra_id, data_relatorio); -CREATE INDEX idx_rdos_criado_por ON rdos(criado_por); -CREATE INDEX idx_rdos_status ON rdos(status); -CREATE INDEX idx_rdos_data_relatorio ON rdos(data_relatorio DESC); - -CREATE INDEX idx_rdo_atividades_rdo ON rdo_atividades(rdo_id); -CREATE INDEX idx_rdo_mao_obra_rdo ON rdo_mao_obra(rdo_id); -CREATE INDEX idx_rdo_equipamentos_rdo ON rdo_equipamentos(rdo_id); -CREATE INDEX idx_rdo_ocorrencias_rdo ON rdo_ocorrencias(rdo_id); -CREATE INDEX idx_rdo_anexos_rdo ON rdo_anexos(rdo_id); - -CREATE INDEX idx_tarefas_obra ON tarefas(obra_id); -CREATE INDEX idx_tarefas_responsavel ON tarefas(responsavel_id); -CREATE INDEX idx_tarefas_status ON tarefas(status); -CREATE INDEX idx_tarefas_data_fim ON tarefas(data_fim); - -CREATE INDEX idx_task_logs_task ON task_logs(task_id); -CREATE INDEX idx_task_logs_usuario ON task_logs(usuario_id); -CREATE INDEX idx_task_logs_created_at ON task_logs(created_at DESC); - --- Índices para busca textual -CREATE INDEX idx_obras_nome_trgm ON obras USING gin(nome gin_trgm_ops); -CREATE INDEX idx_rdos_observacoes_trgm ON rdos USING gin(observacoes_gerais gin_trgm_ops); -``` - -### 3.3 Triggers para Auditoria - -```sql --- Função para atualizar timestamp -CREATE OR REPLACE FUNCTION update_updated_at_column() -RETURNS TRIGGER AS $$ -BEGIN - NEW.updated_at = NOW(); - RETURN NEW; -END; -$$ language 'plpgsql'; - --- Triggers para updated_at -CREATE TRIGGER update_usuarios_updated_at BEFORE UPDATE ON usuarios FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); -CREATE TRIGGER update_obras_updated_at BEFORE UPDATE ON obras FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); -CREATE TRIGGER update_rdos_updated_at BEFORE UPDATE ON rdos FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); -CREATE TRIGGER update_tarefas_updated_at BEFORE UPDATE ON tarefas FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); -``` - -## 4. Row Level Security (RLS) - -### 4.1 Políticas de Segurança - -```sql --- Habilitar RLS em todas as tabelas -ALTER TABLE usuarios ENABLE ROW LEVEL SECURITY; -ALTER TABLE obras ENABLE ROW LEVEL SECURITY; -ALTER TABLE rdos ENABLE ROW LEVEL SECURITY; -ALTER TABLE rdo_atividades ENABLE ROW LEVEL SECURITY; -ALTER TABLE rdo_mao_obra ENABLE ROW LEVEL SECURITY; -ALTER TABLE rdo_equipamentos ENABLE ROW LEVEL SECURITY; -ALTER TABLE rdo_ocorrencias ENABLE ROW LEVEL SECURITY; -ALTER TABLE rdo_anexos ENABLE ROW LEVEL SECURITY; -ALTER TABLE rdo_inspecoes_solda ENABLE ROW LEVEL SECURITY; -ALTER TABLE rdo_verificacoes_torque ENABLE ROW LEVEL SECURITY; -ALTER TABLE tarefas ENABLE ROW LEVEL SECURITY; -ALTER TABLE task_logs ENABLE ROW LEVEL SECURITY; - --- Políticas para usuários -CREATE POLICY "Usuários podem ver próprio perfil" ON usuarios FOR SELECT USING (auth.uid() = id); -CREATE POLICY "Usuários podem atualizar próprio perfil" ON usuarios FOR UPDATE USING (auth.uid() = id); -CREATE POLICY "Admins podem gerenciar usuários" ON usuarios FOR ALL USING (auth.jwt() ->> 'role' = 'admin'); - --- Políticas para obras -CREATE POLICY "Usuários podem ver obras onde participam" ON obras FOR SELECT USING ( - auth.uid() = responsavel_id OR - auth.jwt() ->> 'role' IN ('admin', 'engenheiro') -); - -CREATE POLICY "Engenheiros e admins podem criar obras" ON obras FOR INSERT WITH CHECK ( - auth.jwt() ->> 'role' IN ('admin', 'engenheiro') -); - -CREATE POLICY "Responsáveis podem atualizar suas obras" ON obras FOR UPDATE USING ( - auth.uid() = responsavel_id OR - auth.jwt() ->> 'role' IN ('admin', 'engenheiro') -); - --- Políticas para RDOs -CREATE POLICY "Usuários podem ver RDOs de suas obras" ON rdos FOR SELECT USING ( - EXISTS ( - SELECT 1 FROM obras - WHERE obras.id = rdos.obra_id - AND (obras.responsavel_id = auth.uid() OR auth.jwt() ->> 'role' IN ('admin', 'engenheiro')) - ) -); - -CREATE POLICY "Usuários podem criar RDOs" ON rdos FOR INSERT WITH CHECK ( - auth.uid() = criado_por AND - EXISTS ( - SELECT 1 FROM obras - WHERE obras.id = obra_id - AND (obras.responsavel_id = auth.uid() OR auth.jwt() ->> 'role' IN ('admin', 'engenheiro', 'mestre_obra')) - ) -); - -CREATE POLICY "Criadores podem atualizar próprios RDOs" ON rdos FOR UPDATE USING ( - auth.uid() = criado_por AND status = 'rascunho' -); - --- Políticas para tabelas relacionadas ao RDO -CREATE POLICY "Acesso baseado no RDO" ON rdo_atividades FOR ALL USING ( - EXISTS ( - SELECT 1 FROM rdos - WHERE rdos.id = rdo_atividades.rdo_id - AND (rdos.criado_por = auth.uid() OR auth.jwt() ->> 'role' IN ('admin', 'engenheiro')) - ) -); - --- Aplicar política similar para todas as tabelas rdo_* -CREATE POLICY "Acesso baseado no RDO" ON rdo_mao_obra FOR ALL USING ( - EXISTS (SELECT 1 FROM rdos WHERE rdos.id = rdo_mao_obra.rdo_id AND (rdos.criado_por = auth.uid() OR auth.jwt() ->> 'role' IN ('admin', 'engenheiro'))) -); - -CREATE POLICY "Acesso baseado no RDO" ON rdo_equipamentos FOR ALL USING ( - EXISTS (SELECT 1 FROM rdos WHERE rdos.id = rdo_equipamentos.rdo_id AND (rdos.criado_por = auth.uid() OR auth.jwt() ->> 'role' IN ('admin', 'engenheiro'))) -); - -CREATE POLICY "Acesso baseado no RDO" ON rdo_ocorrencias FOR ALL USING ( - EXISTS (SELECT 1 FROM rdos WHERE rdos.id = rdo_ocorrencias.rdo_id AND (rdos.criado_por = auth.uid() OR auth.jwt() ->> 'role' IN ('admin', 'engenheiro'))) -); - -CREATE POLICY "Acesso baseado no RDO" ON rdo_anexos FOR ALL USING ( - EXISTS (SELECT 1 FROM rdos WHERE rdos.id = rdo_anexos.rdo_id AND (rdos.criado_por = auth.uid() OR auth.jwt() ->> 'role' IN ('admin', 'engenheiro'))) -); - -CREATE POLICY "Acesso baseado no RDO" ON rdo_inspecoes_solda FOR ALL USING ( - EXISTS (SELECT 1 FROM rdos WHERE rdos.id = rdo_inspecoes_solda.rdo_id AND (rdos.criado_por = auth.uid() OR auth.jwt() ->> 'role' IN ('admin', 'engenheiro'))) -); - -CREATE POLICY "Acesso baseado no RDO" ON rdo_verificacoes_torque FOR ALL USING ( - EXISTS (SELECT 1 FROM rdos WHERE rdos.id = rdo_verificacoes_torque.rdo_id AND (rdos.criado_por = auth.uid() OR auth.jwt() ->> 'role' IN ('admin', 'engenheiro'))) -); - --- Políticas para tarefas -CREATE POLICY "Usuários podem ver tarefas de suas obras" ON tarefas FOR SELECT USING ( - EXISTS ( - SELECT 1 FROM obras - WHERE obras.id = tarefas.obra_id - AND (obras.responsavel_id = auth.uid() OR auth.jwt() ->> 'role' IN ('admin', 'engenheiro')) - ) OR responsavel_id = auth.uid() -); - -CREATE POLICY "Usuários podem criar tarefas" ON tarefas FOR INSERT WITH CHECK ( - EXISTS ( - SELECT 1 FROM obras - WHERE obras.id = obra_id - AND (obras.responsavel_id = auth.uid() OR auth.jwt() ->> 'role' IN ('admin', 'engenheiro', 'mestre_obra')) - ) -); - --- Políticas para task_logs -CREATE POLICY "Usuários podem ver logs de suas tarefas" ON task_logs FOR SELECT USING ( - EXISTS ( - SELECT 1 FROM tarefas - WHERE tarefas.id = task_logs.task_id - AND (tarefas.responsavel_id = auth.uid() OR auth.jwt() ->> 'role' IN ('admin', 'engenheiro')) - ) -); - -CREATE POLICY "Usuários podem criar logs" ON task_logs FOR INSERT WITH CHECK ( - auth.uid() = usuario_id -); -``` - -## 5. Configuração do Cliente Supabase - -### 5.1 Configuração Básica - -```typescript -// src/lib/supabase.ts -import { createClient } from '@supabase/supabase-js' -import { Database } from './database.types' - -const supabaseUrl = import.meta.env.VITE_SUPABASE_URL -const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY - -export const supabase = createClient(supabaseUrl, supabaseAnonKey, { - auth: { - autoRefreshToken: true, - persistSession: true, - detectSessionInUrl: true - }, - realtime: { - params: { - eventsPerSecond: 10 - } - } -}) - -// Tipos TypeScript gerados automaticamente -export type Tables = Database['public']['Tables'][T]['Row'] -export type Enums = Database['public']['Enums'][T] -``` - -### 5.2 Hooks Customizados para Dados - -```typescript -// src/hooks/useRDOs.ts -import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' -import { supabase } from '../lib/supabase' -import { Tables } from '../lib/supabase' - -type RDO = Tables<'rdos'> -type RDOWithDetails = RDO & { - atividades: Tables<'rdo_atividades'>[] - mao_obra: Tables<'rdo_mao_obra'>[] - equipamentos: Tables<'rdo_equipamentos'>[] - ocorrencias: Tables<'rdo_ocorrencias'>[] - anexos: Tables<'rdo_anexos'>[] -} - -export function useRDOs(obraId: string) { - return useQuery({ - queryKey: ['rdos', obraId], - queryFn: async () => { - const { data, error } = await supabase - .from('rdos') - .select(` - *, - atividades:rdo_atividades(*), - mao_obra:rdo_mao_obra(*), - equipamentos:rdo_equipamentos(*), - ocorrencias:rdo_ocorrencias(*), - anexos:rdo_anexos(*) - `) - .eq('obra_id', obraId) - .order('data_relatorio', { ascending: false }) - - if (error) throw error - return data as RDOWithDetails[] - } - }) -} - -export function useCreateRDO() { - const queryClient = useQueryClient() - - return useMutation({ - mutationFn: async (rdoData: Partial & { - atividades?: Partial>[] - mao_obra?: Partial>[] - equipamentos?: Partial>[] - ocorrencias?: Partial>[] - }) => { - const { atividades, mao_obra, equipamentos, ocorrencias, ...rdo } = rdoData - - // Criar RDO principal - const { data: rdoCreated, error: rdoError } = await supabase - .from('rdos') - .insert(rdo) - .select() - .single() - - if (rdoError) throw rdoError - - // Inserir dados relacionados - if (atividades?.length) { - const { error } = await supabase - .from('rdo_atividades') - .insert(atividades.map(a => ({ ...a, rdo_id: rdoCreated.id }))) - if (error) throw error - } - - if (mao_obra?.length) { - const { error } = await supabase - .from('rdo_mao_obra') - .insert(mao_obra.map(m => ({ ...m, rdo_id: rdoCreated.id }))) - if (error) throw error - } - - if (equipamentos?.length) { - const { error } = await supabase - .from('rdo_equipamentos') - .insert(equipamentos.map(e => ({ ...e, rdo_id: rdoCreated.id }))) - if (error) throw error - } - - if (ocorrencias?.length) { - const { error } = await supabase - .from('rdo_ocorrencias') - .insert(ocorrencias.map(o => ({ ...o, rdo_id: rdoCreated.id }))) - if (error) throw error - } - - return rdoCreated - }, - onSuccess: (data) => { - queryClient.invalidateQueries({ queryKey: ['rdos', data.obra_id] }) - } - }) -} -``` - -### 5.3 Store Zustand Integrado - -```typescript -// src/stores/rdoStore.ts -import { create } from 'zustand' -import { persist } from 'zustand/middleware' -import { supabase } from '../lib/supabase' -import { Tables } from '../lib/supabase' - -type RDO = Tables<'rdos'> -type Obra = Tables<'obras'> - -interface RDOState { - // Estado - currentObra: Obra | null - rdos: RDO[] - loading: boolean - error: string | null - - // Ações - setCurrentObra: (obra: Obra) => void - loadRDOs: (obraId: string) => Promise - createRDO: (rdoData: Partial) => Promise - updateRDO: (id: string, updates: Partial) => Promise - deleteRDO: (id: string) => Promise - - // Real-time - subscribeToRDOs: (obraId: string) => () => void -} - -export const useRDOStore = create()(persist( - (set, get) => ({ - // Estado inicial - currentObra: null, - rdos: [], - loading: false, - error: null, - - // Ações - setCurrentObra: (obra) => set({ currentObra: obra }), - - loadRDOs: async (obraId) => { - set({ loading: true, error: null }) - try { - const { data, error } = await supabase - .from('rdos') - .select('*') - .eq('obra_id', obraId) - .order('data_relatorio', { ascending: false }) - - if (error) throw error - set({ rdos: data, loading: false }) - } catch (error) { - set({ error: (error as Error).message, loading: false }) - } - }, - - createRDO: async (rdoData) => { - set({ loading: true, error: null }) - try { - const { data, error } = await supabase - .from('rdos') - .insert(rdoData) - .select() - .single() - - if (error) throw error - - set(state => ({ - rdos: [data, ...state.rdos], - loading: false - })) - - return data - } catch (error) { - set({ error: (error as Error).message, loading: false }) - throw error - } - }, - - updateRDO: async (id, updates) => { - set({ loading: true, error: null }) - try { - const { error } = await supabase - .from('rdos') - .update(updates) - .eq('id', id) - - if (error) throw error - - set(state => ({ - rdos: state.rdos.map(rdo => - rdo.id === id ? { ...rdo, ...updates } : rdo - ), - loading: false - })) - } catch (error) { - set({ error: (error as Error).message, loading: false }) - } - }, - - deleteRDO: async (id) => { - set({ loading: true, error: null }) - try { - const { error } = await supabase - .from('rdos') - .delete() - .eq('id', id) - - if (error) throw error - - set(state => ({ - rdos: state.rdos.filter(rdo => rdo.id !== id), - loading: false - })) - } catch (error) { - set({ error: (error as Error).message, loading: false }) - } - }, - - subscribeToRDOs: (obraId) => { - const subscription = supabase - .channel(`rdos-${obraId}`) - .on( - 'postgres_changes', - { - event: '*', - schema: 'public', - table: 'rdos', - filter: `obra_id=eq.${obraId}` - }, - (payload) => { - const { eventType, new: newRecord, old: oldRecord } = payload - - set(state => { - switch (eventType) { - case 'INSERT': - return { rdos: [newRecord as RDO, ...state.rdos] } - case 'UPDATE': - return { - rdos: state.rdos.map(rdo => - rdo.id === newRecord.id ? newRecord as RDO : rdo - ) - } - case 'DELETE': - return { - rdos: state.rdos.filter(rdo => rdo.id !== oldRecord.id) - } - default: - return state - } - }) - } - ) - .subscribe() - - return () => subscription.unsubscribe() - } - }), - { - name: 'rdo-store', - partialize: (state) => ({ currentObra: state.currentObra }) - } -)) -``` - -## 6. Estratégias de Cache e Offline - -### 6.1 Configuração do TanStack Query - -```typescript -// src/lib/queryClient.ts -import { QueryClient } from '@tanstack/react-query' -import { persistQueryClient } from '@tanstack/react-query-persist-client-core' -import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister' - -const queryClient = new QueryClient({ - defaultOptions: { - queries: { - staleTime: 5 * 60 * 1000, // 5 minutos - gcTime: 10 * 60 * 1000, // 10 minutos - retry: 3, - refetchOnWindowFocus: false, - refetchOnReconnect: true - }, - mutations: { - retry: 1 - } - } -}) - -// Persistir cache no localStorage -const localStoragePersister = createSyncStoragePersister({ - storage: window.localStorage, - key: 'rdo-cache' -}) - -persistQueryClient({ - queryClient, - persister: localStoragePersister, - maxAge: 24 * 60 * 60 * 1000 // 24 horas -}) - -export { queryClient } -``` - -### 6.2 Service Worker para Offline - -```typescript -// src/sw.ts -import { precacheAndRoute, cleanupOutdatedCaches } from 'workbox-precaching' -import { registerRoute } from 'workbox-routing' -import { StaleWhileRevalidate, CacheFirst } from 'workbox-strategies' - -// Precache de arquivos estáticos -precacheAndRoute(self.__WB_MANIFEST) -cleanupOutdatedCaches() - -// Cache de API calls -registerRoute( - ({ url }) => url.origin === 'https://your-supabase-url.supabase.co', - new StaleWhileRevalidate({ - cacheName: 'supabase-api', - plugins: [ - { - cacheKeyWillBeUsed: async ({ request }) => { - return `${request.url}?${Date.now()}` - } - } - ] - }) -) - -// Cache de imagens -registerRoute( - ({ request }) => request.destination === 'image', - new CacheFirst({ - cacheName: 'images', - plugins: [ - { - cacheExpiration: { - maxEntries: 100, - maxAgeSeconds: 30 * 24 * 60 * 60 // 30 dias - } - } - ] - }) -) -``` - -## 7. Monitoramento e Analytics - -### 7.1 Métricas de Performance - -```sql --- Views para relatórios e analytics -CREATE VIEW vw_obras_dashboard AS -SELECT - o.id, - o.nome, - o.status, - o.progresso_geral, - COUNT(r.id) as total_rdos, - COUNT(CASE WHEN r.status = 'aprovado' THEN 1 END) as rdos_aprovados, - COUNT(t.id) as total_tarefas, - COUNT(CASE WHEN t.status = 'concluida' THEN 1 END) as tarefas_concluidas, - AVG(CASE WHEN t.status = 'concluida' THEN t.progresso END) as progresso_medio_tarefas -FROM obras o -LEFT JOIN rdos r ON o.id = r.obra_id -LEFT JOIN tarefas t ON o.id = t.obra_id -GROUP BY o.id, o.nome, o.status, o.progresso_geral; - -CREATE VIEW vw_produtividade_mensal AS -SELECT - DATE_TRUNC('month', r.data_relatorio) as mes, - o.nome as obra, - COUNT(r.id) as rdos_criados, - COUNT(ra.id) as atividades_executadas, - SUM(rm.quantidade * rm.horas_trabalhadas) as total_horas_trabalhadas -FROM rdos r -JOIN obras o ON r.obra_id = o.id -LEFT JOIN rdo_atividades ra ON r.id = ra.rdo_id -LEFT JOIN rdo_mao_obra rm ON r.id = rm.rdo_id -GROUP BY DATE_TRUNC('month', r.data_relatorio), o.nome -ORDER BY mes DESC; -``` - -### 7.2 Logs de Auditoria - -```sql --- Tabela de auditoria -CREATE TABLE audit_logs ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - table_name VARCHAR(50) NOT NULL, - record_id UUID NOT NULL, - action VARCHAR(10) NOT NULL CHECK (action IN ('INSERT', 'UPDATE', 'DELETE')), - old_values JSONB, - new_values JSONB, - user_id UUID REFERENCES usuarios(id), - timestamp TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - --- Função de auditoria -CREATE OR REPLACE FUNCTION audit_trigger_function() -RETURNS TRIGGER AS $$ -BEGIN - IF TG_OP = 'DELETE' THEN - INSERT INTO audit_logs (table_name, record_id, action, old_values, user_id) - VALUES (TG_TABLE_NAME, OLD.id, TG_OP, row_to_json(OLD), auth.uid()); - RETURN OLD; - ELSIF TG_OP = 'UPDATE' THEN - INSERT INTO audit_logs (table_name, record_id, action, old_values, new_values, user_id) - VALUES (TG_TABLE_NAME, NEW.id, TG_OP, row_to_json(OLD), row_to_json(NEW), auth.uid()); - RETURN NEW; - ELSIF TG_OP = 'INSERT' THEN - INSERT INTO audit_logs (table_name, record_id, action, new_values, user_id) - VALUES (TG_TABLE_NAME, NEW.id, TG_OP, row_to_json(NEW), auth.uid()); - RETURN NEW; - END IF; - RETURN NULL; -END; -$$ LANGUAGE plpgsql; - --- Aplicar triggers de auditoria -CREATE TRIGGER audit_rdos AFTER INSERT OR UPDATE OR DELETE ON rdos FOR EACH ROW EXECUTE FUNCTION audit_trigger_function(); -CREATE TRIGGER audit_obras AFTER INSERT OR UPDATE OR DELETE ON obras FOR EACH ROW EXECUTE FUNCTION audit_trigger_function(); -``` - -## 8. Backup e Recuperação - -### 8.1 Estratégia de Backup - -```sql --- Função para backup incremental -CREATE OR REPLACE FUNCTION create_incremental_backup() -RETURNS TABLE(table_name TEXT, records_count BIGINT) AS $$ -DECLARE - backup_timestamp TIMESTAMP := NOW(); -BEGIN - -- Criar tabela de controle de backup se não existir - CREATE TABLE IF NOT EXISTS backup_control ( - id SERIAL PRIMARY KEY, - table_name VARCHAR(50), - last_backup TIMESTAMP, - created_at TIMESTAMP DEFAULT NOW() - ); - - -- Backup das tabelas principais - RETURN QUERY - SELECT 'rdos'::TEXT, COUNT(*) FROM rdos WHERE updated_at > COALESCE( - (SELECT last_backup FROM backup_control WHERE table_name = 'rdos'), - '1970-01-01'::TIMESTAMP - ); - - -- Atualizar controle de backup - INSERT INTO backup_control (table_name, last_backup) - VALUES ('rdos', backup_timestamp) - ON CONFLICT (table_name) DO UPDATE SET last_backup = backup_timestamp; -END; -$$ LANGUAGE plpgsql; -``` - -## 9. Configurações de Ambiente - -### 9.1 Variáveis de Ambiente - -```bash -# .env.local -VITE_SUPABASE_URL=https://your-project.supabase.co -VITE_SUPABASE_ANON_KEY=your-anon-key -VITE_SUPABASE_SERVICE_ROLE_KEY=your-service-role-key - -# Configurações de cache -VITE_CACHE_TTL=300000 -VITE_OFFLINE_ENABLED=true - -# Configurações de upload -VITE_MAX_FILE_SIZE=10485760 -VITE_ALLOWED_FILE_TYPES=image/*,application/pdf -``` - -### 9.2 Configuração de Produção - -```typescript -// src/config/database.ts -export const databaseConfig = { - development: { - supabaseUrl: import.meta.env.VITE_SUPABASE_URL, - supabaseKey: import.meta.env.VITE_SUPABASE_ANON_KEY, - enableRealtime: true, - enableCache: true, - cacheTimeout: 5 * 60 * 1000 - }, - production: { - supabaseUrl: import.meta.env.VITE_SUPABASE_URL, - supabaseKey: import.meta.env.VITE_SUPABASE_ANON_KEY, - enableRealtime: true, - enableCache: true, - cacheTimeout: 10 * 60 * 1000, - enableCompression: true, - maxRetries: 3 - } -} - -export const getCurrentConfig = () => { - const env = import.meta.env.MODE - return databaseConfig[env as keyof typeof databaseConfig] || databaseConfig.development -} -``` - -Esta documentação fornece uma base sólida para implementar uma conexão completa com banco de dados no projeto RDO Mobile, incluindo esquema de dados, segurança, performance e estratégias offline. \ No newline at end of file diff --git a/.trae/documents/Arquitetura_Tecnica_RDO.md b/.trae/documents/Arquitetura_Tecnica_RDO.md deleted file mode 100644 index e0b6d28..0000000 --- a/.trae/documents/Arquitetura_Tecnica_RDO.md +++ /dev/null @@ -1,815 +0,0 @@ -# Documento de Arquitetura Técnica - RDO Mobile App - -## 1. Design da Arquitetura - -```mermaid -graph TD - A[Usuário Mobile] --> B[React Native/PWA Frontend] - B --> C[Supabase SDK] - C --> D[Supabase Backend] - - subgraph "Frontend Layer" - B - E[Zustand State Management] - F[React Hook Form] - G[Framer Motion] - H[Tailwind CSS] - end - - subgraph "Backend as a Service (Supabase)" - D - I[PostgreSQL Database] - J[Authentication] - K[Storage (Fotos/Docs)] - L[Real-time Subscriptions] - end - - subgraph "Funcionalidades Offline" - M[IndexedDB Cache] - N[Service Worker] - O[Background Sync] - end - - B --> M - N --> B - O --> C -``` - -## 2. Descrição das Tecnologias - -* **Frontend**: React\@18 + TypeScript + Vite + Tailwind CSS - -* **Mobile**: PWA (Progressive Web App) com Capacitor para recursos nativos - -* **Estado**: Zustand para gerenciamento de estado global - -* **Formulários**: React Hook Form + Zod para validação - -* **Animações**: Framer Motion para microinterações - -* **UI Components**: Headless UI + Radix UI primitives - -* **Ícones**: Phosphor Icons - -* **Backend**: Supabase (PostgreSQL + Auth + Storage + Real-time) - -* **Cache**: TanStack Query para cache de dados - -* **Offline**: Workbox para service workers - -## 3. Definições de Rotas - -| Rota | Propósito | -| ----------------------- | --------------------------------------------- | -| / | Dashboard principal com visão geral das obras | -| /obra/:id | Detalhes específicos de uma obra | -| /obra/:id/rdo/novo | Formulário para criar novo RDO | -| /obra/:id/rdo/:rdoId | Visualizar/editar RDO específico | -| /obra/:id/tarefas | Lista de tarefas da obra | -| /cadastros | Menu principal de cadastros | -| /cadastros/obras | Formulário de cadastro de obras | -| /cadastros/usuarios | Gerenciamento de usuários | -| /cadastros/equipamentos | Cadastro de equipamentos | -|
|
| -| /cadastros/atividades | Tipos de atividades padrão | -| /relatorios | Dashboard de relatórios e exportações | -| /perfil | Configurações do usuário | -| /configuracoes | Configurações do aplicativo | - -## 4. Definições de API - -### 4.1 APIs Principais - -**Autenticação de Usuário** - -``` -POST /auth/v1/token -``` - -Request: - -| Nome do Parâmetro | Tipo | Obrigatório | Descrição | -| ----------------- | ------ | ----------- | ---------------- | -| email | string | true | Email do usuário | -| password | string | true | Senha do usuário | - -Response: - -| Nome do Parâmetro | Tipo | Descrição | -| ----------------- | ------ | ---------------------------- | -| access\_token | string | Token JWT para autenticação | -| user | object | Dados do usuário autenticado | - -**Criar RDO** - -``` -POST /rest/v1/rdos -``` - -Request: - -| Nome do Parâmetro | Tipo | Obrigatório | Descrição | -| --------------------- | ------ | ----------- | ------------------------------ | -| obra\_id | uuid | true | ID da obra | -| data\_relatorio | date | true | Data do relatório | -| condicoes\_climaticas | string | true | Condições do tempo | -| atividades | array | true | Lista de atividades executadas | -| mao\_de\_obra | array | false | Funcionários presentes | -| equipamentos | array | false | Equipamentos utilizados | -| ocorrencias | array | false | Ocorrências registradas | - -Response: - -| Nome do Parâmetro | Tipo | Descrição | -| ----------------- | --------- | ------------------- | -| id | uuid | ID do RDO criado | -| status | string | Status do relatório | -| created\_at | timestamp | Data de criação | - -Exemplo: - -```json -{ - "obra_id": "123e4567-e89b-12d3-a456-426614174000", - "data_relatorio": "2024-01-15", - "condicoes_climaticas": "Ensolarado", - "atividades": [ - { - "tipo": "Concretagem", - "descricao": "Concretagem da laje do 2º pavimento", - "percentual_concluido": 75 - } - ] -} -``` - -**Listar Obras** - -``` -GET /rest/v1/obras -``` - -Response: - -| Nome do Parâmetro | Tipo | Descrição | -| ----------------- | ------ | ---------------------------------------- | -| id | uuid | ID da obra | -| nome | string | Nome da obra | -| endereco | string | Endereço da obra | -| status | string | Status atual (ativa, pausada, concluída) | -| progresso | number | Percentual de conclusão | - -## 5. Arquitetura do Servidor - -```mermaid -graph TD - A[Cliente Mobile] --> B[Supabase Edge Functions] - B --> C[Supabase Auth] - B --> D[PostgreSQL Database] - B --> E[Supabase Storage] - - subgraph "Supabase Backend" - C - D - E - F[Real-time Engine] - G[Row Level Security] - end - - subgraph "Edge Functions" - H[Geração de Relatórios PDF] - I[Processamento de Imagens] - J[Notificações Push] - end - - B --> H - B --> I - B --> J -``` - -## 6. Modelo de Dados - -### 6.1 Definição do Modelo de Dados - -```mermaid -erDiagram - USUARIOS ||--o{ OBRAS : gerencia - USUARIOS ||--o{ RDOS : cria - OBRAS ||--o{ RDOS : possui - OBRAS ||--o{ TAREFAS : contem - RDOS ||--o{ RDO_ATIVIDADES : possui - RDOS ||--o{ RDO_MAO_OBRA : registra - RDOS ||--o{ RDO_EQUIPAMENTOS : utiliza - RDOS ||--o{ RDO_OCORRENCIAS : reporta - RDOS ||--o{ RDO_ANEXOS : contem - RDOS ||--o{ RDO_INSPECOES_SOLDA : possui - RDOS ||--o{ RDO_VERIFICACOES_TORQUE : possui - TAREFAS ||--o{ TASK_LOGS : possui - USUARIOS ||--o{ TASK_LOGS : executa - - USUARIOS { - uuid id PK - string email UK - string nome - string telefone - string cargo - string role - boolean ativo - timestamp created_at - timestamp updated_at - } - - OBRAS { - uuid id PK - string nome - string descricao - string endereco - string cep - string cidade - string estado - uuid responsavel_id FK - date data_inicio - date data_prevista_fim - decimal progresso_geral - string status - jsonb configuracoes - timestamp created_at - timestamp updated_at - } - - RDOS { - uuid id PK - uuid obra_id FK - uuid criado_por FK - date data_relatorio - string condicoes_climaticas - text observacoes_gerais - string status - uuid aprovado_por FK - timestamp aprovado_em - timestamp created_at - timestamp updated_at - } - - RDO_ATIVIDADES { - uuid id PK - uuid rdo_id FK - string tipo_atividade - text descricao - string localizacao - decimal percentual_concluido - integer ordem - timestamp created_at - } - - RDO_MAO_OBRA { - uuid id PK - uuid rdo_id FK - string funcao - integer quantidade - decimal horas_trabalhadas - text observacoes - timestamp created_at - } - - RDO_EQUIPAMENTOS { - uuid id PK - uuid rdo_id FK - string nome_equipamento - string tipo - decimal horas_utilizadas - decimal combustivel_gasto - text observacoes - timestamp created_at - } - - RDO_OCORRENCIAS { - uuid id PK - uuid rdo_id FK - string tipo_ocorrencia - text descricao - string gravidade - text acao_tomada - timestamp created_at - } - - RDO_ANEXOS { - uuid id PK - uuid rdo_id FK - string nome_arquivo - string tipo_arquivo - string url_storage - integer tamanho_bytes - text descricao - timestamp created_at - } - - RDO_INSPECOES_SOLDA { - uuid id PK - uuid rdo_id FK - string identificacao_junta - string status_inspecao - string metodo_inspecao - text observacoes - uuid inspecionado_por FK - timestamp created_at - } - - RDO_VERIFICACOES_TORQUE { - uuid id PK - uuid rdo_id FK - string identificacao_parafuso - decimal torque_especificado - decimal torque_aplicado - string status_verificacao - text observacoes - uuid verificado_por FK - timestamp created_at - } - - TAREFAS { - uuid id PK - uuid obra_id FK - string titulo - text descricao - string status - string prioridade - uuid responsavel_id FK - date data_inicio - date data_fim - decimal progresso - jsonb metadados - timestamp created_at - timestamp updated_at - } - - TASK_LOGS { - uuid id PK - uuid task_id FK - uuid usuario_id FK - string tipo_evento - text descricao - jsonb detalhes - timestamp created_at - } - RDOS ||--o{ OCORRENCIAS : possui - RDOS ||--o{ ANEXOS : contem - OBRAS ||--o{ TAREFAS : possui - EQUIPAMENTOS ||--o{ EQUIPAMENTOS_UTILIZADOS : referencia - - USUARIOS { - uuid id PK - string email - string nome - string funcao - string telefone - timestamp created_at - timestamp updated_at - } - - OBRAS { - uuid id PK - string nome - string endereco - string descricao - date data_inicio - date data_prevista_fim - string status - decimal progresso_percentual - uuid responsavel_id FK - timestamp created_at - } - - RDOS { - uuid id PK - uuid obra_id FK - uuid criado_por FK - date data_relatorio - string condicoes_climaticas - text observacoes_gerais - string status - timestamp created_at - } - - ATIVIDADES { - uuid id PK - uuid rdo_id FK - string tipo_atividade - text descricao - string localizacao - decimal percentual_concluido - time hora_inicio - time hora_fim - } - - MAO_DE_OBRA { - uuid id PK - uuid rdo_id FK - string nome_funcionario - string funcao - decimal horas_trabalhadas - boolean presente - } - - EQUIPAMENTOS { - uuid id PK - string nome - string tipo - string modelo - string status - text observacoes - } - - EQUIPAMENTOS_UTILIZADOS { - uuid id PK - uuid rdo_id FK - uuid equipamento_id FK - decimal horas_operacao - decimal combustivel_consumido - text observacoes - } - - OCORRENCIAS { - uuid id PK - uuid rdo_id FK - string tipo - text descricao - string gravidade - boolean resolvida - } - - ANEXOS { - uuid id PK - uuid rdo_id FK - string tipo - string url_arquivo - string nome_arquivo - text descricao - } - - TAREFAS { - uuid id PK - uuid obra_id FK - string titulo - text descricao - date data_prevista - string status - string prioridade - uuid responsavel_id FK - } -``` - -### 6.2 Linguagem de Definição de Dados (DDL) - -**Tabela de Usuários (usuarios)** -```sql --- Criar tabela -CREATE TABLE usuarios ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - email VARCHAR(255) UNIQUE NOT NULL, - nome VARCHAR(100) NOT NULL, - telefone VARCHAR(20), - cargo VARCHAR(100), - role VARCHAR(20) DEFAULT 'user' CHECK (role IN ('admin', 'supervisor', 'user')), - ativo BOOLEAN DEFAULT true, - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - --- Criar índices -CREATE INDEX idx_usuarios_email ON usuarios(email); -CREATE INDEX idx_usuarios_role ON usuarios(role); -CREATE INDEX idx_usuarios_ativo ON usuarios(ativo); - --- Dados iniciais -INSERT INTO usuarios (email, nome, cargo, role) VALUES -('admin@rdo.com', 'Administrador', 'Gerente de Projeto', 'admin'), -('supervisor@rdo.com', 'Supervisor', 'Supervisor de Obra', 'supervisor'), -('user@rdo.com', 'Usuário Padrão', 'Técnico', 'user'); -``` - -**Tabela de Obras (obras)** -```sql -CREATE TABLE obras ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - nome VARCHAR(255) NOT NULL, - descricao TEXT, - endereco TEXT, - cep VARCHAR(10), - cidade VARCHAR(100), - estado VARCHAR(2), - responsavel_id UUID REFERENCES usuarios(id), - data_inicio DATE, - data_prevista_fim DATE, - progresso_geral DECIMAL(5,2) DEFAULT 0.00, - status VARCHAR(20) DEFAULT 'planejamento' CHECK (status IN ('planejamento', 'em_andamento', 'pausada', 'concluida', 'cancelada')), - configuracoes JSONB DEFAULT '{}', - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - -CREATE INDEX idx_obras_responsavel ON obras(responsavel_id); -CREATE INDEX idx_obras_status ON obras(status); -CREATE INDEX idx_obras_data_inicio ON obras(data_inicio); -``` - -**Tabela de RDOs (rdos)** -```sql -CREATE TABLE rdos ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - obra_id UUID NOT NULL REFERENCES obras(id), - criado_por UUID NOT NULL REFERENCES usuarios(id), - data_relatorio DATE NOT NULL, - condicoes_climaticas VARCHAR(100), - observacoes_gerais TEXT, - status VARCHAR(20) DEFAULT 'rascunho' CHECK (status IN ('rascunho', 'enviado', 'aprovado', 'rejeitado')), - aprovado_por UUID REFERENCES usuarios(id), - aprovado_em TIMESTAMP WITH TIME ZONE, - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - -CREATE INDEX idx_rdos_obra ON rdos(obra_id); -CREATE INDEX idx_rdos_criado_por ON rdos(criado_por); -CREATE INDEX idx_rdos_data_relatorio ON rdos(data_relatorio); -CREATE INDEX idx_rdos_status ON rdos(status); -``` - -**Tabela de Atividades do RDO (rdo_atividades)** -```sql -CREATE TABLE rdo_atividades ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - rdo_id UUID NOT NULL REFERENCES rdos(id) ON DELETE CASCADE, - tipo_atividade VARCHAR(100) NOT NULL, - descricao TEXT, - localizacao VARCHAR(255), - percentual_concluido DECIMAL(5,2) DEFAULT 0.00, - ordem INTEGER DEFAULT 0, - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - -CREATE INDEX idx_rdo_atividades_rdo ON rdo_atividades(rdo_id); -CREATE INDEX idx_rdo_atividades_tipo ON rdo_atividades(tipo_atividade); -``` - -**Tabela de Mão de Obra (rdo_mao_obra)** -```sql -CREATE TABLE rdo_mao_obra ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - rdo_id UUID NOT NULL REFERENCES rdos(id) ON DELETE CASCADE, - funcao VARCHAR(100) NOT NULL, - quantidade INTEGER NOT NULL DEFAULT 1, - horas_trabalhadas DECIMAL(5,2) NOT NULL DEFAULT 0.00, - observacoes TEXT, - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - -CREATE INDEX idx_rdo_mao_obra_rdo ON rdo_mao_obra(rdo_id); -CREATE INDEX idx_rdo_mao_obra_funcao ON rdo_mao_obra(funcao); -``` - -**Tabela de Equipamentos (rdo_equipamentos)** -```sql -CREATE TABLE rdo_equipamentos ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - rdo_id UUID NOT NULL REFERENCES rdos(id) ON DELETE CASCADE, - nome_equipamento VARCHAR(255) NOT NULL, - tipo VARCHAR(100), - horas_utilizadas DECIMAL(5,2) DEFAULT 0.00, - combustivel_gasto DECIMAL(8,2) DEFAULT 0.00, - observacoes TEXT, - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - -CREATE INDEX idx_rdo_equipamentos_rdo ON rdo_equipamentos(rdo_id); -CREATE INDEX idx_rdo_equipamentos_tipo ON rdo_equipamentos(tipo); -``` - -**Tabela de Ocorrências (rdo_ocorrencias)** -```sql -CREATE TABLE rdo_ocorrencias ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - rdo_id UUID NOT NULL REFERENCES rdos(id) ON DELETE CASCADE, - tipo_ocorrencia VARCHAR(100) NOT NULL, - descricao TEXT NOT NULL, - gravidade VARCHAR(20) DEFAULT 'baixa' CHECK (gravidade IN ('baixa', 'media', 'alta', 'critica')), - acao_tomada TEXT, - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - -CREATE INDEX idx_rdo_ocorrencias_rdo ON rdo_ocorrencias(rdo_id); -CREATE INDEX idx_rdo_ocorrencias_tipo ON rdo_ocorrencias(tipo_ocorrencia); -CREATE INDEX idx_rdo_ocorrencias_gravidade ON rdo_ocorrencias(gravidade); -``` - -**Tabela de Anexos (rdo_anexos)** -```sql -CREATE TABLE rdo_anexos ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - rdo_id UUID NOT NULL REFERENCES rdos(id) ON DELETE CASCADE, - nome_arquivo VARCHAR(255) NOT NULL, - tipo_arquivo VARCHAR(50), - url_storage TEXT NOT NULL, - tamanho_bytes INTEGER, - descricao TEXT, - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - -CREATE INDEX idx_rdo_anexos_rdo ON rdo_anexos(rdo_id); -CREATE INDEX idx_rdo_anexos_tipo ON rdo_anexos(tipo_arquivo); -``` - -**Tabela de Inspeções de Solda (rdo_inspecoes_solda)** -```sql -CREATE TABLE rdo_inspecoes_solda ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - rdo_id UUID NOT NULL REFERENCES rdos(id) ON DELETE CASCADE, - identificacao_junta VARCHAR(100) NOT NULL, - status_inspecao VARCHAR(20) DEFAULT 'pendente' CHECK (status_inspecao IN ('pendente', 'aprovada', 'rejeitada', 'retrabalho')), - metodo_inspecao VARCHAR(100), - observacoes TEXT, - inspecionado_por UUID REFERENCES usuarios(id), - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - -CREATE INDEX idx_rdo_inspecoes_solda_rdo ON rdo_inspecoes_solda(rdo_id); -CREATE INDEX idx_rdo_inspecoes_solda_status ON rdo_inspecoes_solda(status_inspecao); -``` - -**Tabela de Verificações de Torque (rdo_verificacoes_torque)** -```sql -CREATE TABLE rdo_verificacoes_torque ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - rdo_id UUID NOT NULL REFERENCES rdos(id) ON DELETE CASCADE, - identificacao_parafuso VARCHAR(100) NOT NULL, - torque_especificado DECIMAL(8,2) NOT NULL, - torque_aplicado DECIMAL(8,2) NOT NULL, - status_verificacao VARCHAR(20) DEFAULT 'conforme' CHECK (status_verificacao IN ('conforme', 'nao_conforme', 'retrabalho')), - observacoes TEXT, - verificado_por UUID REFERENCES usuarios(id), - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - -CREATE INDEX idx_rdo_verificacoes_torque_rdo ON rdo_verificacoes_torque(rdo_id); -CREATE INDEX idx_rdo_verificacoes_torque_status ON rdo_verificacoes_torque(status_verificacao); -``` - -**Tabela de Tarefas (tarefas)** -```sql -CREATE TABLE tarefas ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - obra_id UUID NOT NULL REFERENCES obras(id), - titulo VARCHAR(255) NOT NULL, - descricao TEXT, - status VARCHAR(20) DEFAULT 'pendente' CHECK (status IN ('pendente', 'em_andamento', 'concluida', 'cancelada')), - prioridade VARCHAR(20) DEFAULT 'media' CHECK (prioridade IN ('baixa', 'media', 'alta', 'urgente')), - responsavel_id UUID REFERENCES usuarios(id), - data_inicio DATE, - data_fim DATE, - progresso DECIMAL(5,2) DEFAULT 0.00, - metadados JSONB DEFAULT '{}', - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - -CREATE INDEX idx_tarefas_obra ON tarefas(obra_id); -CREATE INDEX idx_tarefas_responsavel ON tarefas(responsavel_id); -CREATE INDEX idx_tarefas_status ON tarefas(status); -CREATE INDEX idx_tarefas_prioridade ON tarefas(prioridade); -``` - -**Tabela de Logs de Tarefas (task_logs)** -```sql -CREATE TABLE task_logs ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - task_id UUID NOT NULL REFERENCES tarefas(id) ON DELETE CASCADE, - usuario_id UUID NOT NULL REFERENCES usuarios(id), - tipo_evento VARCHAR(50) NOT NULL, - descricao TEXT, - detalhes JSONB DEFAULT '{}', - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - -CREATE INDEX idx_task_logs_task ON task_logs(task_id); -CREATE INDEX idx_task_logs_usuario ON task_logs(usuario_id); -CREATE INDEX idx_task_logs_tipo ON task_logs(tipo_evento); -CREATE INDEX idx_task_logs_created_at ON task_logs(created_at DESC); -``` - -**Tabela de Obras** - -```sql --- Criar tabela de obras -CREATE TABLE obras ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - nome VARCHAR(200) NOT NULL, - endereco TEXT NOT NULL, - descricao TEXT, - data_inicio DATE NOT NULL, - data_prevista_fim DATE, - status VARCHAR(20) DEFAULT 'ativa' CHECK (status IN ('ativa', 'pausada', 'concluida')), - progresso_percentual DECIMAL(5,2) DEFAULT 0.00, - responsavel_id UUID REFERENCES usuarios(id), - orcamento_total DECIMAL(15,2), - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - --- Criar índices -CREATE INDEX idx_obras_status ON obras(status); -CREATE INDEX idx_obras_responsavel ON obras(responsavel_id); -CREATE INDEX idx_obras_data_inicio ON obras(data_inicio DESC); - --- Políticas RLS -ALTER TABLE obras ENABLE ROW LEVEL SECURITY; - -CREATE POLICY "Usuários podem ver obras que participam" ON obras - FOR SELECT USING ( - responsavel_id = auth.uid() OR - EXISTS ( - SELECT 1 FROM usuarios - WHERE id = auth.uid() AND funcao IN ('Gestor', 'Engenheiro') - ) - ); - --- Permissões -GRANT SELECT ON obras TO anon; -GRANT ALL PRIVILEGES ON obras TO authenticated; -``` - -**Tabela de RDOs** - -```sql --- Criar tabela de RDOs -CREATE TABLE rdos ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - obra_id UUID NOT NULL REFERENCES obras(id) ON DELETE CASCADE, - criado_por UUID NOT NULL REFERENCES usuarios(id), - data_relatorio DATE NOT NULL, - condicoes_climaticas VARCHAR(50) NOT NULL, - temperatura_min DECIMAL(4,1), - temperatura_max DECIMAL(4,1), - observacoes_gerais TEXT, - status VARCHAR(20) DEFAULT 'rascunho' CHECK (status IN ('rascunho', 'enviado', 'aprovado')), - aprovado_por UUID REFERENCES usuarios(id), - aprovado_em TIMESTAMP WITH TIME ZONE, - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() -); - --- Criar índices -CREATE INDEX idx_rdos_obra_id ON rdos(obra_id); -CREATE INDEX idx_rdos_data_relatorio ON rdos(data_relatorio DESC); -CREATE INDEX idx_rdos_status ON rdos(status); -CREATE INDEX idx_rdos_criado_por ON rdos(criado_por); - --- Constraint única para evitar múltiplos RDOs na mesma data/obra -CREATE UNIQUE INDEX idx_rdos_obra_data_unique ON rdos(obra_id, data_relatorio); - --- Políticas RLS -ALTER TABLE rdos ENABLE ROW LEVEL SECURITY; - -CREATE POLICY "Usuários podem ver RDOs das suas obras" ON rdos - FOR SELECT USING ( - EXISTS ( - SELECT 1 FROM obras - WHERE id = obra_id AND ( - responsavel_id = auth.uid() OR - EXISTS ( - SELECT 1 FROM usuarios - WHERE usuarios.id = auth.uid() AND funcao IN ('Gestor', 'Engenheiro') - ) - ) - ) - ); - --- Permissões -GRANT SELECT ON rdos TO anon; -GRANT ALL PRIVILEGES ON rdos TO authenticated; -``` - -**Dados Iniciais** - -```sql --- Inserir tipos de atividades padrão -INSERT INTO tipos_atividades (nome, categoria) VALUES -('Escavação', 'Terraplanagem'), -('Fundação', 'Estrutura'), -('Concretagem', 'Estrutura'), -('Alvenaria', 'Vedação'), -('Instalação Elétrica', 'Instalações'), -('Instalação Hidráulica', 'Instalações'), -('Revestimento', 'Acabamento'), -('Pintura', 'Acabamento'); - --- Inserir condições climáticas padrão -INSERT INTO condicoes_climaticas (descricao) VALUES -('Ensolarado'), -('Parcialmente Nublado'), -('Nublado'), -('Chuvisco'), -('Chuva Leve'), -('Chuva Forte'), -('Tempestade'); -``` - diff --git a/.trae/documents/PRD_RDO_Mobile_App.md b/.trae/documents/PRD_RDO_Mobile_App.md deleted file mode 100644 index 1db8c46..0000000 --- a/.trae/documents/PRD_RDO_Mobile_App.md +++ /dev/null @@ -1,129 +0,0 @@ -# Documento de Requisitos do Produto - App RDO Mobile - -## 1. Visão Geral do Produto - -O **RDO Mobile** é um aplicativo mobile-first para registro e acompanhamento diário de atividades em obras de construção civil. O app facilita o processo de criação de Relatórios Diários de Obra (RDO), permitindo que engenheiros, mestres de obra e gestores registrem atividades, mão de obra, equipamentos, condições climáticas e ocorrências de forma prática e organizada. - -O produto visa substituir os relatórios em papel ou Excel por uma solução digital moderna, melhorando a comunicação entre canteiro de obra, escritório e clientes, proporcionando acompanhamento em tempo real do progresso das obras. - -## 2. Funcionalidades Principais - -### 2.1 Papéis de Usuário - -| Papel | Método de Registro | Permissões Principais | -|-------|-------------------|----------------------| -| Mestre de Obra | Cadastro por convite | Criar e editar RDOs, registrar atividades, gerenciar mão de obra | -| Engenheiro | Cadastro por convite | Todas as permissões + aprovar RDOs, gerar relatórios | -| Gestor | Cadastro administrativo | Visualizar todas as obras, relatórios consolidados, gerenciar usuários | -| Cliente | Acesso por convite | Visualizar progresso da obra, relatórios aprovados | - -### 2.2 Módulos Funcionais - -Nosso aplicativo RDO Mobile consiste nas seguintes páginas principais: - -1. **Dashboard Principal**: visão geral das obras, indicadores de progresso, últimas atividades -2. **Detalhes da Obra**: informações específicas da obra, histórico de RDOs, galeria de fotos -3. **Criar RDO**: formulário completo para registro diário de atividades -4. **Lista de Tarefas**: gerenciamento de atividades planejadas e executadas -5. **Cadastros**: formulários para obras, usuários, equipamentos e tipos de atividades -6. **Relatórios**: visualização e exportação de relatórios consolidados - -### 2.3 Detalhes das Páginas - -| Nome da Página | Nome do Módulo | Descrição da Funcionalidade | -|----------------|----------------|-----------------------------| -| Dashboard Principal | Visão Geral | Exibir cards das obras ativas, indicadores de progresso, últimos RDOs criados, notificações importantes | -| Dashboard Principal | Navegação Rápida | Acesso rápido para criar novo RDO, visualizar obras, acessar cadastros | -| Detalhes da Obra | Informações da Obra | Mostrar dados da obra, cronograma, responsáveis, localização | -| Detalhes da Obra | Histórico RDO | Listar RDOs anteriores com filtros por data, status, responsável | -| Detalhes da Obra | Galeria de Fotos | Visualizar fotos organizadas por data, com zoom e compartilhamento | -| Criar RDO | Informações Básicas | Campos para data, obra, responsável, condições climáticas | -| Criar RDO | Atividades Executadas | Adicionar atividades com descrição, localização, percentual concluído | -| Criar RDO | Mão de Obra | Registrar funcionários presentes, horas trabalhadas, função | -| Criar RDO | Equipamentos | Listar equipamentos utilizados, horas de operação, combustível | -| Criar RDO | Ocorrências | Registrar problemas, acidentes, atrasos com descrição detalhada | -| Criar RDO | Anexos | Adicionar fotos, documentos, assinaturas digitais | -| Lista de Tarefas | Tarefas Planejadas | Visualizar atividades programadas para o dia/semana | -| Lista de Tarefas | Controle de Execução | Marcar tarefas como iniciadas, em andamento, concluídas | -| Lista de Tarefas | Progresso Visual | Mostrar percentual de conclusão com barras de progresso | -| Cadastros | Cadastro de Obras | Formulário com dados da obra, endereço, responsáveis, cronograma | -| Cadastros | Cadastro de Usuários | Registrar funcionários com foto, função, permissões | -| Cadastros | Cadastro de Equipamentos | Listar equipamentos com especificações, manutenção, disponibilidade | -| Cadastros | Tipos de Atividades | Definir categorias de atividades padrão para seleção rápida | -| Relatórios | Relatórios Consolidados | Gerar relatórios por período, obra, tipo de atividade | -| Relatórios | Exportação | Exportar relatórios em PDF, Excel, compartilhar por email/WhatsApp | - -## 3. Fluxo Principal - -**Fluxo do Mestre de Obra:** -1. Acessa o dashboard e visualiza as obras sob sua responsabilidade -2. Seleciona uma obra específica para trabalhar -3. Cria um novo RDO diário preenchendo todas as seções obrigatórias -4. Adiciona fotos e registra ocorrências se necessário -5. Submete o RDO para aprovação do engenheiro -6. Acompanha o status das tarefas planejadas - -**Fluxo do Engenheiro:** -1. Revisa RDOs pendentes de aprovação -2. Analisa o progresso geral das obras no dashboard -3. Gera relatórios consolidados para apresentação -4. Gerencia cadastros de equipamentos e atividades - -```mermaid -graph TD - A[Dashboard Principal] --> B[Selecionar Obra] - B --> C[Detalhes da Obra] - C --> D[Criar Novo RDO] - C --> E[Lista de Tarefas] - C --> F[Histórico RDOs] - D --> G[Preencher Atividades] - G --> H[Registrar Mão de Obra] - H --> I[Adicionar Equipamentos] - I --> J[Registrar Ocorrências] - J --> K[Anexar Fotos] - K --> L[Submeter RDO] - A --> M[Cadastros] - M --> N[Obras] - M --> O[Usuários] - M --> P[Equipamentos] - A --> Q[Relatórios] -``` - -## 4. Design da Interface do Usuário - -### 4.1 Estilo de Design - -- **Cores Primárias**: Azul #2563EB (confiança, profissionalismo), Laranja #F97316 (energia, ação) -- **Cores Secundárias**: Cinza #64748B (neutro), Verde #10B981 (sucesso), Vermelho #EF4444 (alertas) -- **Estilo dos Botões**: Neumorphism com bordas arredondadas (12px), sombras sutis, efeitos de pressão -- **Tipografia**: Inter (títulos 18-24px), Open Sans (corpo 14-16px), peso regular e semi-bold -- **Layout**: Cards com Glassmorphism, navegação bottom tab, espaçamentos de 16px/24px -- **Ícones**: Phosphor Icons com estilo outline, tamanho 24px para ações principais - -### 4.2 Visão Geral do Design das Páginas - -| Nome da Página | Nome do Módulo | Elementos da UI | -|----------------|----------------|----------------| -| Dashboard Principal | Cards de Obras | Cards com glassmorphism, gradiente sutil azul-roxo, sombra 0 4px 20px rgba(0,0,0,0.1), bordas arredondadas 16px | -| Dashboard Principal | Indicadores | Gráficos circulares com animação, cores verde/amarelo/vermelho para status, fonte Inter 14px | -| Dashboard Principal | Navegação | Bottom navigation com 5 tabs, ícones Phosphor, background blur, altura 80px | -| Criar RDO | Formulário | Floating labels com animação, campos com border-radius 12px, validação em tempo real com cores | -| Criar RDO | Seções Expansíveis | Accordion com ícones de seta, transição suave 300ms, background rgba(255,255,255,0.1) | -| Lista de Tarefas | Cards de Tarefa | Swipe actions (verde para concluir, vermelho para excluir), checkbox animado, progress bar | -| Lista de Tarefas | Filtros | Chips com seleção múltipla, cores Material Design 3, espaçamento 8px | -| Cadastros | Formulários | Stepper horizontal, campos agrupados em cards, botões flutuantes para ações | -| Relatórios | Gráficos | Charts.js com tema dark/light, cores consistentes, animações de entrada | - -### 4.3 Responsividade - -**Mobile-first** com adaptação para tablets. Layouts flexíveis usando CSS Grid e Flexbox, tamanhos em rem (base 16px), espaçamentos escaláveis (16px/24px/32px). Safe areas para dispositivos com notch/dynamic island. Suporte a orientação portrait e landscape para tablets. - -**Gestos de Navegação:** -- Swipe para direita: voltar à tela anterior -- Swipe para baixo: pull-to-refresh nas listas -- Swipe horizontal em cards: ações rápidas (editar/excluir) -- Long press: menu contextual -- Pinch to zoom: galeria de fotos - -**Dark Mode Automático:** -Detecção da preferência do sistema com toggle manual. Paleta adaptada: backgrounds #1F2937, cards #374151, textos #F9FAFB, acentos mantidos com ajuste de saturação. \ No newline at end of file diff --git a/.vercel/project.json b/.vercel/project.json deleted file mode 100644 index 8f04d72..0000000 --- a/.vercel/project.json +++ /dev/null @@ -1 +0,0 @@ -{"projectId":"prj_yIejbjdWxs5ZZ5YWOEHm8UAqDS8k","orgId":"team_KY59uhtbyLyWDtIuz7Ew3uEk","projectName":"trae_42fqthkv","neverMindDeployCard":true} \ No newline at end of file diff --git a/CHECKLIST_NETLIFY.md b/CHECKLIST_NETLIFY.md deleted file mode 100644 index be34168..0000000 --- a/CHECKLIST_NETLIFY.md +++ /dev/null @@ -1,162 +0,0 @@ -# ✅ CHECKLIST NETLIFY - CONFIGURAÇÃO COMPLETA - -## STATUS ATUAL -- ✅ SQL executado com sucesso (2 usuários no banco) -- ✅ Políticas RLS configuradas -- ⚠️ Login ainda não funciona no Netlify - ---- - -## 🔧 CONFIGURAÇÕES NECESSÁRIAS - -### 1️⃣ VARIÁVEIS DE AMBIENTE NO NETLIFY - -**CRÍTICO:** O Netlify NÃO lê o arquivo `.env` local! - -#### Como configurar: - -1. Acesse: https://app.netlify.com -2. Clique no seu site -3. Vá em: **Site settings** → **Environment variables** -4. Clique em **Add a variable** -5. Adicione estas 2 variáveis: - -``` -Key: VITE_SUPABASE_URL -Value: https://xzudfhifaancyxxfdejx.supabase.co - -Key: VITE_SUPABASE_ANON_KEY -Value: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inh6dWRmaGlmYWFuY3l4eGZkZWp4Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzEzNjE0MTAsImV4cCI6MjA4NjkzNzQxMH0.c5CHWhfXcMrm27LfxEt6OZtttXXvVJOeWu-IbnNLfWY -``` - -6. **IMPORTANTE:** Após adicionar, clique em **Trigger deploy** para fazer um novo deploy - ---- - -### 2️⃣ REDIRECT URLs NO SUPABASE - -1. Acesse: https://supabase.com/dashboard/project/xzudfhifaancyxxfdejx/auth/url-configuration - -2. Na seção **Redirect URLs**, adicione (substitua `SEU-SITE` pelo domínio real): - -``` -https://SEU-SITE.netlify.app/auth/callback -https://SEU-SITE.netlify.app/* -``` - -**Exemplo:** -``` -https://rdo-tracksteel.netlify.app/auth/callback -https://rdo-tracksteel.netlify.app/* -``` - -3. Na seção **Site URL**, configure: -``` -https://SEU-SITE.netlify.app -``` - -4. Clique em **Save** - ---- - -### 3️⃣ GOOGLE CLOUD CONSOLE (OAuth) - -1. Acesse: https://console.cloud.google.com/apis/credentials - -2. Clique no seu **OAuth 2.0 Client ID** - -3. Em **Authorized redirect URIs**, adicione: - -``` -https://xzudfhifaancyxxfdejx.supabase.co/auth/v1/callback -https://SEU-SITE.netlify.app/auth/callback -``` - -4. Clique em **Save** - ---- - -## 🧪 COMO TESTAR - -### Teste 1: Verificar Variáveis de Ambiente - -Após fazer o deploy no Netlify: - -1. Abra o site no Netlify -2. Pressione **F12** (Console do navegador) -3. Digite: - -```javascript -console.log('URL:', import.meta.env.VITE_SUPABASE_URL) -console.log('Key:', import.meta.env.VITE_SUPABASE_ANON_KEY?.substring(0, 20) + '...') -``` - -**Resultado esperado:** -``` -URL: https://xzudfhifaancyxxfdejx.supabase.co -Key: eyJhbGciOiJIUzI1NiIs... -``` - -**Se retornar `undefined`** = Variáveis não configuradas no Netlify! - ---- - -### Teste 2: Verificar Login - -1. Clique em "Login com Google" -2. Autorize o app -3. Deve redirecionar para `/auth/callback` -4. Deve fazer login com sucesso - ---- - -## 🔍 DIAGNÓSTICO DE ERROS - -### Erro: "Invalid redirect URL" -- ❌ Faltou adicionar URL no Supabase (passo 2) -- ❌ Faltou adicionar URI no Google Cloud (passo 3) - -### Erro: "Environment variables not defined" -- ❌ Faltou configurar variáveis no Netlify (passo 1) -- ❌ Faltou fazer novo deploy após configurar - -### Erro: 401 Unauthorized -- ✅ Já resolvido com o SQL que você executou! - -### Login funciona mas volta para tela de login -- ❌ Variáveis de ambiente não configuradas -- ❌ Redirect URLs não configuradas - ---- - -## 📋 ORDEM DE EXECUÇÃO - -1. ✅ **SQL executado** (você já fez!) -2. ⬜ **Configurar variáveis no Netlify** (passo 1) -3. ⬜ **Fazer novo deploy no Netlify** -4. ⬜ **Configurar Redirect URLs no Supabase** (passo 2) -5. ⬜ **Configurar OAuth no Google Cloud** (passo 3) -6. ⬜ **Testar login** - ---- - -## 🎯 QUAL É O SEU DOMÍNIO NETLIFY? - -Para eu te dar os comandos exatos, me informe: - -**Qual é a URL do seu site no Netlify?** - -Exemplo: `https://rdo-tracksteel.netlify.app` - -Com essa informação, posso te dar os valores exatos para copiar e colar! - ---- - -## 💡 DICA RÁPIDA - -Se você ainda não sabe a URL do Netlify: - -1. Acesse: https://app.netlify.com -2. Clique no seu site -3. A URL está no topo da página (ex: `https://nome-do-site.netlify.app`) - diff --git a/CONFIGURACAO_EXATA_RDO.md b/CONFIGURACAO_EXATA_RDO.md deleted file mode 100644 index 04ebbdd..0000000 --- a/CONFIGURACAO_EXATA_RDO.md +++ /dev/null @@ -1,172 +0,0 @@ -# 🎯 CONFIGURAÇÃO EXATA - rdo.tracksteel.com.br - -## ✅ VALORES PRONTOS PARA COPIAR E COLAR - ---- - -## 1️⃣ NETLIFY - VARIÁVEIS DE AMBIENTE - -### Acesse: -https://app.netlify.com → Seu Site → Site settings → Environment variables - -### Adicione estas 2 variáveis: - -**Variável 1:** -``` -Key: VITE_SUPABASE_URL -Value: https://xzudfhifaancyxxfdejx.supabase.co -``` - -**Variável 2:** -``` -Key: VITE_SUPABASE_ANON_KEY -Value: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inh6dWRmaGlmYWFuY3l4eGZkZWp4Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzEzNjE0MTAsImV4cCI6MjA4NjkzNzQxMH0.c5CHWhfXcMrm27LfxEt6OZtttXXvVJOeWu-IbnNLfWY -``` - -### ⚠️ IMPORTANTE: -Após adicionar as variáveis, clique em **"Trigger deploy"** para fazer um novo deploy! - ---- - -## 2️⃣ SUPABASE - REDIRECT URLs - -### Acesse: -https://supabase.com/dashboard/project/xzudfhifaancyxxfdejx/auth/url-configuration - -### Na seção "Redirect URLs", adicione estas URLs (uma por linha): - -``` -https://rdo.tracksteel.com.br/auth/callback -https://rdo.tracksteel.com.br/* -http://localhost:5173/auth/callback -http://localhost:3000/auth/callback -``` - -### Na seção "Site URL", configure: -``` -https://rdo.tracksteel.com.br -``` - -### Clique em **Save** - ---- - -## 3️⃣ GOOGLE CLOUD CONSOLE - OAUTH - -### Acesse: -https://console.cloud.google.com/apis/credentials - -### Clique no seu OAuth 2.0 Client ID - -### Na seção "Authorized redirect URIs", adicione estas URIs: - -``` -https://xzudfhifaancyxxfdejx.supabase.co/auth/v1/callback -https://rdo.tracksteel.com.br/auth/callback -http://localhost:5173/auth/callback -http://localhost:3000/auth/callback -``` - -### Clique em **Save** - ---- - -## 4️⃣ TESTE APÓS CONFIGURAR - -### Teste 1: Verificar Variáveis de Ambiente - -1. Abra: https://rdo.tracksteel.com.br -2. Pressione **F12** (Console do navegador) -3. Cole este código: - -```javascript -console.log('URL:', import.meta.env.VITE_SUPABASE_URL) -console.log('Key:', import.meta.env.VITE_SUPABASE_ANON_KEY?.substring(0, 30) + '...') -``` - -**Resultado esperado:** -``` -URL: https://xzudfhifaancyxxfdejx.supabase.co -Key: eyJhbGciOiJIUzI1NiIsInR5cCI6Ik... -``` - -**Se retornar `undefined`:** -- ❌ Variáveis não foram configuradas no Netlify -- ❌ Ou você não fez o novo deploy após configurar - ---- - -### Teste 2: Login com Google - -1. Acesse: https://rdo.tracksteel.com.br -2. Clique em **"Login com Google"** -3. Autorize o app -4. Deve redirecionar para: `https://rdo.tracksteel.com.br/auth/callback` -5. Deve fazer login com sucesso e ir para a página inicial - ---- - -## 📋 CHECKLIST DE EXECUÇÃO - -- [ ] 1. Configurar variáveis no Netlify -- [ ] 2. Fazer novo deploy no Netlify (Trigger deploy) -- [ ] 3. Aguardar deploy finalizar (2-3 minutos) -- [ ] 4. Configurar Redirect URLs no Supabase -- [ ] 5. Configurar OAuth no Google Cloud -- [ ] 6. Testar variáveis de ambiente (Teste 1) -- [ ] 7. Testar login com Google (Teste 2) - ---- - -## 🔍 DIAGNÓSTICO DE PROBLEMAS - -### Problema: Variáveis retornam `undefined` -**Solução:** -1. Verifique se adicionou as variáveis no Netlify -2. Verifique se fez o novo deploy -3. Aguarde o deploy finalizar completamente -4. Limpe o cache do navegador (Ctrl+Shift+Delete) - -### Problema: "Invalid redirect URL" -**Solução:** -1. Verifique se adicionou as URLs no Supabase (passo 2) -2. Verifique se adicionou as URIs no Google Cloud (passo 3) -3. Aguarde 1-2 minutos para as configurações propagarem - -### Problema: Erro 401 após login -**Solução:** -- ✅ Já resolvido! Você executou o SQL corretamente - -### Problema: Login funciona mas volta para tela de login -**Solução:** -1. Verifique se as variáveis de ambiente estão configuradas -2. Verifique se o novo deploy foi feito -3. Limpe o cache do navegador - ---- - -## 🎯 RESUMO RÁPIDO - -**3 lugares para configurar:** - -1. **Netlify** → Variáveis de ambiente + Novo deploy -2. **Supabase** → Redirect URLs -3. **Google Cloud** → Redirect URIs - -**Tempo estimado:** 10-15 minutos - ---- - -## 💡 DICA IMPORTANTE - -Após configurar tudo, aguarde 2-3 minutos para: -- Deploy do Netlify finalizar -- Configurações do Supabase propagarem -- Configurações do Google Cloud propagarem - -Depois teste o login! - ---- - -**Qualquer dúvida, me avise em qual passo você está!** - diff --git a/CONFIGURAR_SUPABASE_VERCEL.md b/CONFIGURAR_SUPABASE_VERCEL.md deleted file mode 100644 index ef9c29f..0000000 --- a/CONFIGURAR_SUPABASE_VERCEL.md +++ /dev/null @@ -1,119 +0,0 @@ -# 🔧 CONFIGURAR SUPABASE PARA VERCEL - -## 🎯 PROBLEMA - -Erro 404 em `/auth/callback` após login com Google. - -**Causa:** A URL da Vercel não está autorizada no Supabase. - ---- - -## ✅ SOLUÇÃO - -### 1. Adicionar Redirect URLs no Supabase - -1. Acesse: https://supabase.com/dashboard/project/xzudfhifaancyxxfdejx/auth/url-configuration - -2. Na seção **"Redirect URLs"**, adicione estas URLs (uma por linha): - -``` -https://rdots.vercel.app/auth/callback -https://rdots.vercel.app/* -https://rdo.tracksteel.com.br/auth/callback -https://rdo.tracksteel.com.br/* -http://localhost:5173/auth/callback -http://localhost:3000/auth/callback -``` - -3. Na seção **"Site URL"**, configure: -``` -https://rdots.vercel.app -``` - -4. Clique em **"Save"** - ---- - -### 2. Configurar Google Cloud Console - -1. Acesse: https://console.cloud.google.com/apis/credentials - -2. Clique no seu **OAuth 2.0 Client ID** - -3. Na seção **"Authorized redirect URIs"**, adicione: - -``` -https://xzudfhifaancyxxfdejx.supabase.co/auth/v1/callback -https://rdots.vercel.app/auth/callback -https://rdo.tracksteel.com.br/auth/callback -http://localhost:5173/auth/callback -http://localhost:3000/auth/callback -``` - -4. Clique em **"Save"** - ---- - -### 3. Aguardar Deploy da Vercel - -O push que acabei de fazer vai disparar um novo deploy na Vercel. - -1. Acesse: https://vercel.com/dashboard -2. Clique no projeto -3. Vá em **"Deployments"** -4. Aguarde o deploy ficar **"Ready"** (verde) - 2-3 minutos - ---- - -### 4. Testar Login - -Após o deploy finalizar: - -1. Abra: https://rdots.vercel.app -2. Pressione **Ctrl+Shift+R** (hard refresh) -3. Clique em **"Login com Google"** -4. Autorize o app -5. Deve redirecionar para `/auth/callback` ✅ -6. Deve fazer login com sucesso ✅ - ---- - -## 📋 CHECKLIST - -- [ ] Redirect URLs adicionadas no Supabase -- [ ] Site URL configurada no Supabase -- [ ] Redirect URIs adicionadas no Google Cloud -- [ ] Deploy da Vercel finalizado (aguardar 2-3 min) -- [ ] Hard refresh no navegador (Ctrl+Shift+R) -- [ ] Teste de login realizado - ---- - -## 🔍 SE AINDA DER ERRO - -### Erro: "Invalid redirect URL" -- Verifique se adicionou as URLs no Supabase -- Aguarde 1-2 minutos para propagação - -### Erro: 404 em /auth/callback -- Aguarde o deploy da Vercel finalizar -- Verifique se o vercel.json foi aplicado -- Faça hard refresh (Ctrl+Shift+R) - -### Erro: "Missing Publishable Key" -- Configure as variáveis de ambiente na Vercel -- Faça um redeploy sem cache - ---- - -## 🎯 ORDEM DE EXECUÇÃO - -1. ✅ **Configurar Supabase** (passo 1) - FAÇA AGORA -2. ✅ **Configurar Google Cloud** (passo 2) - FAÇA AGORA -3. ⏳ **Aguardar deploy** (passo 3) - 2-3 minutos -4. 🧪 **Testar login** (passo 4) - ---- - -**Comece pelo passo 1 e 2 AGORA enquanto o deploy está rodando!** - diff --git a/CORRECAO_NETLIFY_AUTH.md b/CORRECAO_NETLIFY_AUTH.md deleted file mode 100644 index ffe16f1..0000000 --- a/CORRECAO_NETLIFY_AUTH.md +++ /dev/null @@ -1,211 +0,0 @@ -# 🔧 CORREÇÃO: Autenticação no Netlify - -## 🎯 PROBLEMA IDENTIFICADO - -O app funciona localmente (localhost:5173 e :3000) mas falha ao autenticar no Netlify devido a: - -1. ❌ Variáveis de ambiente não configuradas no Netlify -2. ❌ URLs de callback OAuth não configuradas no Supabase -3. ❌ Políticas RLS bloqueando acesso após OAuth - ---- - -## ✅ SOLUÇÃO COMPLETA - -### 1️⃣ CONFIGURAR VARIÁVEIS DE AMBIENTE NO NETLIFY - -Acesse: https://app.netlify.com → Seu Site → Site settings → Environment variables - -Adicione estas variáveis: - -``` -VITE_SUPABASE_URL=https://xzudfhifaancyxxfdejx.supabase.co -VITE_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inh6dWRmaGlmYWFuY3l4eGZkZWp4Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzEzNjE0MTAsImV4cCI6MjA4NjkzNzQxMH0.c5CHWhfXcMrm27LfxEt6OZtttXXvVJOeWu-IbnNLfWY -``` - -**IMPORTANTE:** Após adicionar, faça um novo deploy! - ---- - -### 2️⃣ CONFIGURAR REDIRECT URLs NO SUPABASE - -Acesse: https://supabase.com/dashboard/project/xzudfhifaancyxxfdejx/auth/url-configuration - -Na seção **Redirect URLs**, adicione: - -``` -https://SEU-SITE.netlify.app/auth/callback -https://SEU-SITE.netlify.app/* -``` - -**Exemplo:** -``` -https://rdo-tracksteel.netlify.app/auth/callback -https://rdo-tracksteel.netlify.app/* -``` - -Na seção **Site URL**, configure: -``` -https://SEU-SITE.netlify.app -``` - ---- - -### 3️⃣ CORRIGIR POLÍTICAS RLS PARA OAUTH - -O problema principal: quando um usuário faz login via Google OAuth, o Supabase cria o registro em `auth.users`, mas a política RLS impede a criação automática do perfil em `public.usuarios`. - -Execute este SQL no Supabase (SQL Editor): - -```sql --- ============================================================================ --- CORREÇÃO RLS PARA OAUTH - PERMITIR CRIAÇÃO AUTOMÁTICA DE PERFIL --- ============================================================================ - --- 1. Permitir INSERT na tabela usuarios para usuários autenticados -DROP POLICY IF EXISTS "Users can create own profile" ON public.usuarios; - -CREATE POLICY "Users can create own profile" ON public.usuarios - FOR INSERT - WITH CHECK (auth.uid() = id); - --- 2. Garantir que o trigger handle_new_user funciona --- Verificar se a função existe -CREATE OR REPLACE FUNCTION public.handle_new_user() -RETURNS TRIGGER AS $$ -BEGIN - -- Inserir novo usuário na tabela public.usuarios - INSERT INTO public.usuarios ( - id, - email, - nome, - role, - ativo - ) VALUES ( - NEW.id, - NEW.email, - COALESCE(NEW.raw_user_meta_data->>'nome', NEW.raw_user_meta_data->>'name', split_part(NEW.email, '@', 1)), - 'usuario', - true - ) - ON CONFLICT (id) DO UPDATE SET - email = EXCLUDED.email, - nome = COALESCE(EXCLUDED.nome, public.usuarios.nome), - updated_at = NOW(); - - RETURN NEW; -END; -$$ LANGUAGE plpgsql SECURITY DEFINER; - --- 3. Garantir que o trigger está ativo -DROP TRIGGER IF EXISTS on_auth_user_created ON auth.users; - -CREATE TRIGGER on_auth_user_created - AFTER INSERT ON auth.users - FOR EACH ROW - EXECUTE FUNCTION public.handle_new_user(); - --- 4. Permitir leitura de organizações para usuários sem organização (signup) -DROP POLICY IF EXISTS "Users can view orgs during signup" ON public.organizacoes; - -CREATE POLICY "Users can view orgs during signup" ON public.organizacoes - FOR SELECT - USING (auth.uid() IS NOT NULL); - --- 5. Permitir criação de organização para novos usuários -DROP POLICY IF EXISTS "Users can create org" ON public.organizacoes; - -CREATE POLICY "Users can create org" ON public.organizacoes - FOR INSERT - WITH CHECK (auth.uid() IS NOT NULL); - --- ============================================================================ --- FIM DA CORREÇÃO --- ============================================================================ -``` - ---- - -### 4️⃣ VERIFICAR CONFIGURAÇÃO DO GOOGLE OAUTH - -No Google Cloud Console (https://console.cloud.google.com): - -1. Acesse: APIs & Services → Credentials -2. Clique no seu OAuth 2.0 Client ID -3. Em **Authorized redirect URIs**, adicione: - -``` -https://xzudfhifaancyxxfdejx.supabase.co/auth/v1/callback -https://SEU-SITE.netlify.app/auth/callback -``` - ---- - -## 🧪 TESTAR A CORREÇÃO - -### Teste 1: Variáveis de Ambiente -```bash -# No console do navegador (F12) no site Netlify: -console.log(import.meta.env.VITE_SUPABASE_URL) -``` -Deve retornar: `https://xzudfhifaancyxxfdejx.supabase.co` - -### Teste 2: Login OAuth -1. Acesse seu site no Netlify -2. Clique em "Login com Google" -3. Autorize o app -4. Deve redirecionar e autenticar com sucesso - -### Teste 3: Verificar Perfil Criado -No Supabase SQL Editor: -```sql -SELECT * FROM public.usuarios WHERE email = 'seu-email@gmail.com'; -``` - ---- - -## 🔍 DIAGNÓSTICO DE PROBLEMAS - -### Erro: "Invalid redirect URL" -- ✅ Verifique se adicionou a URL no Supabase (passo 2) -- ✅ Verifique se adicionou no Google Cloud (passo 4) - -### Erro: "User not found" ou "Permission denied" -- ✅ Execute o SQL de correção RLS (passo 3) -- ✅ Verifique se o trigger `handle_new_user` está ativo - -### Erro: "Environment variables not defined" -- ✅ Configure variáveis no Netlify (passo 1) -- ✅ Faça um novo deploy após adicionar - -### Login funciona mas não carrega dados -- ✅ Problema de RLS - execute o SQL do passo 3 -- ✅ Verifique se o usuário foi criado em `public.usuarios` - ---- - -## 📋 CHECKLIST FINAL - -- [ ] Variáveis de ambiente configuradas no Netlify -- [ ] Novo deploy realizado após configurar variáveis -- [ ] Redirect URLs adicionadas no Supabase -- [ ] Redirect URIs adicionadas no Google Cloud -- [ ] SQL de correção RLS executado no Supabase -- [ ] Teste de login OAuth realizado com sucesso -- [ ] Perfil do usuário criado em `public.usuarios` - ---- - -## 🎯 RESULTADO ESPERADO - -Após seguir todos os passos: - -✅ Login via Google funciona no Netlify -✅ Perfil do usuário é criado automaticamente -✅ Usuário consegue acessar o app normalmente -✅ RLS permite acesso aos dados da organização - ---- - -**Data:** 24/02/2026 -**Status:** Aguardando aplicação das correções diff --git a/CORRIGIR_VERCEL_AGORA.md b/CORRIGIR_VERCEL_AGORA.md deleted file mode 100644 index f7a8ae1..0000000 --- a/CORRIGIR_VERCEL_AGORA.md +++ /dev/null @@ -1,128 +0,0 @@ -# 🚨 CORRIGIR VERCEL - VARIÁVEIS DE AMBIENTE - -## ❌ PROBLEMA ATUAL - -Erro: **"Missing Publishable Key"** - -Isso significa que as variáveis de ambiente NÃO foram configuradas ou NÃO foram aplicadas no build. - ---- - -## ✅ SOLUÇÃO PASSO A PASSO - -### 1. Verificar se as variáveis existem - -1. Acesse: https://vercel.com/dashboard -2. Clique no projeto **rdots** (ou o nome do seu projeto) -3. Vá em **Settings** → **Environment Variables** -4. Verifique se existem estas 2 variáveis: - - `VITE_SUPABASE_URL` - - `VITE_SUPABASE_ANON_KEY` - ---- - -### 2. Se as variáveis NÃO existem: - -Adicione-as agora: - -**Variável 1:** -``` -Key: VITE_SUPABASE_URL -Value: https://xzudfhifaancyxxfdejx.supabase.co -Environments: Production ✅ Preview ✅ Development ✅ -``` - -**Variável 2:** -``` -Key: VITE_SUPABASE_ANON_KEY -Value: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inh6dWRmaGlmYWFuY3l4eGZkZWp4Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzEzNjE0MTAsImV4cCI6MjA4NjkzNzQxMH0.c5CHWhfXcMrm27LfxEt6OZtttXXvVJOeWu-IbnNLfWY -Environments: Production ✅ Preview ✅ Development ✅ -``` - -**IMPORTANTE:** Marque as 3 checkboxes (Production, Preview, Development)! - ---- - -### 3. Se as variáveis JÁ existem: - -Verifique se estão marcadas para **Production**: - -1. Clique no ícone de lápis (editar) ao lado de cada variável -2. Certifique-se que **Production** está marcado ✅ -3. Clique em **Save** - ---- - -### 4. Fazer um novo deploy (OBRIGATÓRIO!) - -Após adicionar/editar as variáveis, você DEVE fazer um novo deploy: - -**Opção A - Redeploy:** -1. Vá em **Deployments** -2. Clique nos 3 pontos do último deploy -3. Clique em **"Redeploy"** -4. Marque **"Use existing Build Cache"** = ❌ (desmarque!) -5. Clique em **"Redeploy"** - -**Opção B - Trigger via Git:** -```bash -# No terminal local -git commit --allow-empty -m "trigger: Forçar rebuild na Vercel" -git push origin main -``` - ---- - -### 5. Aguardar o build finalizar - -1. Vá em **Deployments** -2. Aguarde o novo deploy ficar **"Ready"** (verde) -3. Clique no deploy -4. Clique em **"Visit"** para abrir o site - ---- - -## 🧪 TESTAR SE FUNCIONOU - -Após o novo deploy: - -1. Abra: https://rdots.vercel.app (ou sua URL) -2. Pressione **Ctrl+Shift+R** (hard refresh) -3. Abra o DevTools (F12) -4. Vá na aba **Console** -5. Veja se o erro "Missing Publishable Key" sumiu - ---- - -## 🔍 VERIFICAR SE AS VARIÁVEIS ESTÃO CARREGANDO - -No console do navegador (F12), digite: - -```javascript -// Isso NÃO vai funcionar no console, mas você pode ver no código fonte -// Vá em Sources → Procure por arquivos .js → Procure por "xzudfhifaancyxxfdejx" -``` - -Se encontrar "xzudfhifaancyxxfdejx" no código = ✅ Variáveis carregadas! -Se NÃO encontrar = ❌ Variáveis não foram injetadas no build - ---- - -## 📋 CHECKLIST - -- [ ] Variáveis existem em Settings → Environment Variables -- [ ] Variáveis estão marcadas para Production -- [ ] Fiz um novo deploy (Redeploy) -- [ ] Aguardei o build finalizar -- [ ] Fiz hard refresh no navegador (Ctrl+Shift+R) -- [ ] Erro "Missing Publishable Key" sumiu - ---- - -## 🆘 SE AINDA NÃO FUNCIONAR - -Me envie: -1. Print da tela de Environment Variables da Vercel -2. Print do console (F12) mostrando os erros -3. URL do seu projeto na Vercel - diff --git a/DEPLOY_VERCEL.md b/DEPLOY_VERCEL.md deleted file mode 100644 index 40b0d92..0000000 --- a/DEPLOY_VERCEL.md +++ /dev/null @@ -1,291 +0,0 @@ -# 🚀 DEPLOY NA VERCEL - rdo.tracksteel.com.br - -## ✅ VANTAGENS DA VERCEL - -- ✅ Melhor suporte para Vite/React -- ✅ Deploy automático via GitHub -- ✅ Configuração de variáveis mais simples -- ✅ Edge Functions nativas -- ✅ Melhor performance global - ---- - -## 📋 PASSO A PASSO COMPLETO - -### 1️⃣ CRIAR PROJETO NA VERCEL (5 minutos) - -1. Acesse: https://vercel.com/login -2. Faça login com GitHub -3. Clique em **"Add New..."** → **"Project"** -4. Selecione o repositório: **Reifonas/RDOC** -5. Clique em **"Import"** - ---- - -### 2️⃣ CONFIGURAR O PROJETO - -Na tela de configuração: - -#### Framework Preset: -``` -Vite -``` - -#### Build Command: -``` -npm run build -``` - -#### Output Directory: -``` -dist -``` - -#### Install Command: -``` -npm ci -``` - ---- - -### 3️⃣ ADICIONAR VARIÁVEIS DE AMBIENTE - -Na seção **"Environment Variables"**, adicione: - -**Variável 1:** -``` -Name: VITE_SUPABASE_URL -Value: https://xzudfhifaancyxxfdejx.supabase.co -``` - -**Variável 2:** -``` -Name: VITE_SUPABASE_ANON_KEY -Value: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inh6dWRmaGlmYWFuY3l4eGZkZWp4Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzEzNjE0MTAsImV4cCI6MjA4NjkzNzQxMH0.c5CHWhfXcMrm27LfxEt6OZtttXXvVJOeWu-IbnNLfWY -``` - -**IMPORTANTE:** Marque para aplicar em **Production**, **Preview** e **Development** - ---- - -### 4️⃣ FAZER O DEPLOY - -1. Clique em **"Deploy"** -2. Aguarde o build finalizar (2-3 minutos) -3. Anote a URL gerada (ex: `https://rdoc-xxx.vercel.app`) - ---- - -### 5️⃣ CONFIGURAR DOMÍNIO CUSTOMIZADO - -1. No dashboard do projeto, vá em **"Settings"** → **"Domains"** -2. Clique em **"Add"** -3. Digite: `rdo.tracksteel.com.br` -4. Clique em **"Add"** - -#### Configurar DNS: - -A Vercel vai mostrar os registros DNS necessários. Configure no seu provedor de DNS: - -**Opção A - CNAME (Recomendado):** -``` -Type: CNAME -Name: rdo -Value: cname.vercel-dns.com -``` - -**Opção B - A Record:** -``` -Type: A -Name: rdo -Value: 76.76.21.21 -``` - ---- - -### 6️⃣ CONFIGURAR SUPABASE - -Acesse: https://supabase.com/dashboard/project/xzudfhifaancyxxfdejx/auth/url-configuration - -#### Redirect URLs (adicione estas): - -``` -https://rdo.tracksteel.com.br/auth/callback -https://rdo.tracksteel.com.br/* -https://rdoc-xxx.vercel.app/auth/callback -https://rdoc-xxx.vercel.app/* -http://localhost:5173/auth/callback -http://localhost:3000/auth/callback -``` - -**Substitua `rdoc-xxx` pela URL real que a Vercel gerou!** - -#### Site URL: -``` -https://rdo.tracksteel.com.br -``` - -Clique em **Save** - ---- - -### 7️⃣ CONFIGURAR GOOGLE CLOUD - -Acesse: https://console.cloud.google.com/apis/credentials - -Clique no seu **OAuth 2.0 Client ID** - -#### Authorized redirect URIs (adicione estas): - -``` -https://xzudfhifaancyxxfdejx.supabase.co/auth/v1/callback -https://rdo.tracksteel.com.br/auth/callback -https://rdoc-xxx.vercel.app/auth/callback -http://localhost:5173/auth/callback -http://localhost:3000/auth/callback -``` - -**Substitua `rdoc-xxx` pela URL real que a Vercel gerou!** - -Clique em **Save** - ---- - -## 🧪 TESTAR O DEPLOY - -### Teste 1: Acessar o site - -1. Abra: `https://rdoc-xxx.vercel.app` (URL da Vercel) -2. Ou: `https://rdo.tracksteel.com.br` (após configurar DNS) -3. O site deve carregar normalmente - ---- - -### Teste 2: Verificar variáveis - -1. Abra o DevTools (F12) -2. Vá na aba **Network** -3. Recarregue a página -4. Procure por requisições para `xzudfhifaancyxxfdejx.supabase.co` -5. Se aparecer = ✅ Variáveis configuradas! - ---- - -### Teste 3: Login com Google - -1. Clique em **"Login com Google"** -2. Autorize o app -3. Deve redirecionar para `/auth/callback` -4. Deve fazer login com sucesso ✅ - ---- - -## 🔄 DEPLOY AUTOMÁTICO - -A Vercel faz deploy automático quando você faz push para o GitHub: - -- **Branch `main`** → Deploy em produção -- **Outras branches** → Deploy de preview - ---- - -## 📊 MONITORAMENTO - -### Ver logs de build: -1. Acesse: https://vercel.com/dashboard -2. Clique no projeto -3. Vá em **"Deployments"** -4. Clique em um deploy para ver os logs - -### Ver logs de runtime: -1. No dashboard do projeto -2. Vá em **"Logs"** -3. Veja erros em tempo real - ---- - -## 🔧 CONFIGURAÇÕES AVANÇADAS - -### Variáveis de ambiente por ambiente: - -- **Production**: Usado no domínio principal -- **Preview**: Usado em branches de teste -- **Development**: Usado localmente com `vercel dev` - -### Revalidar cache: - -Se fizer mudanças e não aparecerem: -1. Vá em **"Deployments"** -2. Clique nos 3 pontos do deploy -3. Clique em **"Redeploy"** - ---- - -## 🆚 COMPARAÇÃO: VERCEL vs NETLIFY - -| Recurso | Vercel | Netlify | -|---------|--------|---------| -| Build Vite | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | -| Deploy automático | ✅ | ✅ | -| Edge Functions | ✅ Nativo | ✅ Limitado | -| Performance | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | -| Configuração | Mais simples | Mais complexa | -| Logs | Excelente | Bom | - ---- - -## 📋 CHECKLIST FINAL - -- [ ] Projeto criado na Vercel -- [ ] Variáveis de ambiente configuradas -- [ ] Deploy realizado com sucesso -- [ ] Domínio customizado configurado -- [ ] DNS configurado (aguardar propagação) -- [ ] Redirect URLs adicionadas no Supabase -- [ ] Redirect URIs adicionadas no Google Cloud -- [ ] Teste de login realizado com sucesso - ---- - -## 🎯 RESULTADO ESPERADO - -Após seguir todos os passos: - -✅ Site acessível em `https://rdo.tracksteel.com.br` -✅ Login com Google funcionando -✅ Deploy automático via GitHub -✅ Variáveis de ambiente configuradas -✅ Performance otimizada - ---- - -## 💡 DICAS - -1. **Aguarde a propagação DNS** (pode levar até 24h, mas geralmente 5-10 minutos) -2. **Use a URL da Vercel** (`rdoc-xxx.vercel.app`) para testar antes do DNS propagar -3. **Limpe o cache** do navegador após cada deploy -4. **Monitore os logs** para identificar problemas rapidamente - ---- - -## 🆘 PROBLEMAS COMUNS - -### Build falha: -- Verifique os logs de build -- Verifique se as dependências estão corretas -- Tente fazer build local: `npm run build` - -### Variáveis não carregam: -- Verifique se adicionou as variáveis -- Verifique se marcou para Production -- Faça um novo deploy - -### Login não funciona: -- Verifique se adicionou as redirect URLs no Supabase -- Verifique se adicionou as redirect URIs no Google Cloud -- Aguarde 1-2 minutos para propagação - ---- - -**Qualquer dúvida, me avise em qual passo você está!** - diff --git a/TROUBLESHOOT_VERCEL.md b/TROUBLESHOOT_VERCEL.md deleted file mode 100644 index edb7d1d..0000000 --- a/TROUBLESHOOT_VERCEL.md +++ /dev/null @@ -1,186 +0,0 @@ -# 🔧 TROUBLESHOOTING - VERCEL BUILD - -## 🚨 ERROS COMUNS E SOLUÇÕES - -### 1. Erro: "Module not found" ou "Cannot find module" - -**Solução:** -```bash -# No terminal local, teste o build: -npm run build - -# Se funcionar local mas falhar na Vercel: -# Verifique se todas as dependências estão no package.json -``` - ---- - -### 2. Erro: "TypeScript errors" - -**Solução A - Desabilitar verificação de tipos no build:** - -Adicione no `vite.config.ts`: -```typescript -export default defineConfig({ - build: { - // ... outras configs - }, - esbuild: { - logOverride: { 'this-is-undefined-in-esm': 'silent' } - } -}) -``` - -**Solução B - Ignorar erros de TypeScript:** - -No `package.json`, mude o build command: -```json -"build": "vite build --mode production" -``` - ---- - -### 3. Erro: "Out of memory" ou "JavaScript heap out of memory" - -**Solução:** - -Adicione no `package.json`: -```json -"scripts": { - "build": "NODE_OPTIONS='--max-old-space-size=4096' vite build" -} -``` - -Ou configure na Vercel: -- Settings → General → Build & Development Settings -- Build Command: `NODE_OPTIONS='--max-old-space-size=4096' npm run build` - ---- - -### 4. Erro: "Failed to resolve import" - -**Solução:** - -Verifique se todos os imports estão corretos: -```typescript -// ❌ Errado -import { Component } from './Component' - -// ✅ Correto -import { Component } from './Component.tsx' -``` - -Ou adicione no `vite.config.ts`: -```typescript -export default defineConfig({ - resolve: { - extensions: ['.tsx', '.ts', '.jsx', '.js'] - } -}) -``` - ---- - -### 5. Erro: "Environment variables not defined" - -**Solução:** - -Verifique se as variáveis estão configuradas na Vercel: -- Settings → Environment Variables -- Certifique-se que estão marcadas para Production - ---- - -### 6. Erro: "Build exceeded maximum duration" - -**Solução:** - -Otimize o build no `vite.config.ts`: -```typescript -export default defineConfig({ - build: { - reportCompressedSize: false, - chunkSizeWarningLimit: 1000, - rollupOptions: { - output: { - manualChunks: undefined // Desabilita chunk splitting - } - } - } -}) -``` - ---- - -## 🧪 TESTE LOCAL ANTES DE FAZER DEPLOY - -```bash -# 1. Limpar cache -npm run clean -rm -rf node_modules -rm package-lock.json - -# 2. Reinstalar dependências -npm install - -# 3. Testar build -npm run build - -# 4. Testar preview -npm run preview -``` - -Se funcionar local, deve funcionar na Vercel! - ---- - -## 📋 CHECKLIST DE VERIFICAÇÃO - -- [ ] Build funciona localmente (`npm run build`) -- [ ] Todas as dependências estão no `package.json` -- [ ] Variáveis de ambiente configuradas na Vercel -- [ ] Node version compatível (v18 ou v20) -- [ ] Sem imports de arquivos que não existem -- [ ] Sem erros de TypeScript críticos - ---- - -## 🔍 COMO VER O LOG DE ERRO NA VERCEL - -1. Acesse: https://vercel.com/dashboard -2. Clique no projeto -3. Vá em **"Deployments"** -4. Clique no deploy que falhou -5. Role até a seção **"Build Logs"** -6. Copie a mensagem de erro completa - ---- - -## 💡 SOLUÇÃO RÁPIDA - BUILD SIMPLIFICADO - -Se nada funcionar, crie um `vercel.json` simplificado: - -```json -{ - "buildCommand": "npm install && npm run build", - "outputDirectory": "dist", - "framework": "vite", - "installCommand": "npm install", - "rewrites": [ - { - "source": "/(.*)", - "destination": "/index.html" - } - ] -} -``` - ---- - -## 🆘 AINDA NÃO FUNCIONA? - -Me envie: -1. Print do log de erro completo da Vercel -2. Resultado de `npm run build` no seu terminal local -3. Versão do Node que você está usando: `node -v` - diff --git a/TS_RDO.code-workspace b/TS_RDO.code-workspace new file mode 100644 index 0000000..49d715d --- /dev/null +++ b/TS_RDO.code-workspace @@ -0,0 +1,8 @@ +{ + "folders": [ + { + "path": "TS_RDO" + } + ], + "settings": {} +} \ No newline at end of file diff --git a/VERCEL_QUICK_START.md b/VERCEL_QUICK_START.md deleted file mode 100644 index a06c5a3..0000000 --- a/VERCEL_QUICK_START.md +++ /dev/null @@ -1,65 +0,0 @@ -# ⚡ VERCEL - INÍCIO RÁPIDO - -## 🎯 DEPLOY EM 10 MINUTOS - -### 1. Criar projeto na Vercel -- Acesse: https://vercel.com/new -- Importe: `Reifonas/RDOC` -- Framework: **Vite** - -### 2. Adicionar variáveis de ambiente - -```bash -VITE_SUPABASE_URL=https://xzudfhifaancyxxfdejx.supabase.co -VITE_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inh6dWRmaGlmYWFuY3l4eGZkZWp4Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzEzNjE0MTAsImV4cCI6MjA4NjkzNzQxMH0.c5CHWhfXcMrm27LfxEt6OZtttXXvVJOeWu-IbnNLfWY -``` - -### 3. Deploy -- Clique em **"Deploy"** -- Aguarde 2-3 minutos -- Anote a URL gerada - -### 4. Configurar Supabase - -Adicione no Supabase (Auth → URL Configuration): - -``` -https://SUA-URL.vercel.app/auth/callback -https://rdo.tracksteel.com.br/auth/callback -``` - -### 5. Configurar Google Cloud - -Adicione no Google Cloud Console: - -``` -https://xzudfhifaancyxxfdejx.supabase.co/auth/v1/callback -https://SUA-URL.vercel.app/auth/callback -https://rdo.tracksteel.com.br/auth/callback -``` - -### 6. Testar -- Abra a URL da Vercel -- Faça login com Google -- Deve funcionar! ✅ - ---- - -## 🔗 LINKS ÚTEIS - -- **Dashboard Vercel**: https://vercel.com/dashboard -- **Supabase Auth Config**: https://supabase.com/dashboard/project/xzudfhifaancyxxfdejx/auth/url-configuration -- **Google Cloud Console**: https://console.cloud.google.com/apis/credentials - ---- - -## 📝 NOTAS - -- A Vercel tem melhor suporte para Vite que o Netlify -- Deploy automático via GitHub está configurado -- Domínio customizado pode ser configurado depois - ---- - -**Guia completo em: DEPLOY_VERCEL.md** - diff --git a/netlify.toml b/netlify.toml deleted file mode 100644 index f9d68b9..0000000 --- a/netlify.toml +++ /dev/null @@ -1,21 +0,0 @@ -[build] - command = "npm ci && npm run build" - publish = "dist" - -[build.environment] - NODE_VERSION = "22" - NODE_ENV = "production" - GENERATE_SOURCEMAP = "false" - -# Redirect para SPA -[[redirects]] - from = "/*" - to = "/index.html" - status = 200 - -# Headers básicos de segurança -[[headers]] - for = "/*" - [headers.values] - X-Frame-Options = "DENY" - X-Content-Type-Options = "nosniff" \ No newline at end of file diff --git a/package.json b/package.json index 5608aa7..341b0dd 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,14 @@ { - "name": "trae-project", + "name": "ts-rdo", "private": true, "version": "0.0.0", "type": "module", "scripts": { "dev": "vite", "build": "vite build", - "build:netlify": "vite build --mode production", - "build:vercel": "vite build --mode production", "lint": "eslint .", "lint:fix": "eslint . --fix", "preview": "vite preview", - "preview:netlify": "vite preview --port 4173 --host", - "preview:vercel": "vite preview --port 3000", "start": "node scripts/start.js", "check": "tsc -b --noEmit", "analyze": "vite build --mode analyze", diff --git a/railway.json b/railway.json deleted file mode 100644 index 72f4c0e..0000000 --- a/railway.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "$schema": "https://railway.app/railway.schema.json", - "build": { - "builder": "NIXPACKS", - "buildCommand": "pnpm install && pnpm run build" - }, - "deploy": { - "startCommand": "pnpm preview --host 0.0.0.0 --port $PORT", - "healthcheckPath": "/", - "healthcheckTimeout": 100, - "restartPolicyType": "ON_FAILURE", - "restartPolicyMaxRetries": 10 - }, - "environments": { - "production": { - "variables": { - "NODE_ENV": "production", - "PORT": "${{RAILWAY_PUBLIC_PORT}}" - } - } - } -} \ No newline at end of file diff --git a/render.yaml b/render.yaml deleted file mode 100644 index a5af7c4..0000000 --- a/render.yaml +++ /dev/null @@ -1,47 +0,0 @@ -services: - - type: web - name: rdo-app - env: node - region: oregon # ou frankfurt para Europa - plan: free # plano gratuito - buildCommand: pnpm install && pnpm run build - startCommand: pnpm preview --host 0.0.0.0 --port $PORT - - # Configurações do ambiente - envVars: - - key: NODE_ENV - value: production - - key: PORT - fromService: - type: web - name: rdo-app - property: port - - # Configurações de build - buildFilter: - paths: - - src/** - - public/** - - index.html - - package.json - - pnpm-lock.yaml - - vite.config.ts - - tsconfig.json - - # Headers personalizados - headers: - - path: /* - name: X-Frame-Options - value: DENY - - path: /* - name: X-Content-Type-Options - value: nosniff - - path: /assets/* - name: Cache-Control - value: public, max-age=31536000, immutable - - # Redirects para SPA - routes: - - type: redirect - source: /* - destination: /index.html \ No newline at end of file diff --git a/scripts/push_gitea.py b/scripts/push_gitea.py new file mode 100644 index 0000000..37ec8c1 --- /dev/null +++ b/scripts/push_gitea.py @@ -0,0 +1,19 @@ +import subprocess +import os + +repo_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +# @@ -> %40%40 (Codificação URL padrão para caracteres especiais) +remote_url = "https://admtracksteel:%40%40Gi05Br;;@git.reifonas.cloud/admtracksteel/RDO.git" + +def run_git(args): + result = subprocess.run(["git"] + args, cwd=repo_dir, capture_output=True, text=True) + if result.returncode != 0: + print(f"Erro em git {' '.join(args)}: {result.stderr}") + else: + print(f"Sucesso em git {' '.join(args)}") + return result.returncode + +run_git(["remote", "set-url", "origin", remote_url]) +run_git(["branch", "-M", "main"]) +print("Iniciando Push de RDO para Gitea...") +run_git(["push", "-u", "origin", "main", "--force"]) diff --git a/vercel.json b/vercel.json deleted file mode 100644 index 1323cda..0000000 --- a/vercel.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "rewrites": [ - { - "source": "/(.*)", - "destination": "/index.html" - } - ] -}