Files
admin/docs/core-modules/file-manager/backend.md
T

369 lines
11 KiB
Markdown

# File Manager Backend
The backend module exposes authenticated file operations under `/file-manager`. It validates requests, authorizes actions, normalizes paths, orchestrates file-manager behavior, and delegates raw storage work to a storage adapter.
Source root:
```txt
apps/backend/app/base_modules/FileManager/
```
## Request Flow
```txt
routes.ts
-> controller/file_manager_controller.ts
-> validator/*
-> policy/file_manager_policy.ts
-> services/file_manager_service.ts
-> services/storage_service/storage_service_interface.ts
-> services/storage_service/create_storage_service.ts
-> services/storage_service/fs_storage_service.ts | services/storage_service/s3_storage_service.ts
-> Adonis Drive
```
The controller should stay thin. It handles HTTP concerns: auth policy checks, request validation, path extraction, status codes, and response payload shape.
`FileManagerService` owns business orchestration. Storage adapters own raw persistence operations.
## Routes
All routes are prefixed with `/file-manager` and use `middleware.auth()`.
| Method | Route | Controller Method | Purpose |
| -------- | ------------------ | ----------------- | ------------------------------------------------------- |
| `GET` | `/` | `index` | List root directory entries. |
| `GET` | `/*` | `index` | List entries for a nested directory. |
| `GET` | `/files/details/*` | `show` | Return file metadata and optional text preview content. |
| `GET` | `/files/raw/*` | `raw` | Stream raw file content. |
| `GET` | `/search?q=value` | `search` | Search entries recursively. |
| `POST` | `/folders` | `createFolder` | Create a folder. |
| `POST` | `/files` | `upload` | Upload a file. |
| `POST` | `/files/duplicate` | `duplicate` | Duplicate one or more **file** entries. |
| `PUT` | `/entries/rename` | `rename` | Rename or move an entry within its parent path. |
| `DELETE` | `/*` | `destroy` | Delete an entry. |
## Authorization
Policy file:
```txt
policy/file_manager_policy.ts
```
Controller methods call policy abilities before performing work:
| Ability | Used By |
| ---------- | ---------------------------------------------- |
| `viewList` | List entries, search entries. |
| `view` | File details, raw file stream. |
| `create` | Create folder, upload file, duplicate entries. |
| `update` | Rename entry. |
| `delete` | Delete entry. |
When adding a new operation, add or reuse an explicit policy ability before adding service logic.
## Validation
Validators live in:
```txt
validator/
```
Current validators:
| File | Purpose |
| -------------------------------- | ----------------------------------------------------------------- |
| `list_validator.ts` | Validates filter, sort, order, max results, and pagination token. |
| `create_directory_validator.ts` | Validates parent path and folder name. |
| `rename_entry_validator.ts` | Validates source path and new name. |
| `upload_file_validator.ts` | Validates upload path and file payload. |
| `duplicate_entries_validator.ts` | Validates duplicate source paths. |
| `schemas.ts` | Shared validation schema helpers. |
Path extraction from wildcard routes goes through:
```txt
helpers/get_validated_path_from_request.ts
```
Keep path validation centralized. Avoid parsing wildcard paths directly in controllers or storage adapters.
## Services
### `file_manager_service.ts`
Main orchestration service.
Responsibilities:
- List directory entries with filtering, sorting, and pagination.
- Compose file detail responses with preview content.
- Create directory response entries.
- Validate and move entries.
- Generate unique upload names.
- Generate duplicate copy names.
- Search entries.
- Coordinate storage adapter calls.
### `path_service.ts`
Shared path and filename utility service.
Responsibilities:
- Convert client paths to storage paths.
- Convert storage paths to client paths.
- Join paths safely.
- Get dirname and basename.
- Parse file extension metadata.
- Sanitize filenames.
- Generate unique names.
Use this service for path behavior instead of string manipulation in feature code.
### `entry_list_service.ts`
Applies list behavior to raw storage entries.
Responsibilities:
- Filter entries by category.
- Sort entries.
- Keep folders before files.
- Paginate entries.
- Encode and decode pagination tokens.
Frontend list controls must stay compatible with this service's accepted filter and sort values.
### `file_preview_service.ts`
Adds text preview content to previewable files.
Previewable text extensions are currently defined in:
```txt
services/file_preview_service.ts
```
If a file type needs rich frontend preview, keep the backend response small and stream raw content through `/files/raw/*` when possible.
### `entry_search_service.ts`
Searches entries by path and includes matching parent folders so the frontend can display useful context.
Search receives an abort signal from the controller. Long-running search implementations should respect that signal.
## Storage
Storage abstractions live in:
```txt
services/storage_service/
```
### `storage_service_interface.ts`
Defines the storage adapter contract. Adapters expose raw operations:
- List directory entries.
- List recursive entries.
- Check entry existence.
- Get file metadata.
- Read file content.
- Stream file content.
- Write file.
- Create directory.
- Move entry.
- Delete entry.
- Copy entry.
Services should call the interface, not a concrete adapter.
### `fs_storage_service.ts`
Filesystem storage adapter.
Responsibilities:
- Call the Adonis Drive filesystem disk.
- Map filesystem objects to File Manager entries.
- Handle file streams and metadata.
- Create, move, copy, and delete filesystem entries.
- Preserve filesystem directory marker behavior.
### `s3_storage_service.ts`
S3-compatible storage adapter.
Responsibilities:
- Call the Adonis Drive `s3` disk.
- Map S3 objects and common prefixes to File Manager entries.
- Upload multipart files by streaming the temporary upload file into S3 with `putStream`.
- Read file content and streams from S3.
- Create folders with directory marker objects.
- Move folders by moving every object under the folder prefix.
- Delete files with exact object deletion and folders with folder-prefix deletion.
- Copy file entries.
S3 has no native directories. The adapter uses the same `.keep` marker convention as the filesystem adapter so empty folders can exist.
Folder operations must use slash-terminated prefixes. For example, deleting `test/` must not delete objects such as `test123.txt`.
### `fs_directory_marker_service.ts`
Encapsulates the filesystem directory marker convention.
Current marker:
```txt
.keep
```
Do not duplicate marker logic outside this service. Storage adapters that need virtual folders should use this marker service behind the storage interface.
### `create_storage_service.ts`
Storage service factory.
Current supported storage:
```txt
fs
s3
```
The active adapter is selected by `DRIVE_DISK`.
```env
DRIVE_DISK=fs
```
or:
```env
DRIVE_DISK=s3
```
## Drive Configuration
Adonis Drive config lives in:
```txt
apps/backend/config/drive.ts
```
Configured disks:
| Disk | Driver | Purpose |
| ---- | ------------- | ---------------------------------------------------- |
| `fs` | `services.fs` | Local development and filesystem-backed storage. |
| `s3` | `services.s3` | S3-compatible object storage, including local MinIO. |
The S3 disk expects these environment variables:
| Variable | Local Docker Value | Purpose |
| ----------------------- | --------------------------------------------------------------------- | --------------------------------------------- |
| `AWS_ACCESS_KEY_ID` | `minioadmin` | S3 access key. |
| `AWS_SECRET_ACCESS_KEY` | `minioadmin` | S3 secret key. |
| `AWS_REGION` | `us-east-1` | S3 region. |
| `S3_BUCKET` | `crux-drive` | Bucket used by the file manager. |
| `S3_ENDPOINT` | `http://minio:9000` in Docker, `http://localhost:9000` outside Docker | S3 API endpoint. |
| `S3_CDN_URL` | `http://localhost:9000/crux-drive/` | Browser-facing public URL base for file URLs. |
For MinIO, the S3 disk uses path-style addressing:
```ts
forcePathStyle: true;
```
The adapter also disables ACL API calls:
```ts
supportsACL: false;
```
Bucket public-read behavior is handled by the Docker bucket setup container.
## Local S3 Simulation
Local S3 is simulated with MinIO in:
```txt
docker-compose.yml
```
Services:
| Service | Purpose |
| --------------------- | --------------------------------------------------------------------------------------- |
| `minio` | Runs the S3-compatible object storage server. |
| `minio_create_bucket` | One-shot setup container that creates the bucket and enables anonymous download access. |
MinIO console:
```txt
http://localhost:9001
```
Default local credentials:
```txt
user: minioadmin
pass: minioadmin
```
The `minio_create_bucket` container is expected to exit after setup. A stopped container with successful bucket logs is normal.
To rebuild after dependency or Dockerfile changes:
```sh
docker compose build --no-cache
docker compose up
```
## Response Shape
Directory and file operations return `Entry` objects:
```ts
interface EntryBase {
name: string;
path: string;
updatedAt?: string;
}
interface FileEntry extends EntryBase {
type: "file";
size?: number;
url: string;
}
interface FolderEntry extends EntryBase {
type: "folder";
}
```
List responses include pagination metadata:
```ts
{
data: Entry[];
meta: {
nextPaginationToken: string | null;
};
}
```
## Backend Change Checklist
Before changing backend behavior:
1. Confirm the policy ability for the operation.
2. Add or update a validator for all request input.
3. Keep client paths and storage paths separated through `path_service.ts`.
4. Update the frontend DTO or mapper if response shape changes.
5. Update this documentation when routes, permissions, storage contracts, or response shapes change.