MCPcopy Index your code
hub / github.com/simstudioai/sim / deleteDocumentStorageFiles

Function deleteDocumentStorageFiles

apps/sim/lib/knowledge/documents/service.ts:1847–1913  ·  view source on GitHub ↗
(
  documentsToDelete: Array<{ id: string; fileUrl: string | null; workspaceId?: string | null }>,
  requestId: string
)

Source from the content-addressed store, hash-verified

1845}
1846
1847export async function deleteDocumentStorageFiles(
1848 documentsToDelete: Array<{ id: string; fileUrl: string | null; workspaceId?: string | null }>,
1849 requestId: string
1850): Promise<void> {
1851 const entries = documentsToDelete.map((doc) => ({
1852 doc,
1853 storageKey: getKnowledgeBaseStorageKey(doc.fileUrl),
1854 }))
1855
1856 // Resolve all kb/ ownership bindings in one query (avoids an N+1 across the
1857 // delete fan-out below).
1858 const kbKeys = [
1859 ...new Set(
1860 entries
1861 .map((entry) => entry.storageKey)
1862 .filter((key): key is string => typeof key === 'string' && key.startsWith('kb/'))
1863 ),
1864 ]
1865 const ownerByKey = new Map<string, string | null>()
1866 if (kbKeys.length > 0) {
1867 const bindings = await getFileMetadataByKeys(kbKeys, 'knowledge-base')
1868 for (const binding of bindings) {
1869 ownerByKey.set(binding.key, binding.workspaceId)
1870 }
1871 }
1872
1873 await Promise.allSettled(
1874 entries.map(async ({ doc, storageKey }) => {
1875 if (!storageKey) {
1876 return
1877 }
1878
1879 // Only delete a kb/ object when its trusted ownership binding confirms the
1880 // deleting document's workspace owns it. Prevents deleting another tenant's
1881 // object via a document with a planted fileUrl.
1882 if (storageKey.startsWith('kb/')) {
1883 const bindingWorkspaceId = ownerByKey.get(storageKey)
1884 if (!bindingWorkspaceId) {
1885 logger.warn(`[${requestId}] Skipping storage delete: no ownership binding for key`, {
1886 documentId: doc.id,
1887 storageKey,
1888 })
1889 return
1890 }
1891 if (!doc.workspaceId || bindingWorkspaceId !== doc.workspaceId) {
1892 logger.warn(`[${requestId}] Skipping storage delete: ownership binding mismatch`, {
1893 documentId: doc.id,
1894 storageKey,
1895 bindingWorkspaceId,
1896 documentWorkspaceId: doc.workspaceId ?? null,
1897 })
1898 return
1899 }
1900 }
1901
1902 try {
1903 await deleteFile({ key: storageKey, context: 'knowledge-base' })
1904 await deleteFileMetadata(storageKey)

Callers 2

route.tsFile · 0.90
hardDeleteDocumentsFunction · 0.85

Calls 8

getFileMetadataByKeysFunction · 0.90
deleteFileFunction · 0.90
deleteFileMetadataFunction · 0.90
toErrorFunction · 0.90
setMethod · 0.65
getMethod · 0.65
warnMethod · 0.65

Tested by

no test coverage detected