feat: conectar Tablero CDC a Supabase empresarial

This commit is contained in:
2026-06-01 09:27:26 -04:00
parent a88f106eec
commit c546f59009
8 changed files with 69 additions and 69 deletions
+2 -2
View File
@@ -1,3 +1,3 @@
VITE_SUPABASE_URL="https://ecngyelpabyqbdxhftdy.supabase.co" VITE_SUPABASE_URL="https://dbit.digitalcompass.agency"
VITE_SUPABASE_ANON_KEY="TU_ANON_PUBLIC_KEY" VITE_SUPABASE_ANON_KEY="TU_ANON_PUBLIC_KEY"
VITE_WEBHOOK_URL="" VITE_WEBHOOK_URL="https://agenteit.digitalcompass.agency/webhook/tablero-cdc-sync-proyecto"
+11 -11
View File
@@ -24,7 +24,7 @@ Esta versión incluye:
- Paginación local en las vistas de Todos, Activos y Cerrados con 12 proyectos por página. - Paginación local en las vistas de Todos, Activos y Cerrados con 12 proyectos por página.
- Persistencia de proyectos en Supabase. - Persistencia de proyectos en Supabase.
- Sincronización multiusuario con Supabase Realtime. - Sincronización multiusuario con Supabase Realtime.
- Desplegables dinámicos desde Supabase `app_lists`, con fallback local mientras se termina la sincronización del Sheet. - Desplegables dinámicos desde Supabase `tablero_cdc_app_lists`, con fallback local mientras se termina la sincronización del Sheet.
--- ---
@@ -50,7 +50,7 @@ Esta versión incluye:
Las siguientes funcionalidades se implementarán en próximas fases: Las siguientes funcionalidades se implementarán en próximas fases:
1. Sincronización automática de la hoja `listas` del Google Sheet original hacia Supabase `app_lists`. 1. Sincronización automática de la hoja `listas` del Google Sheet original hacia Supabase `tablero_cdc_app_lists`.
2. Escritura automática de datos en el Sheet original mediante n8n u otra integración definida. 2. Escritura automática de datos en el Sheet original mediante n8n u otra integración definida.
3. Agregar una nueva columna final para enlace de brief en el Sheet original. 3. Agregar una nueva columna final para enlace de brief en el Sheet original.
4. Reglas de seguridad definitivas con Supabase RLS. 4. Reglas de seguridad definitivas con Supabase RLS.
@@ -173,22 +173,22 @@ Desarrollo y soporte técnico: **Isaac Aracena**.
Esta versión ya no depende de `localStorage` para los proyectos. El tablero lee y guarda la información en Supabase usando las tablas: Esta versión ya no depende de `localStorage` para los proyectos. El tablero lee y guarda la información en Supabase usando las tablas:
- `projects` - `tablero_cdc_projects`
- `project_links` - `tablero_cdc_project_links`
- `profiles` - `tablero_cdc_profiles`
- `app_lists` - `tablero_cdc_app_lists`
Notas importantes: Notas importantes:
- Los proyectos abiertos se guardan en base de datos con `status = 'Activo'`, pero en la interfaz se muestran como proyectos sin estatus para mantener el comportamiento visual original. - Los proyectos abiertos se guardan en base de datos con `status = 'Activo'`, pero en la interfaz se muestran como proyectos sin estatus para mantener el comportamiento visual original.
- Los usuarios normales no ven ni actualizan el monto interno desde la app. - Los usuarios normales no ven ni actualizan el monto interno desde la app.
- Solo Gerardo Marrero puede modificar estatus, monto interno y eliminar proyectos desde la interfaz. - Solo Gerardo Marrero puede modificar estatus, monto interno y eliminar proyectos desde la interfaz.
- Los links de propuestas y artes finales se guardan en `project_links`. - Los links de propuestas y artes finales se guardan en `tablero_cdc_project_links`.
- Los desplegables se leen desde `app_lists`. Si una categoría todavía no existe en Supabase, la app usa una lista local de respaldo para no bloquear el formulario. - Los desplegables se leen desde `tablero_cdc_app_lists`. Si una categoría todavía no existe en Supabase, la app usa una lista local de respaldo para no bloquear el formulario.
## Supabase Realtime ## Supabase Realtime
Para que la sincronización multiusuario funcione, habilita Realtime para las tablas `projects`, `project_links` y `app_lists` ejecutando en Supabase SQL Editor el archivo: Para que la sincronización multiusuario funcione, habilita Realtime para las tablas `tablero_cdc_projects`, `tablero_cdc_project_links` y `tablero_cdc_app_lists` ejecutando en Supabase SQL Editor el archivo:
```text ```text
supabase_realtime_projects.sql supabase_realtime_projects.sql
@@ -199,7 +199,7 @@ Luego abre la app en dos pestañas o dos navegadores: al crear, editar o elimina
## Desplegables dinámicos ## Desplegables dinámicos
La app intenta cargar estos desplegables desde `public.app_lists`: La app intenta cargar estos desplegables desde `public.tablero_cdc_app_lists`:
- `client` / `cliente` / `clientes` - `client` / `cliente` / `clientes`
- `brand` / `marca` / `marcas` - `brand` / `marca` / `marcas`
@@ -207,4 +207,4 @@ La app intenta cargar estos desplegables desde `public.app_lists`:
- `status` / `estatus` - `status` / `estatus`
- `country_manager` / `cm` / `bu_cm` para mapear BU → Country Manager - `country_manager` / `cm` / `bu_cm` para mapear BU → Country Manager
Si una categoría aún no existe en Supabase, se usa el respaldo local del frontend. Más adelante n8n sincronizará la hoja `listas` del Sheet original hacia `app_lists`. Si una categoría aún no existe en Supabase, se usa el respaldo local del frontend. Más adelante n8n sincronizará la hoja `listas` del Sheet original hacia `tablero_cdc_app_lists`.
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -7,7 +7,7 @@
<meta name="description" content="Herramienta interna del Departamento de Diseño Creativo." /> <meta name="description" content="Herramienta interna del Departamento de Diseño Creativo." />
<meta name="author" content="CDC" /> <meta name="author" content="CDC" />
<link rel="icon" type="image/svg+xml" href="/tablero-cdc/favicon.svg" /> <link rel="icon" type="image/svg+xml" href="/tablero-cdc/favicon.svg" />
<script type="module" crossorigin src="/tablero-cdc/assets/index-BYKs5Exj.js"></script> <script type="module" crossorigin src="/tablero-cdc/assets/index-BEinrcZb.js"></script>
<link rel="stylesheet" crossorigin href="/tablero-cdc/assets/index-DjXLQf1G.css"> <link rel="stylesheet" crossorigin href="/tablero-cdc/assets/index-DjXLQf1G.css">
</head> </head>
<body> <body>
+1 -1
View File
@@ -108,7 +108,7 @@ export function ProjectDialog({ open, onOpenChange, project }: Props) {
return match?.[1] ?? ""; return match?.[1] ?? "";
}; };
// BU → Country Manager automático desde Supabase app_lists, con fallback local. // BU → Country Manager automático desde Supabase tablero_cdc_app_lists, con fallback local.
const onBU = (bu: string) => { const onBU = (bu: string) => {
const cleanBu = canonicalOptionLabel(bu); const cleanBu = canonicalOptionLabel(bu);
setForm((f) => ({ ...f, bu: cleanBu, cm: getCountryManager(cleanBu) })); setForm((f) => ({ ...f, bu: cleanBu, cm: getCountryManager(cleanBu) }));
+3 -3
View File
@@ -137,7 +137,7 @@ export async function loadAppLists() {
try { try {
const { data, error } = await supabase const { data, error } = await supabase
.from("app_lists") .from("tablero_cdc_app_lists")
.select("category, value, label, sort_order, is_active") .select("category, value, label, sort_order, is_active")
.eq("is_active", true) .eq("is_active", true)
.order("category", { ascending: true }) .order("category", { ascending: true })
@@ -180,12 +180,12 @@ function startAppListsRealtime() {
appListsRealtimeChannel = supabase appListsRealtimeChannel = supabase
.channel("tablero-cdc-app-lists") .channel("tablero-cdc-app-lists")
.on("postgres_changes", { event: "*", schema: "public", table: "app_lists" }, () => .on("postgres_changes", { event: "*", schema: "public", table: "tablero_cdc_app_lists" }, () =>
scheduleRealtimeRefresh(), scheduleRealtimeRefresh(),
) )
.subscribe((status) => { .subscribe((status) => {
if (status === "CHANNEL_ERROR" || status === "TIMED_OUT") { if (status === "CHANNEL_ERROR" || status === "TIMED_OUT") {
console.warn("Supabase Realtime no pudo suscribirse a app_lists:", status); console.warn("Supabase Realtime no pudo suscribirse a tablero_cdc_app_lists:", status);
} }
}); });
} }
+8 -8
View File
@@ -294,12 +294,12 @@ function startProjectsRealtime() {
.channel("tablero-cdc-projects") .channel("tablero-cdc-projects")
.on( .on(
"postgres_changes", "postgres_changes",
{ event: "*", schema: "public", table: "projects" }, { event: "*", schema: "public", table: "tablero_cdc_projects" },
() => scheduleRealtimeRefresh(), () => scheduleRealtimeRefresh(),
) )
.on( .on(
"postgres_changes", "postgres_changes",
{ event: "*", schema: "public", table: "project_links" }, { event: "*", schema: "public", table: "tablero_cdc_project_links" },
() => scheduleRealtimeRefresh(), () => scheduleRealtimeRefresh(),
) )
.subscribe((status) => { .subscribe((status) => {
@@ -323,7 +323,7 @@ function stopProjectsRealtime() {
async function replaceProjectLinks(projectId: string, project: Pick<Project, "propuestaLinks" | "afLinks">) { async function replaceProjectLinks(projectId: string, project: Pick<Project, "propuestaLinks" | "afLinks">) {
const { error: deleteError } = await supabase const { error: deleteError } = await supabase
.from("project_links") .from("tablero_cdc_project_links")
.delete() .delete()
.eq("project_id", projectId); .eq("project_id", projectId);
@@ -333,7 +333,7 @@ async function replaceProjectLinks(projectId: string, project: Pick<Project, "pr
if (linkRows.length === 0) return; if (linkRows.length === 0) return;
const { error: insertError } = await supabase.from("project_links").insert(linkRows); const { error: insertError } = await supabase.from("tablero_cdc_project_links").insert(linkRows);
if (insertError) throw insertError; if (insertError) throw insertError;
} }
@@ -359,7 +359,7 @@ async function loadProjects() {
brief_link, brief_link,
created_at, created_at,
extra_data, extra_data,
project_links ( project_links:tablero_cdc_project_links (
id, id,
link_type, link_type,
url, url,
@@ -368,7 +368,7 @@ async function loadProjects() {
`; `;
const { data, error } = await supabase const { data, error } = await supabase
.from("projects") .from("tablero_cdc_projects")
.select(selectColumns) .select(selectColumns)
.order("created_at", { ascending: false }); .order("created_at", { ascending: false });
@@ -399,7 +399,7 @@ async function addProject(project: Project) {
}; };
const { data, error } = await supabase const { data, error } = await supabase
.from("projects") .from("tablero_cdc_projects")
.insert(insertPayload) .insert(insertPayload)
.select("id") .select("id")
.single(); .single();
@@ -447,7 +447,7 @@ async function updateProject(id: string, patch: Partial<Project>) {
updated_by: userId, updated_by: userId,
}; };
const { error } = await supabase.from("projects").update(updatePayload).eq("id", id); const { error } = await supabase.from("tablero_cdc_projects").update(updatePayload).eq("id", id);
if (error) { if (error) {
setError(error.message); setError(error.message);
+6 -6
View File
@@ -11,9 +11,9 @@ begin
from pg_publication_tables from pg_publication_tables
where pubname = 'supabase_realtime' where pubname = 'supabase_realtime'
and schemaname = 'public' and schemaname = 'public'
and tablename = 'projects' and tablename = 'tablero_cdc_projects'
) then ) then
alter publication supabase_realtime add table public.projects; alter publication supabase_realtime add table public.tablero_cdc_projects;
end if; end if;
if not exists ( if not exists (
@@ -21,9 +21,9 @@ begin
from pg_publication_tables from pg_publication_tables
where pubname = 'supabase_realtime' where pubname = 'supabase_realtime'
and schemaname = 'public' and schemaname = 'public'
and tablename = 'project_links' and tablename = 'tablero_cdc_project_links'
) then ) then
alter publication supabase_realtime add table public.project_links; alter publication supabase_realtime add table public.tablero_cdc_project_links;
end if; end if;
if not exists ( if not exists (
@@ -31,8 +31,8 @@ begin
from pg_publication_tables from pg_publication_tables
where pubname = 'supabase_realtime' where pubname = 'supabase_realtime'
and schemaname = 'public' and schemaname = 'public'
and tablename = 'app_lists' and tablename = 'tablero_cdc_app_lists'
) then ) then
alter publication supabase_realtime add table public.app_lists; alter publication supabase_realtime add table public.tablero_cdc_app_lists;
end if; end if;
end $$; end $$;