import prisma from '../utils/db'; export class AssetService { public async createAsset(data: any) { const { sharedOrgIds, shares, tags, ...rest } = data; // Parse tags let parsedTags: string[] = []; if (Array.isArray(tags)) { parsedTags = tags; } else if (typeof tags === 'string' && tags.trim()) { try { parsedTags = JSON.parse(tags); } catch { parsedTags = tags.split(',').map((t: string) => t.trim()).filter(Boolean); } } const asset = await prisma.asset.create({ data: { ...rest, tags: parsedTags, } }); // Handle immediate sharing if (shares) { let parsedShares: any[] = []; if (Array.isArray(shares)) { parsedShares = shares; } else if (typeof shares === 'string' && shares.trim()) { try { parsedShares = JSON.parse(shares); } catch { parsedShares = shares.split(',').map((id: string) => ({ organizationId: id.trim(), userId: null })).filter(s => s.organizationId); } } if (parsedShares.length > 0) { await prisma.sharedAsset.createMany({ data: parsedShares.map(s => ({ assetId: asset.id, organizationId: s.organizationId, userId: s.userId || null, })), skipDuplicates: true, }); } } else if (sharedOrgIds) { let orgIds: string[] = []; if (Array.isArray(sharedOrgIds)) { orgIds = sharedOrgIds; } else if (typeof sharedOrgIds === 'string' && sharedOrgIds.trim()) { try { orgIds = JSON.parse(sharedOrgIds); } catch { orgIds = sharedOrgIds.split(',').map((id: string) => id.trim()).filter(Boolean); } } if (orgIds.length > 0) { await prisma.sharedAsset.createMany({ data: orgIds.map(orgId => ({ assetId: asset.id, organizationId: orgId, userId: null, })), skipDuplicates: true, }); } } return this.getAssetById(asset.id); } public async getAssets(userContext?: { role: string; userId: string }) { if (!userContext) { return []; } if (userContext.role === 'ADMIN') { return await prisma.asset.findMany({ include: { sharedWith: { include: { organization: { select: { id: true, name: true } }, user: { select: { id: true, email: true } } } }, downloadRequests: { include: { user: { select: { id: true, email: true } } } } }, orderBy: { createdAt: 'desc' } }); } // For clients/partners, find user organization first const user = await prisma.user.findUnique({ where: { id: userContext.userId } }); if (!user || !user.organizationId) { return []; } return await prisma.asset.findMany({ where: { status: 'published', sharedWith: { some: { organizationId: user.organizationId, OR: [ { userId: null }, { userId: user.id } ] } } }, include: { sharedWith: { include: { organization: { select: { id: true, name: true } }, user: { select: { id: true, email: true } } } }, downloadRequests: { where: { userId: userContext.userId } } }, orderBy: { createdAt: 'desc' } }); } public async getAssetById(id: string) { return await prisma.asset.findUnique({ where: { id }, include: { sharedWith: { include: { organization: { select: { id: true, name: true } }, user: { select: { id: true, email: true } } } }, downloadRequests: { include: { user: { select: { id: true, email: true } } } } } }); } public async updateAsset(id: string, data: any) { const { sharedOrgIds, shares, tags, ...rest } = data; const updateData: any = { ...rest }; if (tags !== undefined) { let parsedTags: string[] = []; if (Array.isArray(tags)) { parsedTags = tags; } else if (typeof tags === 'string') { try { parsedTags = JSON.parse(tags); } catch { parsedTags = tags.split(',').map((t: string) => t.trim()).filter(Boolean); } } updateData.tags = parsedTags; } await prisma.asset.update({ where: { id }, data: updateData }); if (shares !== undefined) { let parsedShares: any[] = []; if (Array.isArray(shares)) { parsedShares = shares; } else if (typeof shares === 'string') { try { parsedShares = JSON.parse(shares); } catch { parsedShares = shares.split(',').map((oid: string) => ({ organizationId: oid.trim(), userId: null })).filter(s => s.organizationId); } } await prisma.sharedAsset.deleteMany({ where: { assetId: id } }); if (parsedShares.length > 0) { await prisma.sharedAsset.createMany({ data: parsedShares.map(s => ({ assetId: id, organizationId: s.organizationId, userId: s.userId || null, })), skipDuplicates: true }); } } else if (sharedOrgIds !== undefined) { let orgIds: string[] = []; if (Array.isArray(sharedOrgIds)) { orgIds = sharedOrgIds; } else if (typeof sharedOrgIds === 'string') { try { orgIds = JSON.parse(sharedOrgIds); } catch { orgIds = sharedOrgIds.split(',').map((oid: string) => oid.trim()).filter(Boolean); } } await prisma.sharedAsset.deleteMany({ where: { assetId: id } }); if (orgIds.length > 0) { await prisma.sharedAsset.createMany({ data: orgIds.map(orgId => ({ assetId: id, organizationId: orgId, userId: null, })), skipDuplicates: true }); } } return this.getAssetById(id); } public async shareAsset(assetId: string, organizationIds: string[]) { await prisma.sharedAsset.createMany({ data: organizationIds.map(orgId => ({ assetId, organizationId: orgId, userId: null, })), skipDuplicates: true }); return this.getAssetById(assetId); } public async unshareAsset(assetId: string, organizationIds: string[]) { await prisma.sharedAsset.deleteMany({ where: { assetId, organizationId: { in: organizationIds }, userId: null } }); return this.getAssetById(assetId); } public async incrementDownloadCount(id: string) { return await prisma.asset.update({ where: { id }, data: { downloadsCount: { increment: 1 } } }); } public async deleteAsset(id: string) { return await prisma.asset.delete({ where: { id } }); } // Download Requests Access Methods public async requestDownload(assetId: string, userId: string) { const existing = await prisma.downloadRequest.findFirst({ where: { assetId, userId } }); if (existing) { return await prisma.downloadRequest.update({ where: { id: existing.id }, data: { status: 'PENDING' } }); } return await prisma.downloadRequest.create({ data: { assetId, userId, status: 'PENDING' } }); } public async approveDownloadRequest(requestId: string) { return await prisma.downloadRequest.update({ where: { id: requestId }, data: { status: 'APPROVED' } }); } public async rejectDownloadRequest(requestId: string) { return await prisma.downloadRequest.update({ where: { id: requestId }, data: { status: 'REJECTED' } }); } }