Nesta página

Nesta página

Visão geralRequisitosInstalar e arrancarCriar um projetoCredenciais e tokensVariáveis de ambienteContas de utilizadorDados em coleçõesFicheirosNotificaçõesSDK JavaScriptCloudflare WorkersPainel e cópias de segurançaSegurançaTrabalhar com IAErros e limites

Documentação do QPBase 1.0.1

Tudo o que precisa para instalar, configurar e usar o QPBase. Se vai usar uma IA, comece pelo passo a passo da página inicial.

Visão geral

O QPBase é um servidor HTTP pequeno, sem dependências externas, que guarda os dados de um ou mais projetos num único servidor. A sua aplicação fala com ele por API ou pelo SDK JavaScript que vem na pasta.

A estrutura é sempre a mesma: o navegador fala com a sua aplicação, e só a sua aplicação fala com o QPBase.

O navegador nunca deve falar diretamente com o QPBase. O token do projeto dá acesso a todos os dados desse projeto, por isso fica só no servidor da sua aplicação, em variáveis de ambiente.

Conceitos

  • Projeto (unit): um espaço isolado, com o seu id, os seus tokens e os seus dados. Um servidor QPBase pode ter vários projetos.
  • Coleção: um grupo de registos dentro de um projeto, por exemplo notas ou pedidos.
  • Registo: um objeto JSON guardado numa coleção, com um id.
  • Utilizador: uma conta do seu site, com email e palavra-passe, guardada no projeto.

Requisitos

  • Node 18 ou superior, num servidor que fique sempre a correr e com disco persistente onde o QPBase possa escrever (VPS, Railway, Render, Fly.io); ou
  • Cloudflare Workers, com uma base D1 e um bucket R2.

Não serve alojamento só de ficheiros estáticos, como o GitHub Pages, nem serverless sem disco persistente.

Instalar e arrancar

Extraia a pasta, copie o ficheiro de configuração e arranque:

cd qpbase-v1.0.1
cp .env.example .env
# edite o .env e defina QPBASE_MASTER_KEY com um segredo longo e aleatório
npm start

O QPBase lê o ficheiro .env da pasta onde arranca. As variáveis que já existam no ambiente do servidor têm prioridade sobre as do ficheiro. Para gerar uma chave mestra:

node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

A chave mestra tem de ter 16 caracteres ou mais. O QPBase recusa arrancar se usar o valor de exemplo do .env.example.

Confirme que está a funcionar:

curl http://localhost:8787/health

A resposta é {"ok":true,"name":"QPBase","version":"1.0.1"}.

Criar um projeto

Cada site ou aplicação tem o seu projeto. Crie-o com a chave mestra:

curl -X POST http://localhost:8787/v1/units \
  -H "Authorization: Bearer A_SUA_CHAVE_MESTRA" \
  -H "Content-Type: application/json" \
  -d '{"name":"O meu site"}'

A resposta traz unit.id (o id do projeto) e token.secret (o token do projeto, que começa por qpk_). Guarde o token num local seguro e use-o só no servidor da sua aplicação.

Pode criar mais tokens para o mesmo projeto, listá-los ou apagá-los, sempre com a chave mestra:

RotaO que faz
POST /v1/units/:unitId/tokensCria um token
GET /v1/units/:unitId/tokensLista os tokens
DELETE /v1/units/:unitId/tokens/:tokenIdApaga um token
GET /v1/unitsLista os projetos

Credenciais e tokens

O QPBase usa três tipos de credencial. Cada uma tem o seu lugar.

CredencialComo se enviaServe paraOnde guardar
Chave mestraAuthorization: Bearer …Criar projetos e tokens, exportar e importar, ver o estado do sistemaSó no servidor, em QPBASE_MASTER_KEY
Token do projeto (qpk_…)Authorization: Bearer …Dados, contas, ficheiros e notificações desse projetoSó no servidor da sua aplicação
Token do utilizador (qus_…)X-User-Token: …Identificar o utilizador com sessão. É devolvido no loginA sua aplicação guarda-o por utilizador, por exemplo num cookie httpOnly

