ディレクトリモジュール
MBC CQRS ServerlessフレームワークのためのS3統合を備えたディレクトリ管理機能です。
インストール
npm install @mbc-cqrs-serverless/directory
概要
Directoryパッケージは、マルチテナントCQRSアーキテクチャにおける包括的なファイルとフォルダの管理を提供します。Amazon S3と統合してファイルストレージを管理し、詳細なアクセス権限をサポートします。
機能
- ディレクトリCRUD操作: フォルダとファイルの作成、読み取り、更新、削除
- S3統合: Amazon S3との完全なファイル管理
- アクセス権限: 特定のフォルダとファイルに対する詳細な権限
- マルチテナントサポート: テナント分離されたディレクトリ管理
- イベント駆動アーキテクチャ: コマンド/イベントハンドリングを備えたCQRSパターン上に構築
- RESTful API: ディレクトリ操作のための完全なREST API
- バージョン履歴: ファイルとフォルダの以前のバージョンを追跡および復元
基本セットアップ
モジュール設定
import { DirectoryStorageModule } from '@mbc-cqrs-serverless/directory';
import { Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';
@Module({
imports: [
DirectoryStorageModule.register({
enableController: true, // Enable REST API endpoints (REST APIエンドポイントを有効化)
prismaService: PrismaService, // 必須(directory サービスが注入する)
dataSyncHandlers: [], // Optional data sync handlers (オプションのデータ同期ハンドラー)
}),
],
})
export class AppModule {}
テーブル名の設定
モジュールは既定で directory DynamoDB テーブルを使用する。後方互換オプションでテーブル名と関連識別子を上書きでき、省略すれば現行の挙動が維持される。register と registerAsync の両方が受け付ける。
| オプション | 既定値 | 説明 |
|---|---|---|
tableName | directory | DynamoDB の raw ベーステーブル名。物理テーブルは ${NODE_ENV}-${APP_NAME}-${tableName} に -command / -data / -history サフィックスが付く。 |
pkPrefix | DIRECTORY | パーティションキーのプレフィックス(# 区切りの前)。 |
prismaModelName | directory | RDS 読み取りに使う Prisma モデルのアクセサ名。 |
// directory モジュールを「document」として運用する opt-in 例
DirectoryStorageModule.register({
enableController: true,
prismaService: PrismaService,
tableName: 'document',
pkPrefix: 'DOCUMENT',
prismaModelName: 'document',
});
// 非同期設定 — factory は PrismaService の**インスタンス**を解決して返すこと
DirectoryStorageModule.registerAsync({
tableName: 'document',
pkPrefix: 'DOCUMENT',
prismaModelName: 'document',
imports: [PrismaModule],
inject: [PrismaService],
useFactory: (prisma) => ({ prismaService: prisma }),
});
3つのオプションはセットで設定する
tableName だけを変更すると、パーティションキーは DIRECTORY# のまま prismaService.directory を読むという不整合になる。tableName・pkPrefix・prismaModelName をセットで設定すること。
プロビジョニングとデータ移行
custom テーブル名を使うにはアプリ側のプロビジョニングが必要:
- DynamoDB: raw ベース名(例
"document"。-command/-data/-history付きではない)をprisma/dynamodbs/cqrs.jsonに追加し、npm run migrate:ddbを実行する。これで3つの物理テーブルが作成される。custom 名は手動追加が必要(master モジュールの postinstall のみが既定名を自動追加)。IaC でも同テーブルを定義すること。 - RDS: 対応する Prisma モデル(例
model Document { ... })をschema.prismaに追加し、npm run migrate:rdsを実行する。 - データ: migrate コマンドは空テーブルを作成するだけである。既存データを
directory-*/DIRECTORY#/directoryモデルから新しい対象へコピーするのはアプリ側の責務である。
バージョン情報
設定可能なテーブル名(tableName、pkPrefix、prismaModelName)と registerAsync は バージョン 1.4.0 で追加された。
APIエンドポイント
| メソッド | エンドポイント | 説明 |
|---|---|---|
| POST | /api/directory/ | 新しいファイルまたはフォルダを作成 |
| GET | /api/directory/summary | テナントのファイルサイズサマリーを取得 |
| GET | /api/directory/:id | 特定のファイルまたはフォルダの詳細を取得 |
| GET | /api/directory/:id/history | ファイルまたはフォルダのバージョン履歴を取得 |
| POST | /api/directory/:id/history/:version/restore | 特定のバージョンを復元 |
| PUT | /api/directory/:id/restore | 一時削除されたアイテムを復元 |
| PATCH | /api/directory/:id | 特定のファイルまたはフォルダを更新 |
| PATCH | /api/directory/:id/permission | ファイルまたはフォルダの権限を更新 |
| PATCH | /api/directory/:id/rename | ファイルまたはフォルダの名前を変更 |
| PATCH | /api/directory/:id/copy | ファイルまたはフォルダをコピー |
| PATCH | /api/directory/:id/move | ファイルまたはフォルダを移動 |
| DELETE | /api/directory/:id | ファイルまたはフォルダを論理削除 |
| DELETE | /api/directory/:id/bin | ファイルを完全に削除してS3からも削除 |
| POST | /api/directory/file/view | ファイル閲覧用の署名付きURLを生成 |
| POST | /api/directory/file | ファイルアップロード用の署名付きURLを生成 |
フォルダの作成
import { DirectoryService, DirectoryCreateDto, DirectoryDataEntity } from '@mbc-cqrs-serverless/directory';
import { IInvoke } from '@mbc-cqrs-serverless/core';
import { Injectable } from '@nestjs/common';
@Injectable()
export class FolderService {
constructor(private readonly directoryService: DirectoryService) {}
async createFolder(
createDto: DirectoryCreateDto,
invokeContext: IInvoke,
): Promise<DirectoryDataEntity> {
return this.directoryService.create(createDto, { invokeContext });
}
}
ファイルのアップロード
async uploadFile(
createDto: DirectoryCreateDto,
invokeContext: IInvoke,
): Promise<DirectoryDataEntity> {
// File upload is handled through the create method with file content (ファイルアップロードはcreateメソッドを通じて処理されます)
return this.directoryService.create(createDto, { invokeContext });
}
コンテンツの一覧表示
async getDirectory(
detailDto: DetailDto,
invokeContext: IInvoke,
queryDto: DirectoryDetailDto,
): Promise<DirectoryDataEntity> {
return this.directoryService.findOne(detailDto, { invokeContext }, queryDto);
}
async getDirectoryHistory(
detailDto: DetailDto,
invokeContext: IInvoke,
queryDto: DirectoryDetailDto,
): Promise<DirectoryDataListEntity> {
return this.directoryService.findHistory(detailDto, { invokeContext }, queryDto);
}
ファイル操作
// Get file attributes (ファイル属性を取得)
async getFileAttributes(detailDto: DetailDto): Promise<DirectoryAttributes> {
return this.directoryService.getItemAttributes(detailDto);
}
// Get file item (ファイルアイテムを取得)
async getFile(detailDto: DetailDto): Promise<DirectoryDataEntity> {
return this.directoryService.getItem(detailDto);
}
// Soft delete (marks as deleted) (論理削除、削除済みとしてマーク)
async removeItem(
detailDto: DetailDto,
invokeContext: IInvoke,
queryDto: DirectoryDetailDto,
): Promise<DirectoryDataEntity> {
return this.directoryService.remove(detailDto, { invokeContext }, queryDto);
}
// Permanently remove file and delete from S3 (ファイルを完全に削除してS3からも削除)
async removeFile(
detailDto: DetailDto,
invokeContext: IInvoke,
queryDto: DirectoryDetailDto,
): Promise<DirectoryDataEntity> {
return this.directoryService.removeFile(detailDto, { invokeContext }, queryDto);
}
アイテムの更新
import { DirectoryUpdateDto } from '@mbc-cqrs-serverless/directory';
async updateItem(
detailDto: DetailDto,
updateDto: DirectoryUpdateDto,
invokeContext: IInvoke,
): Promise<DirectoryDataEntity> {
return this.directoryService.update(detailDto, updateDto, { invokeContext });
}
アイテムの名前変更
import { DirectoryRenameDto } from '@mbc-cqrs-serverless/directory';
async renameItem(
detailDto: DetailDto,
renameDto: DirectoryRenameDto,
invokeContext: IInvoke,
): Promise<DirectoryDataEntity> {
return this.directoryService.rename(detailDto, renameDto, { invokeContext });
}