cesjavi commited on
Commit
6faae91
·
1 Parent(s): 913c92b

Fix: Final column naming and relationship corrections (Phase 8 Governance)

Browse files
database/FINAL_SUPABASE_FIX.sql ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -- FINAL GOVERNANCE & RELATIONSHIP FIX (Phase 8)
2
+ -- RUN THIS IN SUPABASE SQL EDITOR TO RESOLVE 400 BAD REQUEST ERRORS
3
+
4
+ -- 1. CLEANUP OLD CONSTRAINTS
5
+ ALTER TABLE IF EXISTS public.team_members DROP CONSTRAINT IF EXISTS team_members_user_id_fkey;
6
+ ALTER TABLE IF EXISTS public.projects DROP CONSTRAINT IF EXISTS projects_owner_id_fkey;
7
+ ALTER TABLE IF EXISTS public.agents DROP CONSTRAINT IF EXISTS agents_user_id_fkey;
8
+ ALTER TABLE IF EXISTS public.audit_logs DROP CONSTRAINT IF EXISTS audit_logs_actor_id_fkey;
9
+ ALTER TABLE IF EXISTS public.agent_templates DROP CONSTRAINT IF EXISTS agent_templates_author_id_fkey;
10
+
11
+ -- 2. CREATE NEW ROBUST RELATIONSHIPS POINTING TO PUBLIC.PROFILES
12
+ -- This is critical for PostgREST join discovery.
13
+ ALTER TABLE public.team_members
14
+ ADD CONSTRAINT team_members_user_id_fkey
15
+ FOREIGN KEY (user_id) REFERENCES public.profiles(id) ON DELETE CASCADE;
16
+
17
+ ALTER TABLE public.projects
18
+ ADD CONSTRAINT projects_owner_id_fkey
19
+ FOREIGN KEY (owner_id) REFERENCES public.profiles(id) ON DELETE SET NULL;
20
+
21
+ ALTER TABLE public.agents
22
+ ADD CONSTRAINT agents_user_id_fkey
23
+ FOREIGN KEY (user_id) REFERENCES public.profiles(id) ON DELETE CASCADE;
24
+
25
+ ALTER TABLE public.audit_logs
26
+ ADD CONSTRAINT audit_logs_user_id_fkey
27
+ FOREIGN KEY (user_id) REFERENCES public.profiles(id) ON DELETE SET NULL;
28
+
29
+ ALTER TABLE public.agent_templates
30
+ ADD CONSTRAINT agent_templates_author_id_fkey
31
+ FOREIGN KEY (author_id) REFERENCES public.profiles(id) ON DELETE SET NULL;
32
+
33
+ -- 3. ENSURE GRANTS
34
+ GRANT SELECT ON ALL TABLES IN SCHEMA public TO authenticated;
35
+ GRANT USAGE ON SCHEMA public TO authenticated;
36
+
37
+ -- 4. RELOAD POSTGREST SCHEMA CACHE
38
+ NOTIFY pgrst, 'reload schema';
39
+
40
+ -- 5. VERIFICATION COMMENT (For PostgREST hinting)
41
+ COMMENT ON CONSTRAINT team_members_user_id_fkey ON public.team_members IS 'Relationship to profiles table for joins';
frontend/src/components/AuditView.tsx CHANGED
@@ -18,7 +18,7 @@ import { supabase } from '../services/supabase';
18
  interface AuditLog {
19
  id: string;
20
  created_at: string;
21
- actor_id: string | null;
22
  action: string;
23
  agent_id: string | null;
24
  task_id: string | null;
@@ -55,9 +55,9 @@ const AuditView: React.FC = () => {
55
  .from('audit_logs')
56
  .select(`
57
  *,
58
- profiles(full_name, email),
59
- agents(name),
60
- tasks(title)
61
  `)
62
  .order('created_at', { ascending: false })
63
  .range(page * pageSize, (page + 1) * pageSize - 1);
@@ -76,9 +76,9 @@ const AuditView: React.FC = () => {
76
  const rows = logs.map(log => [
77
  log.created_at,
78
  log.action,
79
- log.profiles?.email || 'System',
80
- log.agents?.name || 'N/A',
81
- log.tasks?.title || 'N/A',
82
  JSON.stringify(log.metadata)
83
  ]);
84
 
@@ -93,8 +93,8 @@ const AuditView: React.FC = () => {
93
 
94
  const filteredLogs = logs.filter(log =>
95
  log.action.toLowerCase().includes(searchTerm.toLowerCase()) ||
96
- (log.profiles?.email || '').toLowerCase().includes(searchTerm.toLowerCase()) ||
97
- (log.agents?.name || '').toLowerCase().includes(searchTerm.toLowerCase())
98
  );
99
 
100
  const formatTimestamp = (ts: string) => {
@@ -191,21 +191,21 @@ const AuditView: React.FC = () => {
191
  <td style={{ padding: 'var(--space-md)', fontSize: '0.9rem' }}>
192
  <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
193
  <User size={14} style={{ opacity: 0.5 }} />
194
- {log.profiles?.email || <span style={{ color: 'var(--text-dim)', fontSize: '0.8rem' }}>System</span>}
195
  </div>
196
  </td>
197
  <td style={{ padding: 'var(--space-md)', fontSize: '0.9rem' }}>
198
  <div style={{ display: 'flex', flexDirection: 'column', gap: '4px' }}>
199
- {log.agent_id && log.agents && (
200
  <div style={{ display: 'flex', alignItems: 'center', gap: '4px', color: 'var(--accent)', fontSize: '0.8rem' }}>
201
  <Bot size={12} />
202
- {log.agents.name}
203
  </div>
204
  )}
205
- {log.task_id && log.tasks && (
206
  <div style={{ display: 'flex', alignItems: 'center', gap: '4px', color: 'var(--text-dim)', fontSize: '0.8rem' }}>
207
  <FileText size={12} />
208
- {log.tasks.title}
209
  </div>
210
  )}
211
  {!log.agent_id && !log.task_id && <span style={{ color: 'var(--text-dim)', fontSize: '0.8rem' }}>-</span>}
 
18
  interface AuditLog {
19
  id: string;
20
  created_at: string;
21
+ user_id: string | null;
22
  action: string;
23
  agent_id: string | null;
24
  task_id: string | null;
 
55
  .from('audit_logs')
56
  .select(`
57
  *,
58
+ profiles!user_id(full_name, email),
59
+ agents!agent_id(name),
60
+ tasks!task_id(title)
61
  `)
62
  .order('created_at', { ascending: false })
63
  .range(page * pageSize, (page + 1) * pageSize - 1);
 
76
  const rows = logs.map(log => [
77
  log.created_at,
78
  log.action,
79
+ (log as any).profiles?.email || 'System',
80
+ (log as any).agents?.name || 'N/A',
81
+ (log as any).tasks?.title || 'N/A',
82
  JSON.stringify(log.metadata)
83
  ]);
84
 
 
93
 
94
  const filteredLogs = logs.filter(log =>
95
  log.action.toLowerCase().includes(searchTerm.toLowerCase()) ||
96
+ ((log as any).profiles?.email || '').toLowerCase().includes(searchTerm.toLowerCase()) ||
97
+ ((log as any).agents?.name || '').toLowerCase().includes(searchTerm.toLowerCase())
98
  );
99
 
100
  const formatTimestamp = (ts: string) => {
 
191
  <td style={{ padding: 'var(--space-md)', fontSize: '0.9rem' }}>
192
  <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
193
  <User size={14} style={{ opacity: 0.5 }} />
194
+ {(log as any).profiles?.email || <span style={{ color: 'var(--text-dim)', fontSize: '0.8rem' }}>System</span>}
195
  </div>
196
  </td>
197
  <td style={{ padding: 'var(--space-md)', fontSize: '0.9rem' }}>
198
  <div style={{ display: 'flex', flexDirection: 'column', gap: '4px' }}>
199
+ {log.agent_id && (log as any).agents && (
200
  <div style={{ display: 'flex', alignItems: 'center', gap: '4px', color: 'var(--accent)', fontSize: '0.8rem' }}>
201
  <Bot size={12} />
202
+ {(log as any).agents.name}
203
  </div>
204
  )}
205
+ {log.task_id && (log as any).tasks && (
206
  <div style={{ display: 'flex', alignItems: 'center', gap: '4px', color: 'var(--text-dim)', fontSize: '0.8rem' }}>
207
  <FileText size={12} />
208
+ {(log as any).tasks.title}
209
  </div>
210
  )}
211
  {!log.agent_id && !log.task_id && <span style={{ color: 'var(--text-dim)', fontSize: '0.8rem' }}>-</span>}