Variáveis de ambiente

Defina-as no ficheiro .env ou no ambiente do servidor.

VariávelPadrãoPara que serve
QPBASE_MASTER_KEYobrigatóriaChave mestra. 16 caracteres ou mais. Não pode ser o valor de exemplo
PORT8787Porta do servidor
QPBASE_DATA_DIR./qpbase-dataPasta dos dados. Ponha-a em disco persistente, para os dados sobreviverem a novos deploys
QPBASE_CORS_ORIGINvazioOrigem permitida por CORS. Deixe vazio se só a sua aplicação fala com o QPBase
QPBASE_RATE_WINDOW_MS60000Janela do limite de pedidos, em milissegundos
QPBASE_RATE_MAX180Pedidos permitidos por janela, por IP
QPBASE_ADMIN_ENABLEDfalseLiga o painel de administração em /admin
QPBASE_ADMIN_PASSWORDvazioPalavra-passe do painel. 12 caracteres ou mais e diferente da chave mestra
QPBASE_ADMIN_SESSION_MIN30Duração da sessão do painel, em minutos
QPBASE_ADMIN_IMPORT_MAX_MB100Tamanho máximo de uma importação, em MB
QPBASE_TRUST_PROXYfalsePonha true só se estiver atrás de um proxy HTTPS de confiança
QPBASE_ADMIN_ALLOW_HTTPfalseSó para testes locais, sem HTTPS
FCM_PROJECT_ID, FCM_CLIENT_EMAIL, FCM_PRIVATE_KEYvazioCredenciais do Firebase Cloud Messaging (push)
RESEND_API_KEY, RESEND_FROMvazioCredenciais do Resend (email)
TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_FROMvazioCredenciais do Twilio (SMS)

Contas de utilizador

O QPBase trata do registo, do login e da recuperação de palavra-passe. Todas as rotas usam o token do projeto, enviado pela sua aplicação.

RotaCorpoO que faz
POST /v1/:unitId/auth/register{ email, password, name }Cria a conta. O nome é opcional
POST /v1/:unitId/auth/login{ email, password }Devolve o token do utilizador (qus_…), válido 7 dias
POST /v1/:unitId/auth/logout{ token } ou cabeçalhoTermina a sessão
GET /v1/:unitId/auth/mecabeçalho X-User-TokenDevolve o utilizador da sessão
POST /v1/:unitId/auth/password-reset{ email }Devolve o token de recuperação (qpr_…) e a validade
POST /v1/:unitId/auth/password-reset/confirm{ token, password }Define a nova palavra-passe

A palavra-passe tem de ter pelo menos 8 caracteres e fica guardada com hash. O email é validado e guardado em minúsculas.

Chame password-reset só a partir do servidor da sua aplicação. A resposta traz o token de recuperação, e quem o tiver pode mudar a palavra-passe. Envie-o por email ao dono da conta e nunca o devolva ao navegador.

Dados em coleções

Todas as coleções são criadas à medida que as usa. O nome da coleção pode ter letras, números, _ e -, até 64 caracteres. Nomes que começam por _ são reservados.

RotaCorpoO que faz
GET /v1/:unitId/:colecao?limit=100&offset=0Lista registos. Devolve { items, total, limit, offset }. O máximo é 500 por pedido
POST /v1/:unitId/:colecao{ "data": { … } }Cria um registo (resposta 201)
GET /v1/:unitId/:colecao/:idDevolve um registo, ou 404
PUT /v1/:unitId/:colecao/:id{ "data": { … } }Atualiza o registo
DELETE /v1/:unitId/:colecao/:idApaga o registo
curl -X POST http://localhost:8787/v1/UNIT_ID/notas \
  -H "Authorization: Bearer TOKEN_DO_PROJETO" \
  -H "Content-Type: application/json" \
  -d '{"data":{"titulo":"Olá","feito":false}}'

Donos dos registos

