Pular para o conteúdo principal

Virtual Stores System — Visao Geral do Sistema

Documento de referencia para administradores de sistema da In All Web. Audiencia: equipa tecnica interna (SysAdmin).


Arquitectura Geral

O Virtual Stores System e uma plataforma SaaS multi-tenant de e-commerce composta por tres camadas principais:

CamadaTecnologiaFuncao
Backend APIFastAPI + Python 3.12Logica de negocio, autenticacao, REST API
Admin PanelReact 19 + Vite (SPA)Painel de gestao para admins de tenant
StorefrontNext.js 15 (App Router, SSR/SSG)Loja publica indexavel pelo Google

Cada camada e deployada como container Docker independente e orquestrada via Docker Compose + Traefik como reverse proxy.

Internet
|
Traefik (reverse proxy + TLS)
|
+-- /api/* --> Backend (FastAPI, porta 8000)
+-- /admin/* --> Admin Panel (React SPA, porta 5173)
+-- {slug}.store.* --> Storefront (Next.js, porta 3001)

Multi-Tenant

Isolamento de dados

O isolamento entre tenants e garantido por Row-Level Security (RLS) ao nivel da base de dados. Cada tabela relevante tem a coluna tenant_id e todas as queries sao filtradas automaticamente.

Nunca e possivel, por design, que um tenant aceda a dados de outro tenant.

UnifiedTenantMiddleware

O middleware UnifiedTenantMiddleware resolve qual o tenant activo em cada pedido, seguindo esta ordem de prioridade:

  1. JWT token (campo tenant_id no payload)
  2. Subdominio ({slug}.store.inallweb.com)
  3. Dominio custom (mapeado na tabela custom_domains)
  4. Fallback (rejeicao com 401 ou 404)

O tenant resolvido e injectado no contexto do pedido e propagado para todas as queries da BD.

FeatureGateMiddleware

O FeatureGateMiddleware verifica, para cada endpoint protegido, se o tenant tem o plano ou addon necessario. Endpoints marcados com @require_plan("business") ou @require_addon("wishlist") sao bloqueados automaticamente se o tenant nao tiver a funcionalidade activa.


Base de Dados

PostgreSQL 15 — usado em todos os ambientes (dev, uat, staging, prod). SQLite nunca e usado.

Configuracao de pool recomendada:

engine = create_async_engine(
DATABASE_URL,
pool_pre_ping=True,
pool_size=10,
max_overflow=20,
pool_recycle=3600,
)

Migracoes geridas via Alembic. Sempre testar migracoes em dev antes de aplicar em staging ou prod.

Porta padrao em dev/uat: 5435 (mapeada do container para o host).


Cache

Redis e usado para:

  • Cache de sessoes e tokens JWT revogados
  • Cache de resultados de pesquisa e catalogo
  • Rate limiting
  • Filas de tarefas async (Celery, quando aplicavel)

Armazenamento de Imagens

MinIO (S3-compatible) armazena todas as imagens de produtos, logos e banners dos tenants.

O acesso publico e feito via Cloudflare CDN como proxy, o que garante:

  • Cache de imagens no edge (menor latencia para utilizadores finais)
  • Proteccao do endpoint MinIO directo
  • URLs limpas sem expor o storage interno

Configuracao no bucket: products (bucket principal).

Utilizador --> Cloudflare CDN --> MinIO
(cache edge) (storage)

Pagamentos — Stripe Connect

Os pagamentos sao orquestrados pelo iaw-platform, que actua como hub central de Stripe Connect. O virtual-stores nunca interage directamente com a API do Stripe — chama sempre o iaw-platform.

Fluxo:

Loja (checkout) --> Backend VSS --> iaw-platform API --> Stripe Connect
/api/stripe-connect/*
(JWT Bearer)

Cada tenant tem um stripe_connect_account_id registado apos completar o onboarding KYC federado.

Referencia: /opt/contracts/stripe-connect-flow.md


Emails

Zeptomail e o servico de envio de emails transacionais. Os templates estao disponiveis em 6 idiomas: PT, EN, FR, ES, IT, DE.

Tipos de email enviados:

  • Confirmacao de registo e verificacao de email
  • Confirmacao de encomenda
  • Actualizacao de estado de envio
  • Recuperacao de password
  • Faturas (em conjunto com Moloni)

Referencia de templates: /opt/contracts/email-templates.md


Modulos Backend

O backend esta organizado em modulos independentes. Cada modulo vive em src/modules/<modulo>/ e contem routes.py, schemas.py, service.py e models.py.

ModuloDescricao
authLogin, registo, JWT, refresh tokens, roles
productsCRUD de produtos, variantes, precos
categoriesHierarquia de categorias por tenant
cartCarrinho de compras (sessao ou autenticado)
checkoutFluxo de checkout multi-passo
ordersGestao de encomendas, estados, historico
paymentsIntegracao com iaw-platform / Stripe Connect
couponsCodigos de desconto e promocoes
customersPerfis de clientes finais
reviewsAvaliacoes e comentarios de produtos
wishlistLista de desejos (addon)
loyaltyPrograma de pontos e fidelizacao (addon)
searchPesquisa por tags e atributos
recommendationsRecomendacoes de produtos
reportsRelatorios de vendas, produtos, clientes
faqPerguntas frequentes por tenant
suppliersGestao de fornecedores
inventoryControlo de stock
shippingMetodos e zonas de envio
pagesPaginas de conteudo (sobre, politicas, etc.)
storefrontAPI publica consumida pelo Next.js storefront
dashboardMetricas e KPIs para o admin do tenant
sysadminEndpoints exclusivos da equipa In All Web

Ambientes

AmbienteURL baseDadosStripeTestes
devdev.store.inallweb.comSeed/demoSandboxE2E completo
uatuat.store.inallweb.comSeed/demoSandboxE2E completo
stagingstaging.store.inallweb.comReais anonimizadosSandboxE2E completo
prod{slug}.store.inallweb.comReaisLIVE keysDry-run apenas

DEMO_DATA_ENABLED=true em dev e uat. DEMO_DATA_ENABLED=false em staging e prod.


CI/CD — Pipeline GitLab

O repositorio usa GitLab CI com os seguintes stages em sequencia:

StageO que faz
validateLinting (Ruff, ESLint), type check (mypy, tsc)
securitypip-audit, npm audit, Semgrep OWASP
qualitySonarQube — quality gate: 0 bugs, 0 vulnerabilities, <3% duplicacao
buildBuild das imagens Docker
testpytest (backend), vitest (frontend)
releasePush de imagens para registry
deployDeploy no ambiente alvo
verifyVerificacao de health checks pos-deploy
e2eTestes Playwright end-to-end (bloqueante em uat/staging)
evidenceCaptura de screenshots e artefactos
docsGeracao automatica de documentacao
promotePromove para o ambiente seguinte (dev->uat->staging->prod)

Branches protegidas (sem push directo): main, prod, staging.

Runners registados com tags: stores-ci (validate, build, test, E2E) e stores-deploy (deploy, verify, promote).


Endpoints de Monitoring

O Zabbix monitoriza todos os ambientes. O backend expoe:

GET /api/health

Retorna 200 se o servidor esta a correr. Sem autenticacao. Usado pelo load balancer.

{"status": "ok"}

GET /api/ready

Retorna 200 se todas as dependencias estao operacionais (BD + Redis + MinIO). Retorna 503 se alguma dependencia estiver em baixo. O deploy script verifica este endpoint antes de trocar trafego.

{"ready": true}

Graceful shutdown configurado a 30 segundos (timeout_graceful_shutdown=30).


Feature Gating

O FeatureGateMiddleware controla o acesso a funcionalidades com base no plano do tenant e nos addons activos.

Exemplos de restricoes:

FuncionalidadePlano minimo
Multi-utilizador (staff)Business
WishlistAddon activado
Loyalty programAddon activado
Relatorios avancadosProfessional
Multi-sistemaProfessional

O middleware consulta o plano e addons activos do tenant em cada pedido e rejeita com 403 se o acesso nao for permitido.


Seguranca e RGPD

  • Passwords com bcrypt
  • JWT com refresh tokens (dual-token)
  • RLS na BD por tenant_id
  • Dados pessoais nunca em logs (nomes, emails, NIF, moradas)
  • Anonimizacao obrigatoria ao copiar dados de prod para staging/dev
  • Script: stores-management/backend/scripts/anonymize_db.py
  • Credenciais em Vault (secret/data/stores/*) — nunca em codigo ou commits

Contactos e Recursos

RecursoURL / Path
GitLabhttps://gitlab.inallweb.com
SonarQubehttps://sonarqube.inallweb.com
Vaulthttps://vault.inallweb.com
Mattermosthttps://mattermost.inallweb.com
Contratos inter-projecto/opt/contracts/
Repositorio/opt/products/virtual-stores-system/