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
notasoupedidos. - 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 startO 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/healthA 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:
| Rota | O que faz |
|---|---|
POST /v1/units/:unitId/tokens | Cria um token |
GET /v1/units/:unitId/tokens | Lista os tokens |
DELETE /v1/units/:unitId/tokens/:tokenId | Apaga um token |
GET /v1/units | Lista os projetos |
Credenciais e tokens
O QPBase usa três tipos de credencial. Cada uma tem o seu lugar.
| Credencial | Como se envia | Serve para | Onde guardar |
|---|---|---|---|
| Chave mestra | Authorization: Bearer … | Criar projetos e tokens, exportar e importar, ver o estado do sistema | Só no servidor, em QPBASE_MASTER_KEY |
Token do projeto (qpk_…) | Authorization: Bearer … | Dados, contas, ficheiros e notificações desse projeto | Só no servidor da sua aplicação |
Token do utilizador (qus_…) | X-User-Token: … | Identificar o utilizador com sessão. É devolvido no login | A 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ável | Padrão | Para que serve |
|---|---|---|
QPBASE_MASTER_KEY | obrigatória | Chave mestra. 16 caracteres ou mais. Não pode ser o valor de exemplo |
PORT | 8787 | Porta do servidor |
QPBASE_DATA_DIR | ./qpbase-data | Pasta dos dados. Ponha-a em disco persistente, para os dados sobreviverem a novos deploys |
QPBASE_CORS_ORIGIN | vazio | Origem permitida por CORS. Deixe vazio se só a sua aplicação fala com o QPBase |
QPBASE_RATE_WINDOW_MS | 60000 | Janela do limite de pedidos, em milissegundos |
QPBASE_RATE_MAX | 180 | Pedidos permitidos por janela, por IP |
QPBASE_ADMIN_ENABLED | false | Liga o painel de administração em /admin |
QPBASE_ADMIN_PASSWORD | vazio | Palavra-passe do painel. 12 caracteres ou mais e diferente da chave mestra |
QPBASE_ADMIN_SESSION_MIN | 30 | Duração da sessão do painel, em minutos |
QPBASE_ADMIN_IMPORT_MAX_MB | 100 | Tamanho máximo de uma importação, em MB |
QPBASE_TRUST_PROXY | false | Ponha true só se estiver atrás de um proxy HTTPS de confiança |
QPBASE_ADMIN_ALLOW_HTTP | false | Só para testes locais, sem HTTPS |
FCM_PROJECT_ID, FCM_CLIENT_EMAIL, FCM_PRIVATE_KEY | vazio | Credenciais do Firebase Cloud Messaging (push) |
RESEND_API_KEY, RESEND_FROM | vazio | Credenciais do Resend (email) |
TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_FROM | vazio | Credenciais 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.
| Rota | Corpo | O 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çalho | Termina a sessão |
GET /v1/:unitId/auth/me | cabeçalho X-User-Token | Devolve 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.
| Rota | Corpo | O que faz |
|---|---|---|
GET /v1/:unitId/:colecao?limit=100&offset=0 | Lista 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/:id | Devolve um registo, ou 404 | |
PUT /v1/:unitId/:colecao/:id | { "data": { … } } | Atualiza o registo |
DELETE /v1/:unitId/:colecao/:id | Apaga 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
| Rota | O que faz |
|---|---|
POST /v1/:unitId/blobs | Envia um ficheiro. Corpo: { filename, contentType, data }, com data em base64 |
GET /v1/:unitId/blobs?limit=50&offset=0 | Lista ficheiros. O máximo é 200 por pedido |
GET /v1/:unitId/blobs/:id | Devolve os dados do ficheiro (nome, tipo, tamanho) |
GET /v1/:unitId/blobs/:id?download=1 | Descarrega o ficheiro |
DELETE /v1/:unitId/blobs/:id | Apaga 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.
| Rota | Corpo | Serviç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| Grupo | Mé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
- Crie a base e o bucket:
wrangler d1 create qpbase-coreewrangler r2 bucket create qpbase-core-blobs. - Copie
wrangler.toml.exampleparawrangler.tomle preencha odatabase_idda sua base D1. - Defina os segredos:
wrangler secret put QPBASE_MASTER_KEY(eQPBASE_ADMIN_PASSWORD, se quiser o painel). - 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çaO 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/export | Exporta um projeto |
POST /v1/units/:unitId/import | Importa um projeto |
GET /v1/admin/export | Exporta o servidor inteiro |
POST /v1/admin/import | Importa 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ódigo | Significado |
|---|---|
| 400 | Pedido inválido (por exemplo, email ou palavra-passe inválidos, ou ficheiro de tipo não aceite) |
| 401 | Falta a credencial, ou está errada |
| 403 | Sem permissão (por exemplo, registo de outro utilizador, ou coleção reservada) |
| 404 | Não existe |
| 405 | Método não permitido nesta rota |
| 413 | Pedido demasiado grande |
| 429 | Demasiados pedidos. Espere e repita (por omissão, 180 por minuto por IP) |
| 501 | Notificaçõ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.