Se o pedido levar o cabeçalho X-User-Token, os registos criados ficam marcados com o ownerId desse utilizador, e só ele (ou um administrador) os pode editar ou apagar.

As leituras e as listas não são filtradas por dono. Se cada utilizador só deve ver os seus registos, filtre na sua aplicação.

Ficheiros

RotaO que faz
POST /v1/:unitId/blobsEnvia um ficheiro. Corpo: { filename, contentType, data }, com data em base64
GET /v1/:unitId/blobs?limit=50&offset=0Lista ficheiros. O máximo é 200 por pedido
GET /v1/:unitId/blobs/:idDevolve os dados do ficheiro (nome, tipo, tamanho)
GET /v1/:unitId/blobs/:id?download=1Descarrega o ficheiro
DELETE /v1/:unitId/blobs/:idApaga o ficheiro

Cada ficheiro pode ter até 5 MB. Os tipos aceites são PNG, JPEG, GIF, WebP, PDF, texto simples e JSON.

Notificações

Todas as rotas são POST, com o token do projeto.

RotaCorpoServiço
/v1/:unitId/notify/push{ token, title, body, data }Firebase Cloud Messaging
/v1/:unitId/notify/email{ to, subject, html } ou { to, subject, text }Resend
/v1/:unitId/notify/sms{ to, body }Twilio

Cada serviço só funciona depois de definir as suas credenciais. Enquanto não existirem, a rota responde 501 com { "ok": false }: o QPBase não finge que a integração está ativa.

No Cloudflare Workers, estes serviços leem as credenciais de process.env. Confirme que o seu projeto as disponibiliza assim (por exemplo com nodejs_compat) antes de depender das notificações em produção.

SDK JavaScript

O ficheiro sdk/qpbase.js faz as chamadas por si. Use-o no servidor da sua aplicação.

const QPBase = require('./sdk/qpbase');

const qp = new QPBase({
  url: process.env.QPBASE_URL,            // por exemplo http://localhost:8787
  token: process.env.QPBASE_UNIT_TOKEN    // token do projeto (qpk_...)
});
const unitId = process.env.QPBASE_UNIT_ID;

// Dados
const notas = qp.collection(unitId, 'notas');
const nota = await notas.add({ titulo: 'Olá' });
const lista = await notas.list({ limit: 20 });
await notas.update(nota.id, { titulo: 'Olá, mundo' });
await notas.delete(nota.id);

// Contas
const auth = qp.auth(unitId);
await auth.register({ email, password, name });
const sessao = await auth.login({ email, password });   // sessao.token: guarde num cookie httpOnly
GrupoMétodos
qp.collection(unitId, nome)list, get, add, update, delete
qp.auth(unitId)register, login, logout, me, passwordReset, passwordResetConfirm
qp.blobs(unitId)list, upload, meta, download, remove
qp.notify(unitId)push, email, sms

Os métodos aceitam, no fim, o token do utilizador, quando quer que o registo fique associado a ele.

Cloudflare Workers

  1. Crie a base e o bucket: wrangler d1 create qpbase-core e wrangler r2 bucket create qpbase-core-blobs.
  2. Copie wrangler.toml.example para wrangler.toml e preencha o database_id da sua base D1.
  3. Defina os segredos: wrangler secret put QPBASE_MASTER_KEY (e QPBASE_ADMIN_PASSWORD, se quiser o painel).
  4. Publique com wrangler deploy.

As tabelas D1 são criadas no primeiro pedido. O ficheiro migrations/d1_0001_init.sql tem o mesmo esquema, se preferir correr à mão com wrangler d1 execute.

Painel e cópias de segurança

O painel de administração fica em /admin e vem desligado. Para o ligar:

QPBASE_ADMIN_ENABLED=true
QPBASE_ADMIN_PASSWORD=uma-palavra-passe-longa-com-12-ou-mais-caracteres
QPBASE_TRUST_PROXY=true     # só atrás de um proxy HTTPS de confiança

