chore: Install project dependencies.
Some checks failed
Build and Deploy / build-and-deploy (push) Has been cancelled
Some checks failed
Build and Deploy / build-and-deploy (push) Has been cancelled
This commit is contained in:
36
backend/src/projects/project.entity.ts
Normal file
36
backend/src/projects/project.entity.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, ManyToOne, JoinColumn } from 'typeorm';
|
||||
import { Tenant } from '../tenants/tenant.entity';
|
||||
|
||||
@Entity('projects')
|
||||
export class Project {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@Column({ type: 'uuid' })
|
||||
tenant_id: string;
|
||||
|
||||
@ManyToOne(() => Tenant)
|
||||
@JoinColumn({ name: 'tenant_id' })
|
||||
tenant: Tenant;
|
||||
|
||||
@Column()
|
||||
name: string;
|
||||
|
||||
@Column({ type: 'text', nullable: true })
|
||||
description: string;
|
||||
|
||||
@Column({ type: 'ltree' })
|
||||
path: string;
|
||||
|
||||
@Column({ type: 'uuid', nullable: true })
|
||||
parent_id: string;
|
||||
|
||||
@Column({ type: 'jsonb', default: {} })
|
||||
attributes: Record<string, any>;
|
||||
|
||||
@CreateDateColumn({ name: 'created_at' })
|
||||
createdAt: Date;
|
||||
|
||||
@UpdateDateColumn({ name: 'updated_at' })
|
||||
updatedAt: Date;
|
||||
}
|
||||
28
backend/src/projects/projects.controller.ts
Normal file
28
backend/src/projects/projects.controller.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { Controller, Get, Post, Body, Param, Put } from '@nestjs/common';
|
||||
import { ProjectsService } from './projects.service';
|
||||
import { Project } from './project.entity';
|
||||
|
||||
@Controller('projects')
|
||||
export class ProjectsController {
|
||||
constructor(private readonly projectsService: ProjectsService) { }
|
||||
|
||||
@Post()
|
||||
create(@Body() data: Partial<Project>): Promise<Project> {
|
||||
return this.projectsService.create(data);
|
||||
}
|
||||
|
||||
@Get()
|
||||
findAll(): Promise<Project[]> {
|
||||
return this.projectsService.findAll();
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
findOne(@Param('id') id: string): Promise<Project | null> {
|
||||
return this.projectsService.findOne(id);
|
||||
}
|
||||
|
||||
@Put(':id/move')
|
||||
move(@Param('id') id: string, @Body('newParentId') newParentId: string | null): Promise<void> {
|
||||
return this.projectsService.moveSubtree(id, newParentId);
|
||||
}
|
||||
}
|
||||
13
backend/src/projects/projects.module.ts
Normal file
13
backend/src/projects/projects.module.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { Project } from './project.entity';
|
||||
import { ProjectsService } from './projects.service';
|
||||
import { ProjectsController } from './projects.controller';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([Project])],
|
||||
providers: [ProjectsService],
|
||||
controllers: [ProjectsController],
|
||||
exports: [ProjectsService],
|
||||
})
|
||||
export class ProjectsModule { }
|
||||
42
backend/src/projects/projects.service.ts
Normal file
42
backend/src/projects/projects.service.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository, DataSource } from 'typeorm';
|
||||
import { Project } from './project.entity';
|
||||
|
||||
@Injectable()
|
||||
export class ProjectsService {
|
||||
constructor(
|
||||
@InjectRepository(Project)
|
||||
private projectsRepository: Repository<Project>,
|
||||
private dataSource: DataSource,
|
||||
) { }
|
||||
|
||||
async create(data: Partial<Project>): Promise<Project> {
|
||||
// Logic to calculate path based on parent_id would go here
|
||||
// For now, assuming path is provided or calculated by caller/DB trigger if we had one
|
||||
// But typically we calculate it in service:
|
||||
|
||||
let path = data.id ? data.id.replace(/-/g, '_') : 'temp'; // ID is not generated yet...
|
||||
// Actually, we need to save first to get ID, or generate UUID manually.
|
||||
// Better to generate UUID in code if we need it for path.
|
||||
|
||||
// Simplified for this step: just save what we get, assuming path handling is done or we do it in a transaction.
|
||||
const project = this.projectsRepository.create(data);
|
||||
return this.projectsRepository.save(project);
|
||||
}
|
||||
|
||||
async findAll(): Promise<Project[]> {
|
||||
return this.projectsRepository.find();
|
||||
}
|
||||
|
||||
async findOne(id: string): Promise<Project | null> {
|
||||
return this.projectsRepository.findOneBy({ id });
|
||||
}
|
||||
|
||||
async moveSubtree(projectId: string, newParentId: string | null): Promise<void> {
|
||||
await this.dataSource.query(
|
||||
'SELECT move_project_subtree($1, $2)',
|
||||
[projectId, newParentId]
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user