flwo / apps /server /src /modules /projects /projects.service.js
moustafa7's picture
feat: complete admin/client pages - orders, templates, projects, fields, versions, users, deployments
db2ddc0
Raw History Blame Contribute Delete
7.03 kB
import { prisma } from '../../config/database.js'
import { AppError } from '../../lib/AppError.js'
import { config } from '../../config/index.js'
export async function getProject(orderId, userId) {
const order = await prisma.order.findUnique({
where: { id: orderId },
select: { userId: true },
})
if (!order) throw new AppError('الطلب غير موجود', 404, 'ORDER_NOT_FOUND')
if (order.userId !== userId) throw new AppError('ليس لديك صلاحية', 403, 'FORBIDDEN')
const project = await prisma.customerProject.findUnique({
where: { orderId },
include: {
template: {
select: {
id: true, title: true, previewUrl: true, sourceUrl: true,
sourceFile: true, manifest: true,
versions: { where: { isCurrent: true }, take: 1, select: { version: true } },
},
},
},
})
if (!project) throw new AppError('المشروع غير موجود', 404, 'PROJECT_NOT_FOUND')
return project
}
export async function createProject(orderId, userId, templateId) {
const order = await prisma.order.findUnique({
where: { id: orderId },
select: { userId: true, status: true },
})
if (!order) throw new AppError('الطلب غير موجود', 404, 'ORDER_NOT_FOUND')
if (order.userId !== userId) throw new AppError('ليس لديك صلاحية', 403, 'FORBIDDEN')
if (order.status !== 'COMPLETED') throw new AppError('الطلب لم يكتمل بعد', 400, 'ORDER_NOT_COMPLETED')
const existing = await prisma.customerProject.findUnique({ where: { orderId } })
if (existing) throw new AppError('المشروع موجود بالفعل', 409, 'PROJECT_EXISTS')
const currentVersion = await prisma.templateVersion.findFirst({
where: { templateId, isCurrent: true },
select: { version: true },
})
return prisma.customerProject.create({
data: {
orderId, userId, templateId, config: {},
currentVersion: currentVersion?.version || null,
},
include: { template: { select: { id: true, title: true, previewUrl: true } } },
})
}
export async function updateConfig(orderId, userId, config) {
const project = await prisma.customerProject.findUnique({
where: { orderId },
select: { id: true, userId: true },
})
if (!project) throw new AppError('المشروع غير موجود', 404, 'PROJECT_NOT_FOUND')
if (project.userId !== userId) throw new AppError('ليس لديك صلاحية', 403, 'FORBIDDEN')
return prisma.customerProject.update({
where: { id: project.id },
data: { config },
include: { template: { select: { id: true, title: true, previewUrl: true, manifest: true } } },
})
}
export async function updateUrls(orderId, userId, data) {
const project = await prisma.customerProject.findUnique({
where: { orderId },
select: { id: true, userId: true },
})
if (!project) throw new AppError('المشروع غير موجود', 404, 'PROJECT_NOT_FOUND')
if (project.userId !== userId) throw new AppError('ليس لديك صلاحية', 403, 'FORBIDDEN')
return prisma.customerProject.update({
where: { id: project.id },
data,
include: { template: { select: { id: true, title: true, previewUrl: true } } },
})
}
export async function getSourceFile(orderId, userId) {
const order = await prisma.order.findUnique({
where: { id: orderId },
select: { userId: true },
})
if (!order) throw new AppError('الطلب غير موجود', 404, 'ORDER_NOT_FOUND')
if (order.userId !== userId) throw new AppError('ليس لديك صلاحية', 403, 'FORBIDDEN')
const project = await prisma.customerProject.findUnique({
where: { orderId },
include: { template: { select: { id: true, title: true, sourceFile: true, sourceUrl: true } } },
})
if (!project) throw new AppError('المشروع غير موجود', 404, 'PROJECT_NOT_FOUND')
const template = project.template
if (!template.sourceFile) throw new AppError('ملف المصدر غير متاح', 404, 'SOURCE_NOT_FOUND')
return { filePath: template.sourceFile, templateTitle: template.title }
}
export async function checkForUpdate(orderId, userId) {
const order = await prisma.order.findUnique({
where: { id: orderId },
select: { userId: true },
})
if (!order) throw new AppError('الطلب غير موجود', 404, 'ORDER_NOT_FOUND')
if (order.userId !== userId) throw new AppError('ليس لديك صلاحية', 403, 'FORBIDDEN')
const project = await prisma.customerProject.findUnique({
where: { orderId },
select: { currentVersion: true },
})
if (!project) throw new AppError('المشروع غير موجود', 404, 'PROJECT_NOT_FOUND')
const orderWithTemplate = await prisma.order.findUnique({
where: { id: orderId },
select: { templateId: true },
})
const latest = await prisma.templateVersion.findFirst({
where: { templateId: orderWithTemplate.templateId, channel: 'stable' },
orderBy: { createdAt: 'desc' },
select: { version: true, changelog: true, createdAt: true },
})
if (!latest) return { updateAvailable: false, currentVersion: project.currentVersion, latestVersion: null }
const updateAvailable = project.currentVersion !== latest.version
return {
updateAvailable,
currentVersion: project.currentVersion,
latestVersion: latest.version,
changelog: latest.changelog,
releasedAt: latest.createdAt,
}
}
export async function applyTemplateUpdate(orderId, userId) {
const order = await prisma.order.findUnique({
where: { id: orderId },
select: { userId: true, templateId: true },
})
if (!order) throw new AppError('الطلب غير موجود', 404, 'ORDER_NOT_FOUND')
if (order.userId !== userId) throw new AppError('ليس لديك صلاحية', 403, 'FORBIDDEN')
const latest = await prisma.templateVersion.findFirst({
where: { templateId: order.templateId, channel: 'stable' },
orderBy: { createdAt: 'desc' },
select: { version: true },
})
if (!latest) throw new AppError('لا توجد إصدارات متاحة', 404, 'NO_VERSIONS')
const project = await prisma.customerProject.findUnique({
where: { orderId },
select: { id: true, currentVersion: true },
})
if (!project) throw new AppError('المشروع غير موجود', 404, 'PROJECT_NOT_FOUND')
if (project.currentVersion === latest.version) throw new AppError('المشروع بالفعل على أحدث إصدار', 400, 'ALREADY_UPDATED')
return prisma.customerProject.update({
where: { id: project.id },
data: { currentVersion: latest.version, updateStatus: 'up_to_date', availableVersion: null },
include: { template: { select: { id: true, title: true } } },
})
}
export async function generatePreviewUrl(orderId, userId) {
const project = await getProject(orderId, userId)
const baseUrl = config.FRONTEND_URL || ''
const params = new URLSearchParams({ config: JSON.stringify(project.config) })
return `${baseUrl}/api/preview/${project.templateId}?${params.toString()}`
}