Leitura Pública de Documentos

Como exibir documentos em outros sites para leitura sem aceite formal

2024-01-15
documentos leitura api iframe integração

Guia: Leitura Pública de Documentos (Sem Aceite)

📖 Visão Geral

Este guia explica como exibir documentos (termos de uso, políticas, etc.) em outros sites para leitura, sem a necessidade de aceite formal.

Diferença importante: - Leitura: Apenas visualizar o conteúdo (este guia) - Aceite: Registrar aceite formal com verificação de identidade

---

🎯 Quando Usar

Use a leitura pública quando você quer: - Exibir termos de uso em uma página de "Sobre" de outro site - Mostrar política de privacidade para leitura - Incorporar documentos legais em sites externos - Permitir consulta sem obrigatoriedade de aceite

---

🚀 3 Formas de Implementação

Opção 1: Página HTML Completa (Melhor para links diretos)

#### URLs Disponíveis: ` https://sua-plataforma.com/documents/read/<slug>/ `

Exemplo: ` https://legal-docs.com/documents/read/termos-de-uso/ `

#### Como Usar: 1. Configure o public_acceptance_slug no documento 2. Ative public_acceptance_enabled = True 3. Compartilhe o link

#### Recursos: - ✅ Layout completo com header e footer - ✅ Botão para aceitar (se necessário) - ✅ Informações de versão e vigência - ✅ Botão de impressão - ✅ Responsivo

---

Opção 2: Iframe Embarcado (Melhor para incorporação)

#### URLs Disponíveis: ` https://sua-plataforma.com/documents/read/embedded/<UUID>/ `

Exemplo: `html <!-- No seu site externo --> <div class="terms-container"> <iframe id="terms-iframe" src="https://legal-docs.com/documents/read/embedded/550e8400-e29b-41d4-a716-446655440000/" width="100%" height="600" frameborder="0" title="Termos de Uso" style="border: 1px solid #e5e7eb; border-radius: 8px;" ></iframe> </div>

<script> // Ajusta altura automaticamente window.addEventListener('message', function(event) { if (event.data.type === 'resize_iframe') { document.getElementById('terms-iframe').style.height = event.data.height + 'px'; } }); </script> `

#### Configuração (Opcional):

Se quiser controlar quais domínios podem incorporar:

`python from apps.agreements.models import Document, EmbeddedAcceptanceConfig

document = Document.objects.get(public_acceptance_slug="termos-de-uso")

Cria ou atualiza configuração

config, _ = EmbeddedAcceptanceConfig.objects.get_or_create( document=document, defaults={ 'enabled': True, 'allowed_domains': [ 'seusite.com', 'www.seusite.com', '*.seusite.com', # Permite subdomínios ], 'custom_css': ''' .title { color: #2563eb; } .content { font-size: 16px; } ''', 'hide_powered_by': True, } ) `

#### Recursos: - ✅ Layout minimalista (sem header/footer) - ✅ Customizável via CSS - ✅ Validação de domínios permitidos - ✅ Ajuste automático de altura - ✅ Sem botões de aceite

---

Opção 3: API REST (JSON) (Melhor para customização total)

#### URLs Disponíveis: ` GET https://sua-plataforma.com/api/documents/<slug>/ `

Exemplo de Request: `bash curl https://legal-docs.com/api/documents/termos-de-uso/ `

Resposta: `json { "document_id": "550e8400-e29b-41d4-a716-446655440000", "name": "Termos de Uso", "slug": "termos-de-uso", "description": "Termos e condições de uso da plataforma", "version": { "version_number": "2.0", "title": "Termos de Uso - Versão 2.0", "content_html": "<h1>Termos de Uso</h1><p>...</p>", "content_plain": "Termos de Uso\n\n...", "effective_date": "2024-01-01", "published_at": "2024-01-01T10:00:00Z" }, "urls": { "read": "https://legal-docs.com/documents/read/termos-de-uso/", "accept": "https://legal-docs.com/acceptance/termos-de-uso/", "embedded": "https://legal-docs.com/documents/read/embedded/550e8400-e29b-41d4-a716-446655440000/" }, "meta": { "retrieved_at": "2024-01-15T14:30:00Z", "cache_ttl": 3600 } } `

#### Implementação no Seu Site:

HTML: `html <div id="terms-content"> <div class="loading">Carregando termos de uso...</div> </div> `

JavaScript: `javascript async function loadTerms() { try { const response = await fetch( 'https://legal-docs.com/api/documents/termos-de-uso/' ); const data = await response.json(); // Renderiza o conteúdo document.getElementById('terms-content').innerHTML = ` <div class="terms-header"> <h1>${data.version.title}</h1> <p class="meta"> Versão ${data.version.version_number} • Vigência: ${new Date(data.version.effective_date).toLocaleDateString('pt-BR')} </p> </div> <div class="terms-body"> ${data.version.content_html} </div> <div class="terms-footer"> <a href="${data.urls.accept}" class="btn-accept"> Aceitar Termos de Uso </a> </div> `; } catch (error) { console.error('Erro ao carregar termos:', error); document.getElementById('terms-content').innerHTML = '<p class="error">Erro ao carregar termos de uso.</p>'; } }

// Carrega quando a página carregar loadTerms(); `

React/Next.js: `jsx 'use client';

import { useEffect, useState } from 'react';

export default function TermsOfService() { const [terms, setTerms] = useState(null); const [loading, setLoading] = useState(true);

useEffect(() => { fetch('https://legal-docs.com/api/documents/termos-de-uso/') .then(res => res.json()) .then(data => { setTerms(data); setLoading(false); }) .catch(err => { console.error(err); setLoading(false); }); }, []);

if (loading) return <div>Carregando...</div>; if (!terms) return <div>Erro ao carregar termos</div>;

return ( <div className="terms-container"> <h1>{terms.version.title}</h1> <div className="meta"> Versão {terms.version.version_number} • Vigência: {new Date(terms.version.effective_date).toLocaleDateString('pt-BR')} </div> <div className="content" dangerouslySetInnerHTML={{ __html: terms.version.content_html }} /> <a href={terms.urls.accept} className="btn-accept"> Aceitar Termos </a> </div> ); } `

#### Recursos: - ✅ Customização total do design - ✅ CORS habilitado (Access-Control-Allow-Origin: *) - ✅ Cache HTTP (1 hora) - ✅ HTML e texto puro disponíveis - ✅ Links para aceite e embedded inclusos

---

📊 Comparação das Opções

| Aspecto | Página HTML | Iframe | API REST | |---------|------------|--------|----------| | Implementação | ⭐⭐⭐ Muito fácil | ⭐⭐ Fácil | ⭐ Requer código | | Customização | ❌ Limitada | ⚠️ CSS apenas | ✅ Total | | Manutenção | ✅ Zero | ✅ Zero | ⚠️ Você controla | | Atualização | ✅ Automática | ✅ Automática | ⚠️ Depende do cache | | Performance | ⭐⭐ Boa | ⭐⭐ Boa | ⭐⭐⭐ Excelente | | SEO | ✅ Indexável | ❌ Não indexa | ✅ Você controla | | Mobile | ✅ Responsivo | ✅ Responsivo | ✅ Você controla |

---

🔧 Configuração Passo a Passo

1. No Django Admin:

`python

Via shell ou admin

from apps.agreements.models import Document

1. Configure o documento

document = Document.objects.get(name="Termos de Uso") document.public_acceptance_slug = "termos-de-uso" document.public_acceptance_enabled = True document.is_active = True document.save()

2. Certifique-se de ter uma versão ativa

version = document.get_active_version() print(f"Versão ativa: {version.version}")

3. Obtenha as URLs

print(f"URL Leitura: /documents/read/{document.public_acceptance_slug}/") print(f"URL Embedded: /documents/read/embedded/{document.document_key}/") print(f"URL API: /api/documents/{document.public_acceptance_slug}/") `

2. (Opcional) Configure Embedding com Domínios Restritos:

`python from apps.agreements.models import EmbeddedAcceptanceConfig

config = EmbeddedAcceptanceConfig.objects.create( document=document, enabled=True, allowed_domains=[ 'seusite.com', 'www.seusite.com', 'staging.seusite.com', ], custom_css=''' .title { color: #1a56db; font-family: 'Inter', sans-serif; } .content { font-size: 15px; line-height: 1.8; } ''', hide_powered_by=True, ) `

3. Teste as URLs:

