317 lines
8.1 KiB
TypeScript
317 lines
8.1 KiB
TypeScript
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' }
|
|
});
|
|
}
|
|
}
|