mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-24 12:11:12 -05:00
Fix RLS policy for JSONB migration
This commit is contained in:
@@ -59,6 +59,38 @@ export type Database = {
|
||||
}
|
||||
Relationships: []
|
||||
}
|
||||
admin_audit_details: {
|
||||
Row: {
|
||||
audit_log_id: string
|
||||
created_at: string | null
|
||||
detail_key: string
|
||||
detail_value: string
|
||||
id: string
|
||||
}
|
||||
Insert: {
|
||||
audit_log_id: string
|
||||
created_at?: string | null
|
||||
detail_key: string
|
||||
detail_value: string
|
||||
id?: string
|
||||
}
|
||||
Update: {
|
||||
audit_log_id?: string
|
||||
created_at?: string | null
|
||||
detail_key?: string
|
||||
detail_value?: string
|
||||
id?: string
|
||||
}
|
||||
Relationships: [
|
||||
{
|
||||
foreignKeyName: "admin_audit_details_audit_log_id_fkey"
|
||||
columns: ["audit_log_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "admin_audit_log"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
]
|
||||
}
|
||||
admin_audit_log: {
|
||||
Row: {
|
||||
action: string
|
||||
@@ -464,6 +496,44 @@ export type Database = {
|
||||
},
|
||||
]
|
||||
}
|
||||
conflict_detail_fields: {
|
||||
Row: {
|
||||
conflict_resolution_id: string
|
||||
conflicting_value_1: string | null
|
||||
conflicting_value_2: string | null
|
||||
created_at: string | null
|
||||
field_name: string
|
||||
id: string
|
||||
resolved_value: string | null
|
||||
}
|
||||
Insert: {
|
||||
conflict_resolution_id: string
|
||||
conflicting_value_1?: string | null
|
||||
conflicting_value_2?: string | null
|
||||
created_at?: string | null
|
||||
field_name: string
|
||||
id?: string
|
||||
resolved_value?: string | null
|
||||
}
|
||||
Update: {
|
||||
conflict_resolution_id?: string
|
||||
conflicting_value_1?: string | null
|
||||
conflicting_value_2?: string | null
|
||||
created_at?: string | null
|
||||
field_name?: string
|
||||
id?: string
|
||||
resolved_value?: string | null
|
||||
}
|
||||
Relationships: [
|
||||
{
|
||||
foreignKeyName: "conflict_detail_fields_conflict_resolution_id_fkey"
|
||||
columns: ["conflict_resolution_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "conflict_resolutions"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
]
|
||||
}
|
||||
conflict_resolutions: {
|
||||
Row: {
|
||||
conflict_details: Json | null
|
||||
@@ -511,49 +581,64 @@ export type Database = {
|
||||
}
|
||||
contact_email_threads: {
|
||||
Row: {
|
||||
attachment_count: number | null
|
||||
body_html: string | null
|
||||
body_text: string
|
||||
created_at: string
|
||||
direction: string
|
||||
email_provider: string | null
|
||||
from_email: string
|
||||
id: string
|
||||
in_reply_to: string | null
|
||||
is_auto_reply: boolean | null
|
||||
message_id: string
|
||||
metadata: Json | null
|
||||
reference_chain: string[] | null
|
||||
sent_by: string | null
|
||||
smtp_message_id: string | null
|
||||
spam_score: number | null
|
||||
subject: string
|
||||
submission_id: string
|
||||
to_email: string
|
||||
}
|
||||
Insert: {
|
||||
attachment_count?: number | null
|
||||
body_html?: string | null
|
||||
body_text: string
|
||||
created_at?: string
|
||||
direction: string
|
||||
email_provider?: string | null
|
||||
from_email: string
|
||||
id?: string
|
||||
in_reply_to?: string | null
|
||||
is_auto_reply?: boolean | null
|
||||
message_id: string
|
||||
metadata?: Json | null
|
||||
reference_chain?: string[] | null
|
||||
sent_by?: string | null
|
||||
smtp_message_id?: string | null
|
||||
spam_score?: number | null
|
||||
subject: string
|
||||
submission_id: string
|
||||
to_email: string
|
||||
}
|
||||
Update: {
|
||||
attachment_count?: number | null
|
||||
body_html?: string | null
|
||||
body_text?: string
|
||||
created_at?: string
|
||||
direction?: string
|
||||
email_provider?: string | null
|
||||
from_email?: string
|
||||
id?: string
|
||||
in_reply_to?: string | null
|
||||
is_auto_reply?: boolean | null
|
||||
message_id?: string
|
||||
metadata?: Json | null
|
||||
reference_chain?: string[] | null
|
||||
sent_by?: string | null
|
||||
smtp_message_id?: string | null
|
||||
spam_score?: number | null
|
||||
subject?: string
|
||||
submission_id?: string
|
||||
to_email?: string
|
||||
@@ -1049,49 +1134,97 @@ export type Database = {
|
||||
}
|
||||
historical_parks: {
|
||||
Row: {
|
||||
banner_image_id: string | null
|
||||
banner_image_url: string | null
|
||||
card_image_id: string | null
|
||||
card_image_url: string | null
|
||||
closing_date: string | null
|
||||
closing_date_precision: string | null
|
||||
closure_reason: string | null
|
||||
created_at: string
|
||||
description: string | null
|
||||
email: string | null
|
||||
final_state_data: Json
|
||||
id: string
|
||||
location_id: string | null
|
||||
name: string
|
||||
opening_date: string | null
|
||||
opening_date_precision: string | null
|
||||
operated_from: string | null
|
||||
operated_from_precision: string | null
|
||||
operated_until: string | null
|
||||
operated_until_precision: string | null
|
||||
operator_id: string | null
|
||||
original_park_id: string | null
|
||||
park_type: string | null
|
||||
phone: string | null
|
||||
property_owner_id: string | null
|
||||
slug: string
|
||||
status: string | null
|
||||
successor_park_id: string | null
|
||||
website_url: string | null
|
||||
}
|
||||
Insert: {
|
||||
banner_image_id?: string | null
|
||||
banner_image_url?: string | null
|
||||
card_image_id?: string | null
|
||||
card_image_url?: string | null
|
||||
closing_date?: string | null
|
||||
closing_date_precision?: string | null
|
||||
closure_reason?: string | null
|
||||
created_at?: string
|
||||
description?: string | null
|
||||
email?: string | null
|
||||
final_state_data: Json
|
||||
id?: string
|
||||
location_id?: string | null
|
||||
name: string
|
||||
opening_date?: string | null
|
||||
opening_date_precision?: string | null
|
||||
operated_from?: string | null
|
||||
operated_from_precision?: string | null
|
||||
operated_until?: string | null
|
||||
operated_until_precision?: string | null
|
||||
operator_id?: string | null
|
||||
original_park_id?: string | null
|
||||
park_type?: string | null
|
||||
phone?: string | null
|
||||
property_owner_id?: string | null
|
||||
slug: string
|
||||
status?: string | null
|
||||
successor_park_id?: string | null
|
||||
website_url?: string | null
|
||||
}
|
||||
Update: {
|
||||
banner_image_id?: string | null
|
||||
banner_image_url?: string | null
|
||||
card_image_id?: string | null
|
||||
card_image_url?: string | null
|
||||
closing_date?: string | null
|
||||
closing_date_precision?: string | null
|
||||
closure_reason?: string | null
|
||||
created_at?: string
|
||||
description?: string | null
|
||||
email?: string | null
|
||||
final_state_data?: Json
|
||||
id?: string
|
||||
location_id?: string | null
|
||||
name?: string
|
||||
opening_date?: string | null
|
||||
opening_date_precision?: string | null
|
||||
operated_from?: string | null
|
||||
operated_from_precision?: string | null
|
||||
operated_until?: string | null
|
||||
operated_until_precision?: string | null
|
||||
operator_id?: string | null
|
||||
original_park_id?: string | null
|
||||
park_type?: string | null
|
||||
phone?: string | null
|
||||
property_owner_id?: string | null
|
||||
slug?: string
|
||||
status?: string | null
|
||||
successor_park_id?: string | null
|
||||
website_url?: string | null
|
||||
}
|
||||
Relationships: [
|
||||
{
|
||||
@@ -1101,6 +1234,13 @@ export type Database = {
|
||||
referencedRelation: "locations"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "historical_parks_operator_id_fkey"
|
||||
columns: ["operator_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "companies"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "historical_parks_original_park_id_fkey"
|
||||
columns: ["original_park_id"]
|
||||
@@ -1108,6 +1248,13 @@ export type Database = {
|
||||
referencedRelation: "parks"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "historical_parks_property_owner_id_fkey"
|
||||
columns: ["property_owner_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "companies"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "historical_parks_successor_park_id_fkey"
|
||||
columns: ["successor_park_id"]
|
||||
@@ -1119,10 +1266,30 @@ export type Database = {
|
||||
}
|
||||
historical_rides: {
|
||||
Row: {
|
||||
banner_image_id: string | null
|
||||
banner_image_url: string | null
|
||||
card_image_id: string | null
|
||||
card_image_url: string | null
|
||||
category: string | null
|
||||
closing_date: string | null
|
||||
closing_date_precision: string | null
|
||||
coaster_type: string | null
|
||||
created_at: string
|
||||
description: string | null
|
||||
designer_id: string | null
|
||||
drop_height_meters: number | null
|
||||
final_state_data: Json
|
||||
id: string
|
||||
intensity_level: string | null
|
||||
inversions: number | null
|
||||
length_meters: number | null
|
||||
manufacturer_id: string | null
|
||||
max_g_force: number | null
|
||||
max_height_meters: number | null
|
||||
max_speed_kmh: number | null
|
||||
name: string
|
||||
opening_date: string | null
|
||||
opening_date_precision: string | null
|
||||
operated_from: string | null
|
||||
operated_from_precision: string | null
|
||||
operated_until: string | null
|
||||
@@ -1131,14 +1298,37 @@ export type Database = {
|
||||
park_id: string | null
|
||||
relocated_to_park_id: string | null
|
||||
removal_reason: string | null
|
||||
ride_model_id: string | null
|
||||
seating_type: string | null
|
||||
slug: string
|
||||
status: string | null
|
||||
successor_ride_id: string | null
|
||||
}
|
||||
Insert: {
|
||||
banner_image_id?: string | null
|
||||
banner_image_url?: string | null
|
||||
card_image_id?: string | null
|
||||
card_image_url?: string | null
|
||||
category?: string | null
|
||||
closing_date?: string | null
|
||||
closing_date_precision?: string | null
|
||||
coaster_type?: string | null
|
||||
created_at?: string
|
||||
description?: string | null
|
||||
designer_id?: string | null
|
||||
drop_height_meters?: number | null
|
||||
final_state_data: Json
|
||||
id?: string
|
||||
intensity_level?: string | null
|
||||
inversions?: number | null
|
||||
length_meters?: number | null
|
||||
manufacturer_id?: string | null
|
||||
max_g_force?: number | null
|
||||
max_height_meters?: number | null
|
||||
max_speed_kmh?: number | null
|
||||
name: string
|
||||
opening_date?: string | null
|
||||
opening_date_precision?: string | null
|
||||
operated_from?: string | null
|
||||
operated_from_precision?: string | null
|
||||
operated_until?: string | null
|
||||
@@ -1147,14 +1337,37 @@ export type Database = {
|
||||
park_id?: string | null
|
||||
relocated_to_park_id?: string | null
|
||||
removal_reason?: string | null
|
||||
ride_model_id?: string | null
|
||||
seating_type?: string | null
|
||||
slug: string
|
||||
status?: string | null
|
||||
successor_ride_id?: string | null
|
||||
}
|
||||
Update: {
|
||||
banner_image_id?: string | null
|
||||
banner_image_url?: string | null
|
||||
card_image_id?: string | null
|
||||
card_image_url?: string | null
|
||||
category?: string | null
|
||||
closing_date?: string | null
|
||||
closing_date_precision?: string | null
|
||||
coaster_type?: string | null
|
||||
created_at?: string
|
||||
description?: string | null
|
||||
designer_id?: string | null
|
||||
drop_height_meters?: number | null
|
||||
final_state_data?: Json
|
||||
id?: string
|
||||
intensity_level?: string | null
|
||||
inversions?: number | null
|
||||
length_meters?: number | null
|
||||
manufacturer_id?: string | null
|
||||
max_g_force?: number | null
|
||||
max_height_meters?: number | null
|
||||
max_speed_kmh?: number | null
|
||||
name?: string
|
||||
opening_date?: string | null
|
||||
opening_date_precision?: string | null
|
||||
operated_from?: string | null
|
||||
operated_from_precision?: string | null
|
||||
operated_until?: string | null
|
||||
@@ -1163,10 +1376,27 @@ export type Database = {
|
||||
park_id?: string | null
|
||||
relocated_to_park_id?: string | null
|
||||
removal_reason?: string | null
|
||||
ride_model_id?: string | null
|
||||
seating_type?: string | null
|
||||
slug?: string
|
||||
status?: string | null
|
||||
successor_ride_id?: string | null
|
||||
}
|
||||
Relationships: [
|
||||
{
|
||||
foreignKeyName: "historical_rides_designer_id_fkey"
|
||||
columns: ["designer_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "companies"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "historical_rides_manufacturer_id_fkey"
|
||||
columns: ["manufacturer_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "companies"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "historical_rides_original_ride_id_fkey"
|
||||
columns: ["original_ride_id"]
|
||||
@@ -1188,6 +1418,13 @@ export type Database = {
|
||||
referencedRelation: "parks"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "historical_rides_ride_model_id_fkey"
|
||||
columns: ["ride_model_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "ride_models"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "historical_rides_successor_ride_id_fkey"
|
||||
columns: ["successor_ride_id"]
|
||||
@@ -1197,6 +1434,41 @@ export type Database = {
|
||||
},
|
||||
]
|
||||
}
|
||||
item_change_fields: {
|
||||
Row: {
|
||||
created_at: string | null
|
||||
edit_history_id: string
|
||||
field_name: string
|
||||
id: string
|
||||
new_value: string | null
|
||||
old_value: string | null
|
||||
}
|
||||
Insert: {
|
||||
created_at?: string | null
|
||||
edit_history_id: string
|
||||
field_name: string
|
||||
id?: string
|
||||
new_value?: string | null
|
||||
old_value?: string | null
|
||||
}
|
||||
Update: {
|
||||
created_at?: string | null
|
||||
edit_history_id?: string
|
||||
field_name?: string
|
||||
id?: string
|
||||
new_value?: string | null
|
||||
old_value?: string | null
|
||||
}
|
||||
Relationships: [
|
||||
{
|
||||
foreignKeyName: "item_change_fields_edit_history_id_fkey"
|
||||
columns: ["edit_history_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "item_edit_history"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
]
|
||||
}
|
||||
item_edit_history: {
|
||||
Row: {
|
||||
changes: Json
|
||||
@@ -1363,6 +1635,38 @@ export type Database = {
|
||||
},
|
||||
]
|
||||
}
|
||||
moderation_audit_metadata: {
|
||||
Row: {
|
||||
audit_log_id: string
|
||||
created_at: string | null
|
||||
id: string
|
||||
metadata_key: string
|
||||
metadata_value: string
|
||||
}
|
||||
Insert: {
|
||||
audit_log_id: string
|
||||
created_at?: string | null
|
||||
id?: string
|
||||
metadata_key: string
|
||||
metadata_value: string
|
||||
}
|
||||
Update: {
|
||||
audit_log_id?: string
|
||||
created_at?: string | null
|
||||
id?: string
|
||||
metadata_key?: string
|
||||
metadata_value?: string
|
||||
}
|
||||
Relationships: [
|
||||
{
|
||||
foreignKeyName: "moderation_audit_metadata_audit_log_id_fkey"
|
||||
columns: ["audit_log_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "moderation_audit_log"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
]
|
||||
}
|
||||
notification_channels: {
|
||||
Row: {
|
||||
channel_type: string
|
||||
@@ -1423,6 +1727,38 @@ export type Database = {
|
||||
}
|
||||
Relationships: []
|
||||
}
|
||||
notification_event_data: {
|
||||
Row: {
|
||||
created_at: string | null
|
||||
event_key: string
|
||||
event_value: string
|
||||
id: string
|
||||
notification_log_id: string
|
||||
}
|
||||
Insert: {
|
||||
created_at?: string | null
|
||||
event_key: string
|
||||
event_value: string
|
||||
id?: string
|
||||
notification_log_id: string
|
||||
}
|
||||
Update: {
|
||||
created_at?: string | null
|
||||
event_key?: string
|
||||
event_value?: string
|
||||
id?: string
|
||||
notification_log_id?: string
|
||||
}
|
||||
Relationships: [
|
||||
{
|
||||
foreignKeyName: "notification_event_data_notification_log_id_fkey"
|
||||
columns: ["notification_log_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "notification_logs"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
]
|
||||
}
|
||||
notification_logs: {
|
||||
Row: {
|
||||
channel: string
|
||||
@@ -2188,6 +2524,41 @@ export type Database = {
|
||||
}
|
||||
Relationships: []
|
||||
}
|
||||
profile_change_fields: {
|
||||
Row: {
|
||||
audit_log_id: string
|
||||
created_at: string | null
|
||||
field_name: string
|
||||
id: string
|
||||
new_value: string | null
|
||||
old_value: string | null
|
||||
}
|
||||
Insert: {
|
||||
audit_log_id: string
|
||||
created_at?: string | null
|
||||
field_name: string
|
||||
id?: string
|
||||
new_value?: string | null
|
||||
old_value?: string | null
|
||||
}
|
||||
Update: {
|
||||
audit_log_id?: string
|
||||
created_at?: string | null
|
||||
field_name?: string
|
||||
id?: string
|
||||
new_value?: string | null
|
||||
old_value?: string | null
|
||||
}
|
||||
Relationships: [
|
||||
{
|
||||
foreignKeyName: "profile_change_fields_audit_log_id_fkey"
|
||||
columns: ["audit_log_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "profile_audit_log"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
]
|
||||
}
|
||||
profiles: {
|
||||
Row: {
|
||||
auth0_sub: string | null
|
||||
@@ -2377,6 +2748,47 @@ export type Database = {
|
||||
}
|
||||
Relationships: []
|
||||
}
|
||||
request_breadcrumbs: {
|
||||
Row: {
|
||||
category: string
|
||||
created_at: string | null
|
||||
id: string
|
||||
level: string | null
|
||||
message: string
|
||||
request_id: string
|
||||
sequence_order: number
|
||||
timestamp: string
|
||||
}
|
||||
Insert: {
|
||||
category: string
|
||||
created_at?: string | null
|
||||
id?: string
|
||||
level?: string | null
|
||||
message: string
|
||||
request_id: string
|
||||
sequence_order: number
|
||||
timestamp: string
|
||||
}
|
||||
Update: {
|
||||
category?: string
|
||||
created_at?: string | null
|
||||
id?: string
|
||||
level?: string | null
|
||||
message?: string
|
||||
request_id?: string
|
||||
sequence_order?: number
|
||||
timestamp?: string
|
||||
}
|
||||
Relationships: [
|
||||
{
|
||||
foreignKeyName: "request_breadcrumbs_request_id_fkey"
|
||||
columns: ["request_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "request_metadata"
|
||||
referencedColumns: ["request_id"]
|
||||
},
|
||||
]
|
||||
}
|
||||
request_metadata: {
|
||||
Row: {
|
||||
breadcrumbs: Json | null
|
||||
@@ -2394,7 +2806,12 @@ export type Database = {
|
||||
method: string
|
||||
parent_request_id: string | null
|
||||
request_id: string
|
||||
request_method: string | null
|
||||
request_path: string | null
|
||||
response_status: number | null
|
||||
response_time_ms: number | null
|
||||
retry_count: number | null
|
||||
session_id: string | null
|
||||
started_at: string
|
||||
status_code: number | null
|
||||
trace_id: string | null
|
||||
@@ -2417,7 +2834,12 @@ export type Database = {
|
||||
method: string
|
||||
parent_request_id?: string | null
|
||||
request_id: string
|
||||
request_method?: string | null
|
||||
request_path?: string | null
|
||||
response_status?: number | null
|
||||
response_time_ms?: number | null
|
||||
retry_count?: number | null
|
||||
session_id?: string | null
|
||||
started_at?: string
|
||||
status_code?: number | null
|
||||
trace_id?: string | null
|
||||
@@ -2440,7 +2862,12 @@ export type Database = {
|
||||
method?: string
|
||||
parent_request_id?: string | null
|
||||
request_id?: string
|
||||
request_method?: string | null
|
||||
request_path?: string | null
|
||||
response_status?: number | null
|
||||
response_time_ms?: number | null
|
||||
retry_count?: number | null
|
||||
session_id?: string | null
|
||||
started_at?: string
|
||||
status_code?: number | null
|
||||
trace_id?: string | null
|
||||
@@ -4308,6 +4735,54 @@ export type Database = {
|
||||
},
|
||||
]
|
||||
}
|
||||
submission_metadata: {
|
||||
Row: {
|
||||
created_at: string | null
|
||||
display_order: number | null
|
||||
id: string
|
||||
metadata_key: string
|
||||
metadata_value: string
|
||||
submission_id: string
|
||||
updated_at: string | null
|
||||
value_type: string | null
|
||||
}
|
||||
Insert: {
|
||||
created_at?: string | null
|
||||
display_order?: number | null
|
||||
id?: string
|
||||
metadata_key: string
|
||||
metadata_value: string
|
||||
submission_id: string
|
||||
updated_at?: string | null
|
||||
value_type?: string | null
|
||||
}
|
||||
Update: {
|
||||
created_at?: string | null
|
||||
display_order?: number | null
|
||||
id?: string
|
||||
metadata_key?: string
|
||||
metadata_value?: string
|
||||
submission_id?: string
|
||||
updated_at?: string | null
|
||||
value_type?: string | null
|
||||
}
|
||||
Relationships: [
|
||||
{
|
||||
foreignKeyName: "submission_metadata_submission_id_fkey"
|
||||
columns: ["submission_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "content_submissions"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
{
|
||||
foreignKeyName: "submission_metadata_submission_id_fkey"
|
||||
columns: ["submission_id"]
|
||||
isOneToOne: false
|
||||
referencedRelation: "moderation_queue_with_entities"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
]
|
||||
}
|
||||
test_data_registry: {
|
||||
Row: {
|
||||
created_at: string
|
||||
|
||||
193
src/lib/auditHelpers.ts
Normal file
193
src/lib/auditHelpers.ts
Normal file
@@ -0,0 +1,193 @@
|
||||
/**
|
||||
* Helper functions for relational audit logging
|
||||
* Replaces JSONB storage with proper relational tables
|
||||
*/
|
||||
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { logger } from './logger';
|
||||
|
||||
/**
|
||||
* Write admin audit details to relational table
|
||||
* Replaces JSONB admin_audit_log.details column
|
||||
*/
|
||||
export async function writeAdminAuditDetails(
|
||||
auditLogId: string,
|
||||
details: Record<string, unknown>
|
||||
): Promise<void> {
|
||||
if (!details || Object.keys(details).length === 0) return;
|
||||
|
||||
const entries = Object.entries(details).map(([key, value]) => ({
|
||||
audit_log_id: auditLogId,
|
||||
detail_key: key,
|
||||
detail_value: typeof value === 'object' ? JSON.stringify(value) : String(value),
|
||||
}));
|
||||
|
||||
const { error } = await supabase
|
||||
.from('admin_audit_details')
|
||||
.insert(entries);
|
||||
|
||||
if (error) {
|
||||
logger.error('Failed to write admin audit details', { error, auditLogId });
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write moderation audit metadata to relational table
|
||||
* Replaces JSONB moderation_audit_log.metadata column
|
||||
*/
|
||||
export async function writeModerationAuditMetadata(
|
||||
auditLogId: string,
|
||||
metadata: Record<string, unknown>
|
||||
): Promise<void> {
|
||||
if (!metadata || Object.keys(metadata).length === 0) return;
|
||||
|
||||
const entries = Object.entries(metadata).map(([key, value]) => ({
|
||||
audit_log_id: auditLogId,
|
||||
metadata_key: key,
|
||||
metadata_value: typeof value === 'object' ? JSON.stringify(value) : String(value),
|
||||
}));
|
||||
|
||||
const { error } = await supabase
|
||||
.from('moderation_audit_metadata')
|
||||
.insert(entries);
|
||||
|
||||
if (error) {
|
||||
logger.error('Failed to write moderation audit metadata', { error, auditLogId });
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write item change fields to relational table
|
||||
* Replaces JSONB item_edit_history.changes column
|
||||
*/
|
||||
export async function writeItemChangeFields(
|
||||
editHistoryId: string,
|
||||
changes: Record<string, { old_value?: unknown; new_value?: unknown }>
|
||||
): Promise<void> {
|
||||
if (!changes || Object.keys(changes).length === 0) return;
|
||||
|
||||
const entries = Object.entries(changes).map(([fieldName, change]) => ({
|
||||
edit_history_id: editHistoryId,
|
||||
field_name: fieldName,
|
||||
old_value: change.old_value !== undefined
|
||||
? (typeof change.old_value === 'object' ? JSON.stringify(change.old_value) : String(change.old_value))
|
||||
: null,
|
||||
new_value: change.new_value !== undefined
|
||||
? (typeof change.new_value === 'object' ? JSON.stringify(change.new_value) : String(change.new_value))
|
||||
: null,
|
||||
}));
|
||||
|
||||
const { error } = await supabase
|
||||
.from('item_change_fields')
|
||||
.insert(entries);
|
||||
|
||||
if (error) {
|
||||
logger.error('Failed to write item change fields', { error, editHistoryId });
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write request breadcrumbs to relational table
|
||||
* Replaces JSONB request_metadata.breadcrumbs column
|
||||
*/
|
||||
export async function writeRequestBreadcrumbs(
|
||||
requestId: string,
|
||||
breadcrumbs: Array<{
|
||||
timestamp: string;
|
||||
category: string;
|
||||
message: string;
|
||||
level?: 'debug' | 'info' | 'warn' | 'error';
|
||||
}>
|
||||
): Promise<void> {
|
||||
if (!breadcrumbs || breadcrumbs.length === 0) return;
|
||||
|
||||
const entries = breadcrumbs.map((breadcrumb, index) => ({
|
||||
request_id: requestId,
|
||||
timestamp: breadcrumb.timestamp,
|
||||
category: breadcrumb.category,
|
||||
message: breadcrumb.message,
|
||||
level: breadcrumb.level || 'info',
|
||||
sequence_order: index,
|
||||
}));
|
||||
|
||||
const { error } = await supabase
|
||||
.from('request_breadcrumbs')
|
||||
.insert(entries);
|
||||
|
||||
if (error) {
|
||||
logger.error('Failed to write request breadcrumbs', { error, requestId });
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read admin audit details from relational table
|
||||
*/
|
||||
export async function readAdminAuditDetails(
|
||||
auditLogId: string
|
||||
): Promise<Record<string, string>> {
|
||||
const { data, error } = await supabase
|
||||
.from('admin_audit_details')
|
||||
.select('detail_key, detail_value')
|
||||
.eq('audit_log_id', auditLogId);
|
||||
|
||||
if (error) {
|
||||
logger.error('Failed to read admin audit details', { error, auditLogId });
|
||||
return {};
|
||||
}
|
||||
|
||||
return data.reduce((acc, row) => {
|
||||
acc[row.detail_key] = row.detail_value;
|
||||
return acc;
|
||||
}, {} as Record<string, string>);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read moderation audit metadata from relational table
|
||||
*/
|
||||
export async function readModerationAuditMetadata(
|
||||
auditLogId: string
|
||||
): Promise<Record<string, string>> {
|
||||
const { data, error } = await supabase
|
||||
.from('moderation_audit_metadata')
|
||||
.select('metadata_key, metadata_value')
|
||||
.eq('audit_log_id', auditLogId);
|
||||
|
||||
if (error) {
|
||||
logger.error('Failed to read moderation audit metadata', { error, auditLogId });
|
||||
return {};
|
||||
}
|
||||
|
||||
return data.reduce((acc, row) => {
|
||||
acc[row.metadata_key] = row.metadata_value;
|
||||
return acc;
|
||||
}, {} as Record<string, string>);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read item change fields from relational table
|
||||
*/
|
||||
export async function readItemChangeFields(
|
||||
editHistoryId: string
|
||||
): Promise<Record<string, { old_value: string | null; new_value: string | null }>> {
|
||||
const { data, error } = await supabase
|
||||
.from('item_change_fields')
|
||||
.select('field_name, old_value, new_value')
|
||||
.eq('edit_history_id', editHistoryId);
|
||||
|
||||
if (error) {
|
||||
logger.error('Failed to read item change fields', { error, editHistoryId });
|
||||
return {};
|
||||
}
|
||||
|
||||
return data.reduce((acc, row) => {
|
||||
acc[row.field_name] = {
|
||||
old_value: row.old_value,
|
||||
new_value: row.new_value,
|
||||
};
|
||||
return acc;
|
||||
}, {} as Record<string, { old_value: string | null; new_value: string | null }>);
|
||||
}
|
||||
Reference in New Issue
Block a user