main
Backend Deploy 🚀 / build-and-deploy (push) Has been cancelled

This commit is contained in:
Harun CAN
2026-03-29 12:43:49 +03:00
parent 829413f05d
commit 85c35c73e8
41 changed files with 6127 additions and 36 deletions
+153
View File
@@ -0,0 +1,153 @@
import {
Controller,
Get,
Post,
Patch,
Delete,
Param,
Body,
Query,
HttpCode,
HttpStatus,
Logger,
ParseUUIDPipe,
Req,
} from '@nestjs/common';
import {
ApiTags,
ApiOperation,
ApiResponse,
ApiBearerAuth,
ApiQuery,
} from '@nestjs/swagger';
import { ProjectsService } from './projects.service';
import { CreateProjectDto, UpdateProjectDto, CreateFromTweetDto } from './dto/project.dto';
@ApiTags('projects')
@ApiBearerAuth()
@Controller('projects')
export class ProjectsController {
private readonly logger = new Logger(ProjectsController.name);
constructor(private readonly projectsService: ProjectsService) {}
/**
* Yeni bir video projesi oluşturur (DRAFT durumunda).
*/
@Post()
@ApiOperation({ summary: 'Yeni video projesi oluştur' })
@ApiResponse({ status: 201, description: 'Proje başarıyla oluşturuldu' })
async create(@Body() dto: CreateProjectDto, @Req() req: any) {
const userId = req.user?.id || req.user?.sub;
this.logger.log(`Yeni proje oluşturuluyor: "${dto.title}"`);
return this.projectsService.create(userId, dto);
}
/**
* Kullanıcının tüm projelerini listeler.
*/
@Get()
@ApiOperation({ summary: 'Tüm projeleri listele' })
@ApiQuery({ name: 'page', required: false, type: Number })
@ApiQuery({ name: 'limit', required: false, type: Number })
@ApiQuery({ name: 'status', required: false, type: String })
@ApiResponse({ status: 200, description: 'Proje listesi' })
async findAll(
@Req() req: any,
@Query('page') page?: number,
@Query('limit') limit?: number,
@Query('status') status?: string,
) {
const userId = req.user?.id || req.user?.sub;
return this.projectsService.findAll(userId, {
page: page || 1,
limit: limit || 10,
status,
});
}
/**
* Tek bir projeyi sahneleri ve medya asset'leriyle birlikte getirir.
*/
@Get(':id')
@ApiOperation({ summary: 'Proje detaylarını getir' })
@ApiResponse({ status: 200, description: 'Proje detayları' })
@ApiResponse({ status: 404, description: 'Proje bulunamadı' })
async findOne(@Param('id', ParseUUIDPipe) id: string, @Req() req: any) {
const userId = req.user?.id || req.user?.sub;
return this.projectsService.findOne(userId, id);
}
/**
* Projeyi günceller (sadece DRAFT durumundaki projeler güncellenebilir).
*/
@Patch(':id')
@ApiOperation({ summary: 'Projeyi güncelle' })
@ApiResponse({ status: 200, description: 'Proje güncellendi' })
async update(
@Param('id', ParseUUIDPipe) id: string,
@Body() dto: UpdateProjectDto,
@Req() req: any,
) {
const userId = req.user?.id || req.user?.sub;
this.logger.log(`Proje güncelleniyor: ${id}`);
return this.projectsService.update(userId, id, dto);
}
/**
* Projeyi soft-delete ile siler.
*/
@Delete(':id')
@HttpCode(HttpStatus.NO_CONTENT)
@ApiOperation({ summary: 'Projeyi sil (soft delete)' })
@ApiResponse({ status: 204, description: 'Proje silindi' })
async remove(@Param('id', ParseUUIDPipe) id: string, @Req() req: any) {
const userId = req.user?.id || req.user?.sub;
this.logger.log(`Proje siliniyor: ${id}`);
return this.projectsService.remove(userId, id);
}
/**
* AI ile senaryo üretimini tetikler.
*/
@Post(':id/generate-script')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: 'AI ile senaryo üret (Gemini)' })
@ApiResponse({ status: 200, description: 'Senaryo üretildi ve kaydedildi' })
async generateScript(@Param('id', ParseUUIDPipe) id: string, @Req() req: any) {
const userId = req.user?.id || req.user?.sub;
this.logger.log(`Senaryo üretimi başlatılıyor: ${id}`);
return this.projectsService.generateScript(userId, id);
}
/**
* Senaryoyu onaylar ve video üretim kuyruğuna gönderir.
*/
@Post(':id/approve')
@HttpCode(HttpStatus.ACCEPTED)
@ApiOperation({ summary: 'Senaryoyu onayla ve video üretimini başlat' })
@ApiResponse({ status: 202, description: 'Video üretimi kuyruğa eklendi' })
async approveAndStartGeneration(
@Param('id', ParseUUIDPipe) id: string,
@Req() req: any,
) {
const userId = req.user?.id || req.user?.sub;
this.logger.log(`Proje onaylanıyor ve kuyruğa gönderiliyor: ${id}`);
return this.projectsService.approveAndQueueGeneration(userId, id);
}
/**
* X/Twitter tweet URL'sinden otomatik proje oluşturur ve senaryo üretir.
* Tweet çekilir → prompt'a dönüştürülür → AI senaryo üretir → proje kaydedilir.
*/
@Post('from-tweet')
@HttpCode(HttpStatus.CREATED)
@ApiOperation({ summary: 'X/Twitter tweet\'ten proje oluştur' })
@ApiResponse({ status: 201, description: 'Tweet\'ten proje oluşturuldu ve senaryo üretildi' })
@ApiResponse({ status: 400, description: 'Geçersiz tweet URL\'si veya tweet bulunamadı' })
async createFromTweet(@Body() dto: CreateFromTweetDto, @Req() req: any) {
const userId = req.user?.id || req.user?.sub;
this.logger.log(`Tweet'ten proje oluşturuluyor: ${dto.tweetUrl}`);
return this.projectsService.createFromTweet(userId, dto);
}
}