コンテンツにスキップ

ファイル連携・削除・補償・検索

@alneas/data-engine/integrations/files が FileProvider、FileNode、 DataAccessFileProvider の正本です。表示・選択状態・ブラウザー保存・SDK設定は 利用側に残します。SDKの実行時importはありません。連携入口の型には任意peerの @alneas/data-access@0.1.0 と @alneas/universal-storage@0.1.0 が必要です。 engineの基本機能はこれらを未導入でも利用できます。

import { DataAccessFileProvider } from '@alneas/data-engine/integrations/files';
const files = new DataAccessFileProvider({
dataAccess, storage, collection: 'files', physicalPrefix: 'vault/',
searchMode: 'portable', deleteMode: 'metadata-only',
});
const node = await files.uploadFile('inbox/', new Blob(['hello']), 'report.txt');
await files.updateMetadata(node.id, { tags: '経理,承認済み' });
const matches = await files.searchNodes({ query: 'REPORT', tags: ['経理'] });

例の dataAccess / storage は、利用側で認証・認可・接続設定済みのアダプターです。 テーブルや認証情報は自動生成しません。DBには id、folder、filename、 physical_key、size、content_type、tags、updated_at、kind を用意します。 フォルダー作成ではsize/content_typeを省略するためNULLを許容し、tagsも任意にします。 IDの既定はWeb CryptoのrandomUUIDです。独自のcreateIdはアプリ内で一意な新しい値を [A-Za-z0-9_-]{1,128} の形式で返してください。物理キーの名前空間も専有します。 保存にはstorageが実際に返したキーを使い、表示名やIDから削除キーを推測しません。

rename/moveはDB情報だけを変更し、実体キーを保持します。フォルダー操作はその行だけが 対象で、子孫の再帰処理はしません。updateMetadataで永続化するのはtagsだけです。 任意のDB列やストレージメタデータの更新は保証しません。listNodesはfolderの一致と kind/filenameの昇順を利用します。ページング・カーソル機能はなくhasMore:falseを返す ため、アダプターがフォルダー全件を返す必要があります。大規模一覧にはページ対応の 独自Providerを実装してください。

既定のmetadata-onlyは従来通りDBの行だけを順番に削除し、最初の失敗で停止します。 実体は保持され、保存料金も発生し得ます。実体も削除する場合は deleteMode:'storage-and-metadata' を明示します。ファイル行のphysical_keyで実体を 先に削除し、次にDB行を削除します。行が存在しない場合は何もしません。storage.deleteが falseを返した場合はheadがnullであることを確認してから進みます。ストレージ操作・確認の 失敗時はDB行を保持します。実体削除後にDB削除だけ失敗した場合は、参照切れの行が残ります。 FileProviderOperationErrorのstage/nodeId/physicalKey/storageDeleted/completedIds/causeを 使って再試行・復旧してください。失敗したIDより後のIDは未処理です。 DBと実体の一括トランザクションではありません。削除するのは現在見えるキーであり、 S3の過去バージョン・削除マーカー・保存義務・法的な消去の保証は含みません。 認可・並行更新・キーの共有禁止は利用側で管理します。

実体アップロード後にDB登録します。既定のuploadFailurePolicy:’retain’は、DB登録が 失敗しても実体を保持します。DBがコミット済みで応答だけ失われた可能性があるためです。 Publicの例外には実体キーと元のcauseが入ります。compensateを選ぶ場合は canCompensateUploadを指定します。読み戻しがnull、かつこの関数がtrueを返した場合だけ 補償削除します。関数は「確実に未コミット」「今回の新しいキーを専有」を確認してください。 結果整合性による読み遅れや行の不在だけでは不十分です。行があればretained、確認不能なら unconfirmed、補償削除成功はdeleted、補償失敗はfailedとcompensationError、確認を断った 場合はretainedです。いずれも元のDB登録の例外は投げます。storage.upload自体の失敗も 結果が不明なため自動削除しません。自動再送・孤立実体の定期削除は実装していません。

Publicの既定portableは全論理フォルダーを対象に、ファイル名の部分一致をJavaScriptの toLowerCaseで比較します。正規表現ではなく、記号も文字通りです。Unicode正規化やロケール 固有の照合はしません。空のqueryは全件に一致します。tagsは引用符・エスケープなしの カンマ区切り文字列で、前後の空白を除いた大文字小文字を区別する完全一致です。 指定タグすべての一致(AND)が必要です。タグ自体にカンマは使えません。 候補の順序を維持し、関連度ソートは追加しません。

標準ではfind(collection, {}, {paginateAll:true})で認可済み候補の全件取得を要求し、 ローカルで照合します。アダプターが全件取得に対応する必要があり、サーバーの件数制限を 自動的に突破できるわけではありません。maxSearchRecords(既定10,000件)は取得後の 件数検査であり、通信量を制限しません。大規模検索はsearchRecords(criteria)で索引を使い、 条件に合う認可済み候補を漏れなく返してください。同じportable条件で再照合します。 途中の1ページだけを返すと検索漏れになるため、そのような実装にはしないでください。

legacy-adapterは従来の$regex/$options:’i’と$allをそのまま渡します。対応可否と意味は アダプター次第で、CSV文字列がDB配列になるわけではありません。privateの既存入口は この既定と元のDB登録例外の同一性を維持します。Public直importはportableと構造化例外が 既定です。privateの検索改善はportableを明示して段階的に切り替えられます。