O painel pede a palavra-passe de administração (a chave mestra nunca é escrita no navegador), guarda a sessão num cookie httpOnly e SameSite=Strict, exige HTTPS (localhost é permitido para testes) e bloqueia durante 15 minutos depois de 5 tentativas falhadas. Permite listar projetos, exportar um projeto ou o servidor inteiro e importar com confirmação escrita.

Cópias de segurança pela API

Rota (chave mestra)O que faz
GET /v1/units/:unitId/exportExporta um projeto
POST /v1/units/:unitId/importImporta um projeto
GET /v1/admin/exportExporta o servidor inteiro
POST /v1/admin/importImporta o servidor inteiro

As cópias incluem as coleções, as contas de utilizador e os ficheiros. Não incluem os tokens do projeto: depois de importar num servidor novo, crie novos tokens. Guarde as cópias fora do servidor.

Segurança

  • O token do projeto e a chave mestra ficam só no servidor, em variáveis de ambiente. Nunca no código do site, no navegador nem no Git.
  • Ponha o QPBase atrás de HTTPS e, se a aplicação estiver no mesmo servidor, bloqueie no firewall o acesso externo à porta do QPBase.
  • Ligue o painel de administração só se precisar, com uma palavra-passe de 12 ou mais caracteres, diferente da chave mestra.
  • Faça cópias de segurança com regularidade e guarde-as fora do servidor.
  • O QPBase corre como um único processo por servidor, e o limite de pedidos é por processo. Para vários servidores seria preciso acrescentar uma camada externa de bloqueio e de armazenamento.
  • Mantenha o aviso «Powered by QPBase» no uso gratuito, e peça licença antes de publicar um projeto comercial.

Trabalhar com IA

A pasta inclui o ficheiro AI-INTEGRATION-INSTRUCTIONS.md, escrito para qualquer assistente de IA. Diz-lhe que regras seguir (por exemplo, o token nunca vai para o navegador), como escolher onde hospedar e como testar no fim.

Dê a pasta e o seu projeto à IA e cole este pedido:

Tens acesso à pasta do QPBase e ao meu projeto.

1. Lê primeiro o AI-INTEGRATION-INSTRUCTIONS.md e o README.md da pasta do QPBase,
   e respeita o ficheiro LICENSE.
2. Integra o QPBase no meu projeto para guardar os dados no mesmo servidor,
   sem Supabase, Firebase ou outra base de dados externa.
3. Antes de escrever código, confirma que o meu alojamento corre Node de forma
   permanente com disco gravável persistente (ou Cloudflare Workers). Se não
   correr, avisa-me e pára.
4. Nunca ponhas a chave mestra, o token do projeto ou tokens de utilizador no
   código do site, no Git ou no browser. O browser fala só com o servidor da
   aplicação, e só esse servidor fala com o QPBase.
5. Cria no projeto um .env.example com as variáveis necessárias, sem valores reais.
6. Vê no LICENSE se o meu projeto conta como uso comercial e diz-me. Se contar,
   lembra-me que preciso de uma licença comercial antes de publicar. Se for uso
   gratuito, põe o aviso "Powered by QPBase" no rodapé ou nos créditos.
7. No fim, testa /health, registo e login, e um ciclo criar, ler, editar e
   apagar. Diz-me o que integraste, como arrancar e que limitações existem.

A IA deve dizer-lhe se o projeto conta como uso comercial. Se contar, precisa de uma licença antes de publicar: veja a página da licença.

Erros e limites

CódigoSignificado
400Pedido inválido (por exemplo, email ou palavra-passe inválidos, ou ficheiro de tipo não aceite)
401Falta a credencial, ou está errada
403Sem permissão (por exemplo, registo de outro utilizador, ou coleção reservada)
404Não existe
405Método não permitido nesta rota
413Pedido demasiado grande
429Demasiados pedidos. Espere e repita (por omissão, 180 por minuto por IP)
501Notificações: o serviço ainda não tem credenciais

Os erros vêm sempre como { "error": "mensagem" }.

Precisa de ajuda ou de uma licença comercial? Escreva para licenca@isabstudio.dev.