fix(workspace): obtener orgName via JOIN en getById, eliminar fetch separado con race condition
Some checks failed
/ Deploy to Cloudflare Pages (push) Has been cancelled

This commit is contained in:
2026-07-07 15:26:52 -03:00
parent 6fee592e40
commit df5fb55696
3 changed files with 11 additions and 16 deletions

View File

@@ -21,6 +21,7 @@ export interface Process {
ownerId: string // 🆕 Sprint 4 — owner del proceso (auth.uid() al crear)
updatedBy: string // 🆕 Sprint 4 — UUID del usuario que hizo el último update
orgId: string | null // 🆕 Sprint 7 — organización dueña del proceso (null = proceso interno InQ)
orgName?: string | null // 🆕 Sprint 7 — nombre de la org (poblado por getById via JOIN, no se persiste)
}
export type ActivityType = 'task' | 'subprocess'

View File

@@ -22,7 +22,6 @@ import { useLibraryStore } from '@/store/library-store'
import { useAuth } from '@/auth/AuthContext'
import { AppHeader } from '@/components/AppHeader'
import { ErrorBoundary } from '@/components/ErrorBoundary'
import { supabase } from '@/lib/supabase'
type SelectedCategory = 'activity' | 'gateway' | null
@@ -68,18 +67,7 @@ export function WorkspacePage() {
}
}, [user, processId, navigate])
// Nombre de la organización dueña del proceso (para el back button contextual).
// undefined = todavía cargando, null = cargado sin resultado, string = nombre real.
const [orgName, setOrgName] = useState<string | null | undefined>(undefined)
useEffect(() => {
if (!currentProcess?.orgId) { setOrgName(null); return }
supabase
.from('organizations')
.select('name')
.eq('id', currentProcess.orgId)
.maybeSingle()
.then(({ data }) => setOrgName(data?.name ?? null))
}, [currentProcess?.orgId])
// orgName viene directamente del proceso cargado via JOIN en getById (sin fetch separado)
// Validación XOR: todos los gateways exclusivos deben sumar 1.0
const xorValidation = useMemo(() => {
@@ -198,10 +186,12 @@ export function WorkspacePage() {
}
// client_viewer ya fue redirigido antes de este punto; solo verificamos client_editor aquí
// eslint-disable-next-line no-console
console.log('[WorkspacePage] currentProcess:', { id: currentProcess.id, orgId: currentProcess.orgId })
const isClientRole = user?.platformRole === 'client_editor'
const backLabel = isClientRole
? 'Procesos'
: orgName ?? 'Biblioteca'
: currentProcess.orgName ?? 'Biblioteca'
function handleBack() {
const orgId = currentProcess?.orgId

View File

@@ -23,6 +23,8 @@ function toRow(process: Process, userId: string) {
}
function fromRow(row: Record<string, unknown>): Process {
// org puede estar presente si el query hizo JOIN con organizations (getById lo incluye)
const org = row.org as { name: string } | null
return {
id: row.id as string,
name: row.name as string,
@@ -40,6 +42,7 @@ function fromRow(row: Record<string, unknown>): Process {
ownerId: (row.owner_id as string) ?? '',
updatedBy: (row.updated_by as string) ?? '',
orgId: (row.org_id as string | null) ?? null,
orgName: org?.name ?? null,
}
}
@@ -96,13 +99,14 @@ export const supabaseProcessRepo = {
},
async getById(id: string): Promise<Process | undefined> {
// JOIN con organizations para obtener orgName en una sola query (evita fetch separado y race conditions)
const { data, error } = await supabase
.from('processes')
.select('*')
.select('*, org:organizations!org_id(name)')
.eq('id', id)
.single()
if (error) return undefined
return fromRow(data)
return fromRow(data as Record<string, unknown>)
},
// JOIN con users para resolver owner/updater en una sola query (evita N+1).