🚀 Initialize Musadaq SaaS: Full Backend + AI + React Dashboard + Docker Setup

This commit is contained in:
Hamza-Ayed
2026-04-16 23:26:32 +03:00
commit d66891ba0f
221 changed files with 13079 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
/**
* ════════════════════════════════════════════════════════════
* مُصادَق (Musadaq) — Local Storage Service
* ════════════════════════════════════════════════════════════
*/
import { Injectable, InternalServerErrorException } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import * as fs from 'fs';
import * as path from 'path';
@Injectable()
export class LocalStorageService {
private readonly storageRoot: string;
constructor(private configService: ConfigService) {
this.storageRoot = this.configService.get<string>('STORAGE_PATH', './uploads');
// Ensure the root storage directory exists
if (!fs.existsSync(this.storageRoot)) {
fs.mkdirSync(this.storageRoot, { recursive: true });
}
}
/**
* حفظ ملف في التخزين المحلي
*/
async saveFile(
tenantId: string,
companyId: string,
fileName: string,
buffer: Buffer,
): Promise<string> {
try {
const now = new Date();
const relativePath = path.join(
tenantId,
companyId,
'invoices',
now.getFullYear().toString(),
(now.getMonth() + 1).toString(),
);
const fullPath = path.join(this.storageRoot, relativePath);
// Create directories if they don't exist
if (!fs.existsSync(fullPath)) {
fs.mkdirSync(fullPath, { recursive: true });
}
const filePath = path.join(fullPath, fileName);
fs.writeFileSync(filePath, buffer);
// Return the relative path to be stored in the database
return path.join(relativePath, fileName);
} catch (error) {
throw new InternalServerErrorException('File storage failed');
}
}
/**
* حذف ملف
*/
async deleteFile(filePath: string): Promise<void> {
try {
const fullPath = path.join(this.storageRoot, filePath);
if (fs.existsSync(fullPath)) {
fs.unlinkSync(fullPath);
}
} catch (error) {
// Log error but don't fail the request
}
}
}