feat: add wiki, metadata, and task management
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:
@@ -5,6 +5,8 @@ import { TenantsModule } from './tenants/tenants.module';
|
||||
import { ProjectsModule } from './projects/projects.module';
|
||||
import { Tenant } from './tenants/tenant.entity';
|
||||
import { Project } from './projects/project.entity';
|
||||
import { Task } from './tasks/task.entity';
|
||||
import { TasksModule } from './tasks/tasks.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -16,11 +18,12 @@ import { Project } from './projects/project.entity';
|
||||
username: process.env.DB_USERNAME || 'postgres',
|
||||
password: process.env.DB_PASSWORD || 'postgres',
|
||||
database: process.env.DB_DATABASE || 'evrak',
|
||||
entities: [Tenant, Project],
|
||||
synchronize: false, // Schema is managed by SQL migration files
|
||||
entities: [Tenant, Project, Task],
|
||||
synchronize: true, // Enabled for development
|
||||
}),
|
||||
TenantsModule,
|
||||
ProjectsModule,
|
||||
TasksModule,
|
||||
],
|
||||
})
|
||||
export class AppModule { }
|
||||
|
||||
@@ -19,6 +19,9 @@ export class Project {
|
||||
@Column({ type: 'text', nullable: true })
|
||||
description: string;
|
||||
|
||||
@Column({ type: 'text', nullable: true })
|
||||
wiki_content: string;
|
||||
|
||||
@Column({ type: 'ltree' })
|
||||
path: string;
|
||||
|
||||
|
||||
44
backend/src/tasks/task.entity.ts
Normal file
44
backend/src/tasks/task.entity.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, ManyToOne, JoinColumn } from 'typeorm';
|
||||
import { Project } from '../projects/project.entity';
|
||||
import { Tenant } from '../tenants/tenant.entity';
|
||||
|
||||
@Entity('tasks')
|
||||
export class Task {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@Column({ type: 'uuid' })
|
||||
tenant_id: string;
|
||||
|
||||
@ManyToOne(() => Tenant)
|
||||
@JoinColumn({ name: 'tenant_id' })
|
||||
tenant: Tenant;
|
||||
|
||||
@Column({ type: 'uuid' })
|
||||
project_id: string;
|
||||
|
||||
@ManyToOne(() => Project)
|
||||
@JoinColumn({ name: 'project_id' })
|
||||
project: Project;
|
||||
|
||||
@Column()
|
||||
title: string;
|
||||
|
||||
@Column({ type: 'text', nullable: true })
|
||||
description: string;
|
||||
|
||||
@Column({ default: 'todo' })
|
||||
status: string; // todo, in_progress, done
|
||||
|
||||
@Column({ default: 'medium' })
|
||||
priority: string; // low, medium, high
|
||||
|
||||
@Column({ type: 'timestamp', nullable: true })
|
||||
due_date: Date;
|
||||
|
||||
@CreateDateColumn({ name: 'created_at' })
|
||||
createdAt: Date;
|
||||
|
||||
@UpdateDateColumn({ name: 'updated_at' })
|
||||
updatedAt: Date;
|
||||
}
|
||||
29
backend/src/tasks/tasks.controller.ts
Normal file
29
backend/src/tasks/tasks.controller.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { Controller, Get, Post, Body, Patch, Param, Delete, UseGuards, Query } from '@nestjs/common';
|
||||
import { TasksService } from './tasks.service';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
|
||||
@Controller('tasks')
|
||||
@UseGuards(AuthGuard('jwt'))
|
||||
export class TasksController {
|
||||
constructor(private readonly tasksService: TasksService) { }
|
||||
|
||||
@Get()
|
||||
findAll(@Query('projectId') projectId: string) {
|
||||
return this.tasksService.findAll(projectId);
|
||||
}
|
||||
|
||||
@Post()
|
||||
create(@Body() createTaskDto: any) {
|
||||
return this.tasksService.create(createTaskDto);
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
update(@Param('id') id: string, @Body() updateTaskDto: any) {
|
||||
return this.tasksService.update(id, updateTaskDto);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
remove(@Param('id') id: string) {
|
||||
return this.tasksService.remove(id);
|
||||
}
|
||||
}
|
||||
12
backend/src/tasks/tasks.module.ts
Normal file
12
backend/src/tasks/tasks.module.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { TasksService } from './tasks.service';
|
||||
import { TasksController } from './tasks.controller';
|
||||
import { Task } from './task.entity';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([Task])],
|
||||
controllers: [TasksController],
|
||||
providers: [TasksService],
|
||||
})
|
||||
export class TasksModule { }
|
||||
49
backend/src/tasks/tasks.service.ts
Normal file
49
backend/src/tasks/tasks.service.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { Injectable, Inject, Scope } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { Task } from './task.entity';
|
||||
import { REQUEST } from '@nestjs/core';
|
||||
import { Request } from 'express';
|
||||
|
||||
@Injectable({ scope: Scope.REQUEST })
|
||||
export class TasksService {
|
||||
constructor(
|
||||
@InjectRepository(Task)
|
||||
private tasksRepository: Repository<Task>,
|
||||
@Inject(REQUEST) private request: Request,
|
||||
) { }
|
||||
|
||||
private getTenantId(): string {
|
||||
const user = (this.request as any).user;
|
||||
return user.tenantId;
|
||||
}
|
||||
|
||||
async findAll(projectId: string): Promise<Task[]> {
|
||||
return this.tasksRepository.find({
|
||||
where: {
|
||||
project_id: projectId,
|
||||
tenant_id: this.getTenantId()
|
||||
},
|
||||
order: { createdAt: 'DESC' }
|
||||
});
|
||||
}
|
||||
|
||||
async create(createTaskDto: any): Promise<Task> {
|
||||
return this.tasksRepository.save({
|
||||
...createTaskDto,
|
||||
tenant_id: this.getTenantId()
|
||||
});
|
||||
}
|
||||
|
||||
async update(id: string, updateTaskDto: any): Promise<Task | null> {
|
||||
await this.tasksRepository.update(
|
||||
{ id, tenant_id: this.getTenantId() },
|
||||
updateTaskDto
|
||||
);
|
||||
return this.tasksRepository.findOne({ where: { id, tenant_id: this.getTenantId() } });
|
||||
}
|
||||
|
||||
async remove(id: string): Promise<void> {
|
||||
await this.tasksRepository.delete({ id, tenant_id: this.getTenantId() });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user