refactor(fase1b): unify upload/download via use-case + proxy download
- upload-file use-case is now the single save path with dedup policy (hash / bucket-key / none), partPrefix + signatureBuffer inputs, fileHash in UploadOutput, and owned temp-file cleanup; pass temp path (not open stream) to telegram service for testability - upload-controller (multipart + JSON) and web-api upload delegate to the use-case; JSON body via JsonUploadPayloadSchema; responses built from use-case output via buildUploadResponse - web-api download 302 redirect -> proxy stream (closes bot_token leak); shared CORS + sanitizeFilenameHeader - file-controller drops double file-info cache layer (pool caches) - bot handler uses DI singletons instead of direct construction - get-file RedirectRetrieval.redirectUrl marked deprecated, URL via shared builder; chunked-storage URL via buildTelegramFileUrl (no inline api.telegram.org/file/bot left in src/)
This commit is contained in:
@@ -4,8 +4,7 @@ import { buildNewFile } from '../../domain/entities/file-factory';
|
||||
import type { IFileRepository } from '../../domain/ports/file-repository';
|
||||
import type { ITelegramService } from '../../domain/ports/telegram-service';
|
||||
import { config } from '../../env';
|
||||
import { DrizzleFileRepository } from '../../infrastructure/persistence/repositories/file-repository';
|
||||
import { botPool } from '../../infrastructure/telegram/bot-pool';
|
||||
import { fileRepository, telegramService } from '../../infrastructure/di';
|
||||
import logger from '../../shared/logger/index';
|
||||
import {
|
||||
checkFileSize,
|
||||
@@ -75,9 +74,9 @@ const replyWithDownloadUrl = async (ctx: BotContext, publicId: string): Promise<
|
||||
*
|
||||
* @param deps - Optional external dependencies for testing or DI override.
|
||||
* @param deps.telegramService - The Telegram service used to forward files to
|
||||
* the storage channel. Defaults to the singleton BotPool instance.
|
||||
* the storage channel. Defaults to the DI singleton.
|
||||
* @param deps.fileRepo - The file repository used for deduplication queries
|
||||
* and persisting new file records. Defaults to a new DrizzleFileRepository.
|
||||
* and persisting new file records. Defaults to the DI singleton.
|
||||
* @returns The launched Telegraf bot instance, suitable for graceful shutdown
|
||||
* via `bot.stop(signal)`.
|
||||
*/
|
||||
@@ -89,8 +88,8 @@ export async function startBot(
|
||||
fileRepo?: IFileRepository;
|
||||
} = {},
|
||||
): Promise<Telegraf<Context>> {
|
||||
const telegramService = deps.telegramService ?? botPool;
|
||||
const fileRepo = deps.fileRepo ?? new DrizzleFileRepository();
|
||||
const telegramSvc = deps.telegramService ?? telegramService;
|
||||
const fileRepo = deps.fileRepo ?? fileRepository;
|
||||
|
||||
try {
|
||||
const bot = new Telegraf(config.botTokens[0]);
|
||||
@@ -147,7 +146,7 @@ export async function startBot(
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await telegramService.forwardToStorage(file_id, fileName, fileType);
|
||||
const result = await telegramSvc.forwardToStorage(file_id, fileName, fileType);
|
||||
const publicId = nanoid();
|
||||
|
||||
await fileRepo.create(
|
||||
|
||||
Reference in New Issue
Block a user