138 lines
2.9 KiB
TypeScript
138 lines
2.9 KiB
TypeScript
// src/services/project.ts
|
|
// Copyright (C) 2025 DTP Technologies, LLC
|
|
// All Rights Reserved
|
|
|
|
import { Project } from "../models/project.js";
|
|
import { DtpService } from "../lib/service.js";
|
|
|
|
export interface IProjectListItem {
|
|
id: string;
|
|
name: string;
|
|
slug: string;
|
|
gitUrl?: string;
|
|
createdAt: Date;
|
|
}
|
|
|
|
export interface IProjectCreateInput {
|
|
name: string;
|
|
slug: string;
|
|
gitUrl?: string;
|
|
}
|
|
|
|
export interface IProjectUpdateInput {
|
|
name?: string;
|
|
slug?: string;
|
|
gitUrl?: string;
|
|
}
|
|
|
|
export class ProjectService extends DtpService {
|
|
get name(): string {
|
|
return "ProjectService";
|
|
}
|
|
get slug(): string {
|
|
return "project";
|
|
}
|
|
|
|
async start(): Promise<void> {
|
|
this.log.info("service started");
|
|
}
|
|
|
|
async stop(): Promise<void> {
|
|
this.log.info("service stopped");
|
|
}
|
|
|
|
async listByUser(userId: string): Promise<IProjectListItem[]> {
|
|
const projects = await Project.find({ user: userId })
|
|
.sort({ createdAt: -1 })
|
|
.lean();
|
|
|
|
return projects.map((p) => ({
|
|
id: p._id.toString(),
|
|
name: p.name,
|
|
slug: p.slug,
|
|
gitUrl: p.gitUrl,
|
|
createdAt: p.createdAt,
|
|
}));
|
|
}
|
|
|
|
async getById(projectId: string, userId: string): Promise<IProjectListItem | null> {
|
|
const project = await Project.findOne({
|
|
_id: projectId,
|
|
user: userId,
|
|
}).lean();
|
|
|
|
if (!project) {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
id: project._id.toString(),
|
|
name: project.name,
|
|
slug: project.slug,
|
|
gitUrl: project.gitUrl,
|
|
createdAt: project.createdAt,
|
|
};
|
|
}
|
|
|
|
async create(userId: string, input: IProjectCreateInput): Promise<IProjectListItem> {
|
|
const project = new Project({
|
|
user: userId,
|
|
name: input.name,
|
|
slug: input.slug,
|
|
gitUrl: input.gitUrl,
|
|
});
|
|
|
|
await project.save();
|
|
this.log.info("Project created", { projectId: project._id, slug: project.slug });
|
|
|
|
return {
|
|
id: project._id.toString(),
|
|
name: project.name,
|
|
slug: project.slug,
|
|
gitUrl: project.gitUrl,
|
|
createdAt: project.createdAt,
|
|
};
|
|
}
|
|
|
|
async update(
|
|
projectId: string,
|
|
userId: string,
|
|
input: IProjectUpdateInput,
|
|
): Promise<IProjectListItem | null> {
|
|
const project = await Project.findOneAndUpdate(
|
|
{ _id: projectId, user: userId },
|
|
input,
|
|
{ new: true },
|
|
).lean();
|
|
|
|
if (!project) {
|
|
return null;
|
|
}
|
|
|
|
this.log.info("Project updated", { projectId: project._id });
|
|
|
|
return {
|
|
id: project._id.toString(),
|
|
name: project.name,
|
|
slug: project.slug,
|
|
gitUrl: project.gitUrl,
|
|
createdAt: project.createdAt,
|
|
};
|
|
}
|
|
|
|
async delete(projectId: string, userId: string): Promise<boolean> {
|
|
const result = await Project.deleteOne({
|
|
_id: projectId,
|
|
user: userId,
|
|
});
|
|
|
|
if (result.deletedCount === 0) {
|
|
return false;
|
|
}
|
|
|
|
this.log.info("Project deleted", { projectId, userId });
|
|
return true;
|
|
}
|
|
}
|
|
|
|
export default new ProjectService(); |