Portal de documentação técnica isolado em SaaS next.js: nextra, prisma e auth middleware sem poluição de banco
Voltar para blog

Portal de documentação técnica isolado em SaaS next.js: nextra, prisma e auth middleware sem poluição de banco

07/06/2026 · 6 min · Desenvolvimento

Documentação técnica fragmentada em repositório SaaS ativo#

Em stacks maduras de produção, a documentação técnica tende a evoluir em paralelo ao produto - arquivos .md isolados acumulam-se no repositório sem estrutura de navegação, busca ou controle de acesso. Este é o cenário clássico enfrentado: um SaaS em Next.js + React + Node + Prisma + MongoDB com dezenas de módulos críticos documentados em Markdown solto - schemas Prisma completos, payloads de API, diagramas de arquitetura em ASCII art e tabelas de transição de estados - mas sem nenhuma camada de portal unificada para a equipe consumir.

A pergunta operacional que precisava ser respondida antes de qualquer implementação: como consolidar essa documentação em um portal profissional sem introduzir dependências que poluam o banco de dados, quebrem o pipeline de CI/CD ou exponham dados sensíveis publicamente?


1. Pré-requisitos e versões mínimas requeridas#

Para garantir a estabilidade e evitar quebras de empacotamento no build final da aplicação, estabelecemos os seguintes limites mínimos de versão:

Dependência TécnicaVersão Mínima RequeridaPapel no Portal
Next.js14.0+ (App Router ou Pages Router)Framework core da aplicação
Nextra3.0+Engine de renderização de documentação MDX
Node.js18.0+ (LTS)Runtime de execução do servidor
Clerk / NextAuth.jsÚltima estável configuradaProvedor de autenticação e sessão
Prisma ORM5.0+Camada de mapeamento de dados (não afetada pelo Nextra)
MongoDB6.0+Banco de dados transacional (não afetado pelo Nextra)

2. Auditoria comparativa das ferramentas#

Antes de comprometer qualquer mudança no repositório, fiz uma análise estrutural das alternativas de portais de documentação:

Docusaurus (meta)#

O padrão da indústria para portais developer-focused. Suporte nativo a MDX, versionamento de API, i18n e barra de busca Algolia. O bloqueio arquitetural: exige um projeto React/Node completamente separado. Isso implica um segundo pipeline de CI/CD, segundo processo de build, segunda configuração de variáveis de ambiente e um overhead de manutenção que não se justificava - documentação interna para uma equipe pequena numa stack já consolidada.

Domain.com / mintlify e similares#

Ferramentas baseadas em SaaS externos são projetadas para extração de conteúdo público ou manuais de uso para clientes finais. O bloqueio arquitetural: hospedar documentação técnica de infraestrutura e schemas internos de dados em nuvens terceiras expõe o código a riscos desnecessários de segurança, além de exigir sincronismo constante de chaves e controle de acesso via OAuth externo.

Nextra#

Framework de documentação construído sobre Next.js puro. A proposta de valor é direta: zero overhead de infraestrutura adicional, pois opera dentro do mesmo processo de build next build já existente. Suporta MDX nativamente, renderiza tabelas Markdown com fidelidade total, mantém espaçamento monoespaçado em diagramas ASCII e aplica syntax highlighting automático para blocos TypeScript, Shell e Prisma. Zero nova dependência de infraestrutura.


3. Validação forense: o nextra toca o MongoDB/prisma?#

Esta foi a questão crítica de validação antes da implementação. A preocupação era legítima: um módulo instalado como dependência Next.js poderia tentar importar o Prisma Client ou abrir conexões com o banco durante o ciclo de vida do servidor.

Resultado da análise: O Nextra opera exclusivamente na camada de sistema de arquivos durante o processo de build do Next.js. Sua pipeline de transformação é a seguinte:

