From 670679d09c7ce35ee571f436c961d3c90c3ce123 Mon Sep 17 00:00:00 2001
From: 4Ventures <4ventures@MacBook-Air-de-4Ventures.local>
Date: Tue, 22 Sep 2026 18:50:25 +0200
Subject: [PATCH] feat: add WordPress, PrestaShop and Shopify connection slots
Per-client CMS/ecommerce channels in the agency hub with URL/API
placeholders; live sync can come later.
Co-authored-by: Cursor
---
sql/cms_integrations.sql | 31 ++++++++++++++++++++++
src/app/api/admin/create-client/route.ts | 3 +++
src/components/AgencyPortfolioBoard.tsx | 8 +++---
src/components/ClientIntegrationsPanel.tsx | 13 +++++++++
src/lib/agency.ts | 3 +++
5 files changed, 54 insertions(+), 4 deletions(-)
create mode 100644 sql/cms_integrations.sql
diff --git a/sql/cms_integrations.sql b/sql/cms_integrations.sql
new file mode 100644
index 0000000..8905ae0
--- /dev/null
+++ b/sql/cms_integrations.sql
@@ -0,0 +1,31 @@
+-- CMS / ecommerce connection slots per tenant
+-- Idempotent.
+
+alter table public.integrations drop constraint if exists integrations_provider_check;
+alter table public.integrations
+ add constraint integrations_provider_check
+ check (provider in (
+ 'meta_ads',
+ 'google_ads',
+ 'ga4',
+ 'search_console',
+ 'tag_manager',
+ 'clientify',
+ 'klaviyo',
+ 'mailchimp',
+ 'google_drive',
+ 'wordpress',
+ 'prestashop',
+ 'shopify'
+ ));
+
+insert into public.integrations (tenant_id, provider, status, label)
+select t.id, p.provider, 'disconnected', p.label
+from public.tenants t
+cross join (
+ values
+ ('wordpress', 'WordPress'),
+ ('prestashop', 'PrestaShop'),
+ ('shopify', 'Shopify')
+) as p(provider, label)
+on conflict (tenant_id, provider) do nothing;
diff --git a/src/app/api/admin/create-client/route.ts b/src/app/api/admin/create-client/route.ts
index 7bbe59c..5338681 100644
--- a/src/app/api/admin/create-client/route.ts
+++ b/src/app/api/admin/create-client/route.ts
@@ -55,6 +55,9 @@ export async function POST(req: NextRequest) {
['klaviyo', 'Klaviyo'],
['mailchimp', 'Mailchimp'],
['google_drive', 'Google Drive'],
+ ['wordpress', 'WordPress'],
+ ['prestashop', 'PrestaShop'],
+ ['shopify', 'Shopify'],
];
await fetch(`${url}/rest/v1/integrations`, {
method: 'POST',
diff --git a/src/components/AgencyPortfolioBoard.tsx b/src/components/AgencyPortfolioBoard.tsx
index e6456b9..17850a9 100644
--- a/src/components/AgencyPortfolioBoard.tsx
+++ b/src/components/AgencyPortfolioBoard.tsx
@@ -55,17 +55,17 @@ type AlertRow = {
const MATRIX_PROVIDERS = [
'meta_ads',
'google_ads',
- 'ga4',
'clientify',
'google_drive',
+ 'wordpress',
] as const;
const SHORT: Record = {
meta_ads: 'Meta',
google_ads: 'GAds',
- ga4: 'GA4',
clientify: 'CRM',
google_drive: 'Drive',
+ wordpress: 'WP',
};
function healthBadge(h: string) {
@@ -241,8 +241,8 @@ export default function AgencyPortfolioBoard() {
Panel de control · clientes y conexiones
- Cada cliente con su Meta, Google Ads, GA4, Clientify y Drive.
- Activa/apaga canales en Integraciones.
+ Cada cliente con su Meta, Google Ads, Clientify, Drive y web
+ (WordPress…). Activa/apaga canales en Conexiones.
= {
klaviyo: 'Account / list ID',
mailchimp: 'Audience ID',
google_drive: 'Folder ID (auto-match o pegar)',
+ wordpress: 'https://sitio.com + Application Password',
+ prestashop: 'https://tienda.com + API key',
+ shopify: 'mitienda.myshopify.com + Admin API token',
};
export default function ClientIntegrationsPanel({
@@ -106,6 +109,7 @@ export default function ClientIntegrationsPanel({
{ id: 'analytics', title: 'Analítica y medición' },
{ id: 'crm', title: 'CRM' },
{ id: 'email', title: 'Email / lifecycle' },
+ { id: 'cms', title: 'Web / e‑commerce' },
{ id: 'files', title: 'Archivos' },
];
@@ -278,6 +282,15 @@ export default function ClientIntegrationsPanel({
ID manual.
)}
+ {(p.id === 'wordpress' ||
+ p.id === 'prestashop' ||
+ p.id === 'shopify') && (
+
+ Guarda la URL del site (y key/token si aplica) en el
+ campo. Sync automático de pedidos/contenidos: siguiente
+ fase.
+
+ )}
);
})}
diff --git a/src/lib/agency.ts b/src/lib/agency.ts
index 5f22511..d32a833 100644
--- a/src/lib/agency.ts
+++ b/src/lib/agency.ts
@@ -10,6 +10,9 @@ export const INTEGRATION_PROVIDERS = [
{ id: 'klaviyo', label: 'Klaviyo', group: 'email' },
{ id: 'mailchimp', label: 'Mailchimp', group: 'email' },
{ id: 'google_drive', label: 'Google Drive', group: 'files' },
+ { id: 'wordpress', label: 'WordPress', group: 'cms' },
+ { id: 'prestashop', label: 'PrestaShop', group: 'cms' },
+ { id: 'shopify', label: 'Shopify', group: 'cms' },
] as const;
export type IntegrationProviderId =