Fix metric_file permissions not cascading from report_files

This commit is contained in:
Wells Bunker 2025-09-22 13:40:46 -06:00
parent c5e0060072
commit 1646e37540
No known key found for this signature in database
GPG Key ID: DB16D6F2679B78FC
6 changed files with 5857 additions and 20 deletions

View File

@ -185,11 +185,13 @@ export function createCreateReportsExecute(
userId: context.userId, userId: context.userId,
}); });
await updateMetricsToReports({ if (metricIds.length > 0) {
reportId, await updateMetricsToReports({
metricIds, reportId,
userId: context.userId, metricIds,
}); userId: context.userId,
});
}
// Track file associations if messageId is available // Track file associations if messageId is available
if (context.messageId) { if (context.messageId) {

View File

@ -193,10 +193,12 @@ async function processEditOperations(
metricIds, metricIds,
}); });
await updateMetricsToReports({ if (metricIds.length > 0) {
reportId, await updateMetricsToReports({
metricIds, reportId,
}); metricIds,
});
}
if (messageId) { if (messageId) {
await trackFileAssociations({ await trackFileAssociations({

View File

@ -0,0 +1,50 @@
-- Custom SQL migration file, put your code below! --
-- Function to populate metric_files_to_report_files table from existing report content
-- Extracts metric IDs from report content and creates relationships
-- Drop the existing function first to allow changing the return type
DROP FUNCTION IF EXISTS populate_metric_files_to_report_files();
-- Create the function with VOID return type
CREATE FUNCTION populate_metric_files_to_report_files()
RETURNS VOID AS $$
BEGIN
-- Use CTE to extract all metric IDs from report content first
INSERT INTO metric_files_to_report_files (
metric_file_id,
report_file_id,
created_at,
updated_at,
deleted_at,
created_by
)
WITH extracted_metrics AS (
SELECT DISTINCT
rf.id AS report_file_id,
rf.created_by,
(regexp_matches(rf.content, '<metric[^>]*metricId="([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})"[^>]*>', 'g'))[1]::UUID AS metric_file_id
FROM report_files rf
WHERE rf.deleted_at IS NULL
AND rf.content ~ '<metric[^>]*metricId="[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}"[^>]*>'
)
SELECT
em.metric_file_id,
em.report_file_id,
CURRENT_TIMESTAMP AS created_at,
CURRENT_TIMESTAMP AS updated_at,
NULL AS deleted_at,
em.created_by
FROM extracted_metrics em
WHERE EXISTS (
SELECT 1
FROM metric_files mf
WHERE mf.id = em.metric_file_id
AND mf.deleted_at IS NULL
)
ON CONFLICT (metric_file_id, report_file_id) DO NOTHING;
END;
$$ LANGUAGE plpgsql;
-- Execute the function
SELECT populate_metric_files_to_report_files();

File diff suppressed because it is too large Load Diff

View File

@ -750,6 +750,13 @@
"when": 1758309016682, "when": 1758309016682,
"tag": "0107_deprecate_tables", "tag": "0107_deprecate_tables",
"breakpoints": true "breakpoints": true
},
{
"idx": 108,
"version": "7",
"when": 1758568913678,
"tag": "0108_amazing_cassandra_nova",
"breakpoints": true
} }
] ]
} }

View File

@ -1,7 +1,7 @@
import { and, eq, inArray, isNull } from 'drizzle-orm'; import { and, eq, inArray, isNull } from 'drizzle-orm';
import { z } from 'zod'; import { z } from 'zod';
import { db } from '../../connection'; import { db } from '../../connection';
import { metricFilesToReportFiles } from '../../schema'; import { metricFilesToReportFiles, reportFiles } from '../../schema';
// Input validation schema // Input validation schema
const UpdateMetricsToReportsInputSchema = z.object({ const UpdateMetricsToReportsInputSchema = z.object({
@ -53,17 +53,32 @@ export const updateMetricsToReports = async (
); );
// 3. Create new relationships // 3. Create new relationships
if (metricsToCreate.length > 0 && userId) { if (metricsToCreate.length > 0) {
const newRelationships = metricsToCreate.map((metricId) => ({ let createdBy = userId;
metricFileId: metricId, if (!userId) {
reportFileId: reportId, const [createdByResponse] = await db
createdAt: now, .select({ id: reportFiles.createdBy })
updatedAt: now, .from(reportFiles)
deletedAt: null, .where(eq(reportFiles.id, reportId));
createdBy: userId, if (createdByResponse?.id) {
})); createdBy = createdByResponse.id;
}
}
await tx.insert(metricFilesToReportFiles).values(newRelationships); if (createdBy) {
const newRelationships = metricsToCreate.map((metricId) => ({
metricFileId: metricId,
reportFileId: reportId,
createdAt: now,
updatedAt: now,
deletedAt: null,
createdBy: createdBy,
}));
await tx.insert(metricFilesToReportFiles).values(newRelationships);
} else {
throw new Error('Could not find user id for reports created by');
}
} }
// 4. Restore soft-deleted relationships (undelete and update) // 4. Restore soft-deleted relationships (undelete and update)