/docs/*.md (filesystem)
   ↓
  Nextra Parser (remark + rehype plugins)
   ↓
  Next.js getStaticProps / getStaticPaths
   ↓
  HTML estático gerado no build
   ↓
  Servido via CDN / Next.js Static File Handler

O Nextra não:

Ele é estritamente um transformador de Markdown → HTML executado pela engine de SSG do Next.js (getStaticProps), funcionando em isolamento total da camada ORM.


4. Configuração detalhada do tema (theme.config.jsx)#

O comportamento visual, a indexação da busca integrada e as preferências de UI são gerenciados centralizadamente no arquivo theme.config.jsx na raiz do projeto.

// theme.config.jsx
import React from 'react'

export default {
  logo: <span>📘 DocCenter Interno</span>,
  project: {
    link: 'https://github.com/seu-org/seu-repo',
  },
  docsRepositoryBase: 'https://github.com/seu-org/seu-repo/tree/main/docs',
  head: (
    <>
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <meta name="description" content="Portal de Documentação Técnica Interna - SaaS" />
      <meta name="robots" content="noindex, nofollow" /> {/* Blindagem SEO externa */}
    </>
  ),
  
  // Nextra já inclui busca full-text integrada baseada em FlexSearch
  search: {
    placeholder: 'Buscar documentação...',
  },

  // Configurações de Dark Mode e Design System
  darkMode: true, // Habilitar alternância de tema escuro/claro
  nextThemes: {
    defaultTheme: 'dark', // Forçar o tema dark como padrão
  },
  primaryHue: {
    dark: 210, // Tons azuis para o tema dark
    light: 200
  },
  primarySaturation: 100,

  footer: {
    text: () => (
      <span>
        © {new Date().getFullYear()} DocCenter Interno. Acesso restrito a engenheiros autorizados.
      </span>
    )
  }
}

5. MDX e componentes avançados do nextra#

Com o Nextra, você pode renderizar componentes React dinâmicos diretamente no corpo da documentação Markdown. Abaixo, exemplos do uso dos componentes utilitários integrados Callout e Steps.

Exemplo de uso no MDX (badges.md)#

---
title: Sistema de Badges
description: Documentação técnica do sistema de gamificação e conquistas.
---

import { Callout, Steps } from 'nextra/components'

# Sistema de Badges - Documentação Técnica

## Modelo de dados (prisma schema)

model Badge { id String @id @default(auto()) @map("_id") @db.ObjectId name String @unique slug String @unique category BadgeCategory createdAt DateTime @default(now()) }


<Callout type="warning" emoji="⚠️">
  **Atenção de Migração**: Modificações no model `Badge` exigem execução do script de sync de dados `npx prisma db push` em lote. Certifique-se de que não restam transações ativas pendentes.
</Callout>

## Fluxo de integração de webhooks

<Steps>
### Configurar endpoint do webhook
Configure o listener de recebimento na URL `/api/webhooks/canny`.
 
### Validar assinatura canny
Verifique o header `X-Canny-Signature` usando o segredo criptográfico compartilhado.
 
### Processar concessão
Se o evento for `post.status_changed` e mover para `completed`, execute a rotina de atribuição da Badge no banco.
</Steps>

6. Engenharia de segurança: proteção da rota /docs via middleware#

A documentação contém schemas Prisma com tipos de dados, payloads de webhooks com estrutura de eventos internos e fluxos de autenticação detalhados. Exposição pública é inaceitável. A proteção foi implementada aproveitando o Middleware do Next.js já existente na aplicação.

Configuração do middleware.ts com tratamento de sessão#

O middleware de autenticação (usando Clerk ou NextAuth.js) intercepta as chamadas nas rotas especificadas no matcher e avalia o tempo de vida do cookie de sessão.

// middleware.ts
import { authMiddleware } from "@clerk/nextjs"; // ou NextAuth equivalente

export default authMiddleware({
  // Rotas explicitamente públicas - não requerem sessão ativa
  publicRoutes: [
    "/",
    "/login",
    "/signup",
    "/api/public",
    "/api/webhooks/(.*)"
  ],
  // Rotas restritas e fluxo de redirecionamento automático
  // Caso a sessão expire (Session Timeout), redireciona o usuário para a página de login
});

