3.2 KiB
3.2 KiB
Phase 3: Filesystem Storage Migration
Agent Assignment
Primary Agent: storage-agent Duration: 30-40 minutes
Prerequisites
- None (can start immediately)
Objectives
- Create filesystem storage adapter
- Replace MinIO adapter with filesystem
- Update documents feature to use filesystem
- Verify document upload/download works
Step-by-Step Instructions
Step 1: Create Filesystem Adapter
Create backend/src/core/storage/adapters/filesystem.adapter.ts:
import { StorageService } from '../storage.service';
import * as fs from 'fs/promises';
import * as path from 'path';
import { createReadStream } from 'fs';
export class FilesystemAdapter implements StorageService {
private basePath: string;
constructor(basePath: string = '/app/data/documents') {
this.basePath = basePath;
}
async putObject(bucket: string, key: string, body: Buffer, contentType?: string): Promise<void> {
const filePath = path.join(this.basePath, key);
await fs.mkdir(path.dirname(filePath), { recursive: true });
await fs.writeFile(filePath, body);
}
async getObjectStream(bucket: string, key: string): Promise<NodeJS.ReadableStream> {
const filePath = path.join(this.basePath, key);
return createReadStream(filePath);
}
async deleteObject(bucket: string, key: string): Promise<void> {
const filePath = path.join(this.basePath, key);
await fs.unlink(filePath);
}
async headObject(bucket: string, key: string): Promise<any> {
const filePath = path.join(this.basePath, key);
const stats = await fs.stat(filePath);
return { size: stats.size, lastModified: stats.mtime };
}
async getSignedUrl(bucket: string, key: string): Promise<string> {
// Not needed for filesystem, return direct path
return `/api/documents/download/${key}`;
}
}
Step 2: Update Storage Service Factory
Modify backend/src/core/storage/storage.service.ts:
import { FilesystemAdapter } from './adapters/filesystem.adapter';
export function getStorageService(): StorageService {
// Always use filesystem adapter
return new FilesystemAdapter('/app/data/documents');
}
Step 3: Verify Documents Feature
No changes needed to documents.controller.ts - it uses StorageService interface.
Storage keys will be filesystem paths:
documents/{userId}/{vehicleId}/{documentId}/{filename}
Step 4: Test Document Upload
# Rebuild backend
cd backend && npm run build
# Restart backend
docker compose restart mvp-backend
# Test upload (requires authentication)
curl -X POST https://admin.motovaultpro.com/api/documents \
-H "Authorization: Bearer $TOKEN" \
-F "file=@test.pdf" \
-F "vehicleId=123"
# Verify file exists
docker compose exec mvp-backend ls -la /app/data/documents/
Validation Criteria
- FilesystemAdapter created
- getStorageService returns FilesystemAdapter
- Document upload works
- Document download works
- Files stored in /app/data/documents/
- No MinIO references in code
Validation Command:
grep -r "minio\|MinIO" backend/src/ | wc -l
# Expected: 0
Update EXECUTION-STATE.json
{
"phases": {"3": {"status": "completed", "validation_passed": true}}
}