Refactor: Cleaned up Vercel, Netlify, and other platform traces. Prepared for VPS deploy.

This commit is contained in:
Marcos
2026-03-22 21:55:34 -03:00
parent c9e75fbe2c
commit e198eb3b09
23 changed files with 28 additions and 4277 deletions

View File

@@ -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`

View File

@@ -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<<EOF" >> $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`);
}
}

View File

@@ -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

View File

@@ -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 (
<Router>
<QueryProvider>
<AuthProvider>
<RouteRenderer routes={routes} />
</AuthProvider>
</QueryProvider>
</Router>
);
}
```
### 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

File diff suppressed because it is too large Load Diff

View File

@@ -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 |
| <br /> | <br /> |
| /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');
```

View File

@@ -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.

View File

@@ -1 +0,0 @@
{"projectId":"prj_yIejbjdWxs5ZZ5YWOEHm8UAqDS8k","orgId":"team_KY59uhtbyLyWDtIuz7Ew3uEk","projectName":"trae_42fqthkv","neverMindDeployCard":true}

View File

@@ -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`)

View File

@@ -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á!**

View File

@@ -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!**

View File

@@ -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

View File

@@ -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

View File

@@ -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á!**

View File

@@ -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`

8
TS_RDO.code-workspace Normal file
View File

@@ -0,0 +1,8 @@
{
"folders": [
{
"path": "TS_RDO"
}
],
"settings": {}
}

View File

@@ -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**

View File

@@ -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"

View File

@@ -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",

View File

@@ -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}}"
}
}
}
}

View File

@@ -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

19
scripts/push_gitea.py Normal file
View File

@@ -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"])

View File

@@ -1,8 +0,0 @@
{
"rewrites": [
{
"source": "/(.*)",
"destination": "/index.html"
}
]
}