Causa del 403: Supabase evalúa siempre la política INSERT cuando se usa .upsert(), incluso si la fila ya existe. client_editor no tiene INSERT en processes, entonces cualquier .upsert() sobre procesos existentes fallaba con 403.
Some checks failed
/ Deploy to Cloudflare Pages (push) Has been cancelled

Fix: nuevo método updateEditable() en process-repo.ts que usa .update().eq('id', process.id) con solo los campos editables (sin bpmn_xml, owner_id, created_by, id). Todos los paths de edición en process-store.ts y library-store.ts ahora usan updateEditable(). El .upsert() original queda únicamente para la creación inicial desde ImportPage y setCurrentProcess — rutas que client_editor nunca puede alcanzar (el import está bloqueado por el guard de rol).
This commit is contained in:
2026-07-07 13:25:43 -03:00
parent 9b89cb8669
commit cad8fbca4f
3 changed files with 29 additions and 7 deletions

View File

@@ -72,6 +72,28 @@ export const supabaseProcessRepo = {
if (error) throw error if (error) throw error
}, },
// Actualiza solo campos editables por el usuario (sin bpmn_xml, owner_id, created_by).
// Usa UPDATE en lugar de upsert para evitar el chequeo de INSERT policy (que client_editor no tiene).
async updateEditable(process: Process, userId: string): Promise<void> {
const { error } = await supabase
.from('processes')
.update({
name: process.name,
client: process.clientName,
currency: process.currency,
overhead_percentage: process.overheadPercentage,
annual_frequency: process.annualFrequency,
analysis_horizon_years: process.analysisHorizonYears,
automation_investment: process.automationInvestment,
tags: process.tags,
group_id: process.groupId,
updated_by: userId,
updated_at: new Date().toISOString(),
})
.eq('id', process.id)
if (error) throw error
},
async getById(id: string): Promise<Process | undefined> { async getById(id: string): Promise<Process | undefined> {
const { data, error } = await supabase const { data, error } = await supabase
.from('processes') .from('processes')

View File

@@ -85,7 +85,7 @@ export const useLibraryStore = create<LibraryState>((set, get) => ({
const process = get().processes.find((p) => p.id === processId) const process = get().processes.find((p) => p.id === processId)
if (!process) return if (!process) return
const updated = { ...process, groupId, updatedAt: Date.now() } const updated = { ...process, groupId, updatedAt: Date.now() }
await supabaseProcessRepo.save(updated, userId) await supabaseProcessRepo.updateEditable(updated, userId)
set((state) => ({ set((state) => ({
processes: state.processes.map((p) => p.id === processId ? updated : p), processes: state.processes.map((p) => p.id === processId ? updated : p),
})) }))

View File

@@ -62,7 +62,7 @@ export const useProcessStore = create<ProcessState>((set, get) => ({
const current = get().currentProcess const current = get().currentProcess
if (!current) return if (!current) return
const updated: Process = { ...current, ...updates, updatedAt: Date.now() } const updated: Process = { ...current, ...updates, updatedAt: Date.now() }
await supabaseProcessRepo.save(updated, userId) await supabaseProcessRepo.updateEditable(updated, userId)
set({ currentProcess: updated }) set({ currentProcess: updated })
}, },
@@ -71,7 +71,7 @@ export const useProcessStore = create<ProcessState>((set, get) => ({
const current = get().currentProcess const current = get().currentProcess
if (current) { if (current) {
const updatedProcess = { ...current, updatedAt: Date.now() } const updatedProcess = { ...current, updatedAt: Date.now() }
await supabaseProcessRepo.save(updatedProcess, userId) await supabaseProcessRepo.updateEditable(updatedProcess, userId)
set((state) => ({ set((state) => ({
activities: state.activities.map((a) => (a.id === activity.id ? activity : a)), activities: state.activities.map((a) => (a.id === activity.id ? activity : a)),
currentProcess: updatedProcess, currentProcess: updatedProcess,
@@ -88,7 +88,7 @@ export const useProcessStore = create<ProcessState>((set, get) => ({
const current = get().currentProcess const current = get().currentProcess
if (current) { if (current) {
const updatedProcess = { ...current, updatedAt: Date.now() } const updatedProcess = { ...current, updatedAt: Date.now() }
await supabaseProcessRepo.save(updatedProcess, userId) await supabaseProcessRepo.updateEditable(updatedProcess, userId)
set((state) => ({ set((state) => ({
gateways: state.gateways.map((g) => (g.id === gateway.id ? gateway : g)), gateways: state.gateways.map((g) => (g.id === gateway.id ? gateway : g)),
currentProcess: updatedProcess, currentProcess: updatedProcess,
@@ -105,7 +105,7 @@ export const useProcessStore = create<ProcessState>((set, get) => ({
const current = get().currentProcess const current = get().currentProcess
if (current) { if (current) {
const updatedProcess = { ...current, updatedAt: Date.now() } const updatedProcess = { ...current, updatedAt: Date.now() }
await supabaseProcessRepo.save(updatedProcess, userId) await supabaseProcessRepo.updateEditable(updatedProcess, userId)
set((state) => ({ resources: [...state.resources, resource], currentProcess: updatedProcess })) set((state) => ({ resources: [...state.resources, resource], currentProcess: updatedProcess }))
} else { } else {
set((state) => ({ resources: [...state.resources, resource] })) set((state) => ({ resources: [...state.resources, resource] }))
@@ -117,7 +117,7 @@ export const useProcessStore = create<ProcessState>((set, get) => ({
const current = get().currentProcess const current = get().currentProcess
if (current) { if (current) {
const updatedProcess = { ...current, updatedAt: Date.now() } const updatedProcess = { ...current, updatedAt: Date.now() }
await supabaseProcessRepo.save(updatedProcess, userId) await supabaseProcessRepo.updateEditable(updatedProcess, userId)
set((state) => ({ set((state) => ({
resources: state.resources.map((r) => (r.id === resource.id ? resource : r)), resources: state.resources.map((r) => (r.id === resource.id ? resource : r)),
currentProcess: updatedProcess, currentProcess: updatedProcess,
@@ -134,7 +134,7 @@ export const useProcessStore = create<ProcessState>((set, get) => ({
const current = get().currentProcess const current = get().currentProcess
if (current) { if (current) {
const updatedProcess = { ...current, updatedAt: Date.now() } const updatedProcess = { ...current, updatedAt: Date.now() }
await supabaseProcessRepo.save(updatedProcess, userId) await supabaseProcessRepo.updateEditable(updatedProcess, userId)
set((state) => ({ set((state) => ({
resources: state.resources.filter((r) => r.id !== resourceId), resources: state.resources.filter((r) => r.id !== resourceId),
currentProcess: updatedProcess, currentProcess: updatedProcess,