Página HTML: ` http://localhost:8000/documents/read/termos-de-uso/ `

Iframe: ` http://localhost:8000/documents/read/embedded/550e8400-e29b-41d4-a716-446655440000/ `

API: `bash curl http://localhost:8000/api/documents/termos-de-uso/ `

---

🎨 Exemplos de Customização CSS

Estilo Moderno (para Iframe):

`css .title { font-family: 'Inter', -apple-system, sans-serif; font-size: 28px; font-weight: 700; color: #111827; letter-spacing: -0.02em; }

.content { font-size: 16px; line-height: 1.75; color: #374151; }

.content h2 { color: #1f2937; font-size: 20px; font-weight: 600; margin-top: 2em; border-bottom: 2px solid #e5e7eb; padding-bottom: 0.5em; }

.content ul { list-style: none; padding-left: 0; }

.content li::before { content: "✓ "; color: #10b981; font-weight: bold; margin-right: 8px; } `

Estilo Minimalista:

`css * { font-family: 'Georgia', serif; }

.title { font-size: 32px; font-weight: 400; color: #000; text-align: center; }

.content { max-width: 650px; margin: 0 auto; font-size: 18px; line-height: 1.6; color: #333; } `

---

🔒 Segurança

CORS (API):

- A API retorna Access-Control-Allow-Origin: * - Permite acesso de qualquer domínio - Sem autenticação necessária (conteúdo público)

Iframe:

- Headers CSP configurados automaticamente - Validação de domínios permitidos (se configurado) - Sem cookies ou sessões necessários

---

💡 Casos de Uso

1. Site Institucional:

`html <!-- Em https://meusite.com/termos --> <iframe src="https://legal-docs.com/documents/read/embedded/UUID/" width="100%" height="800"></iframe> `

2. SPA/React App:

`jsx import TermsAPI from './components/TermsAPI';

function TermsPage() { return <TermsAPI slug="termos-de-uso" />; } `

3. Link Direto:

`html <a href="https://legal-docs.com/documents/read/termos-de-uso/" target="_blank"> Leia nossos Termos de Uso </a> `

---

🆚 Comparação: Leitura vs Aceite

| Feature | Leitura | Aceite | |---------|---------|--------| | Formulário | ❌ Não | ✅ Sim | | Verificação Email | ❌ Não | ✅ Sim (Magic Link/OTP) | | Registro em BD | ❌ Não | ✅ Sim | | Auditoria | ❌ Não | ✅ Completa | | Certificado | ❌ Não | ✅ Sim | | Uso | Consulta | Aceite Legal |

---

📱 Responsividade

Todas as 3 opções são mobile-friendly: - Página HTML: Responsiva com Tailwind CSS - Iframe: Ajusta altura automaticamente - API: Você controla o design

---

⚡ Performance

Cache:

- API: Cache HTTP de 1 hora (Cache-Control: public, max-age=3600) - HTML/Iframe: Cache controlado pelo navegador

CDN (recomendado):

`nginx

Nginx

location ~ ^/documents/read/ { proxy_cache my_cache; proxy_cache_valid 200 1h; add_header X-Cache-Status $upstream_cache_status; } `

---

🐛 Troubleshooting

Iframe não carrega:

1. Verifique allowed_domains na configuração 2. Teste com allowed_domains = [] (modo permissivo) 3. Verifique console do navegador (CORS/CSP)

API retorna 404:

1. Verifique public_acceptance_enabled = True 2. Verifique is_active = True 3. Verifique se existe versão ativa

Conteúdo não atualiza:

1. Limpe cache do navegador 2. Verifique se a versão está publicada 3. Force refresh: Ctrl+Shift+R

---

🎓 Próximos Passos

- [ ] Configure seus documentos - [ ] Escolha o método (HTML, Iframe ou API) - [ ] Implemente no seu site - [ ] (Opcional) Configure domínios permitidos - [ ] (Opcional) Customize o CSS - [ ] Teste em produção

---

💬 Dúvidas?

Se precisar de aceite formal (com verificação de identidade), use: - /acceptance/<slug>/ - Formulário de aceite público - /embedded/<uuid>/ - Aceite via iframe (com formulário)

Este guia é para leitura apenas, sem aceite.

Esta página foi útil?