export const config = {
  matcher: [
    // Capturar todas as rotas de páginas e APIs, exceto arquivos estáticos
    "/((?!.*\\..*|_next).*)",
    "/",
    "/(api|trpc)(.*)",
    "/docs/:path*" // Rota de documentação explicitamente capturada
  ],
};

Roteiro de testes de autenticação via CLI#

Para homologar a segurança da rota /docs/badges sem o uso de navegadores, execute as seguintes requisições com curl:

# 1. Testar acesso anônimo (Sem autenticação)
# Esperado: Retornar HTTP 302 com cabeçalho Location apontando para o login
curl -I http://localhost:3000/docs/badges

# 2. Testar acesso com Token de Sessão Inválido ou Expirado
# Esperado: Retornar HTTP 401 Unauthorized ou redirecionamento de segurança
curl -I -H "Authorization: Bearer <TOKEN_INVALIDO>" http://localhost:3000/docs/badges

# 3. Testar acesso com Token Autenticado Válido
# Esperado: Retornar HTTP 200 OK com o conteúdo estruturado da documentação
curl -I -H "Authorization: Bearer <TOKEN_VALIDO>" http://localhost:3000/docs/badges

7. Versionamento de documentações por subdiretórios#

O Nextra suporta versionamento estático de documentação organizando os arquivos .md em subpastas dedicadas e configurando arquivos _meta.json específicos para cada versão:

/docs
  /v1
    _meta.json
    index.md
    badges.md
  /v2
    _meta.json
    index.md
    badges.md

Configuração do _meta.json do diretório /docs/v2/#

{
  "index": "Visão Geral V2",
  "badges": "🏅 Sistema de Badges Avançado (V2)"
}

8. Validação de build de produção#

Para validar que o compilador do Next.js gerou corretamente as páginas estáticas e mapeou todos os caminhos do Nextra sem erros sintáticos:

# 1. Executar o build estático de produção
npm run build

# 2. Inspecionar logs em busca de avisos ou erros de compilação
npm run build 2>&1 | grep -i "error"

# 3. Validar se os arquivos estáticos foram gerados fisicamente no diretório de saída
ls -la .next/server/app/docs/

# 4. Verificar o tamanho total dos chunks estáticos do frontend
ls -la .next/static/chunks/

# 5. Iniciar o servidor em modo de produção
npm run start

Dispare uma chamada local contra a rota gerada para validar o header de resposta:

# Testar se a página index da documentação responde com sucesso após o build
curl -I http://localhost:3000/docs/

9. Estratégias de deploy da documentação#

Deploy nativo via vercel#

Se a sua stack Next.js já utiliza a Vercel, o deploy é integrado automaticamente a cada push na branch protegida. Para disparar manualmente em modo produção:

# Executar build e deploy de produção na Vercel
vercel --prod

Deploy conteinerizado via Docker multi-stage#

Se o seu SaaS roda em nuvens como AWS, GCP ou infraestruturas dedicadas, utilize o seguinte Dockerfile otimizado:

# Estágio 1: Instalação e Build
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Estágio 2: Runner de Produção
FROM node:18-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json

EXPOSE 3000
USER node
CMD ["npm", "run", "start"]

Configuração do Docker compose (docker-compose.yml)#

version: "3.8"
services:
  saas-app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    restart: always
    environment:
      - NODE_ENV=production

Checklist: documentação nextra em SaaS next.js#

1. Pré-implementação#

2. Configurações de compilação e layout#

3. Migração de conteúdo e versionamento#

4. Segurança e middleware#

5. Compilação, validação e deploy#

Este artigo foi útil?

Deixe uma reação rápida para apoiar o conteúdo:

CC BY-NC

Este post está licenciado sob CC BY-NC.

Comentários

Participe da discussão abaixo.

0 comentários