feat(tags): add input validation for tag and entity operations
Added validation checks for tagId, personId, and projectId across tag-related operations. Introduced `BadRequestException` for invalid or missing inputs. Replaced generic errors with more descriptive exceptions.
This commit is contained in:
parent
d48b6fa48b
commit
5abd33e648
@ -1,4 +1,4 @@
|
|||||||
import { Injectable, NotFoundException, Inject } from '@nestjs/common';
|
import { Injectable, NotFoundException, Inject, BadRequestException } from '@nestjs/common';
|
||||||
import { eq, and } from 'drizzle-orm';
|
import { eq, and } from 'drizzle-orm';
|
||||||
import { DRIZZLE } from '../../../database/database.module';
|
import { DRIZZLE } from '../../../database/database.module';
|
||||||
import * as schema from '../../../database/schema';
|
import * as schema from '../../../database/schema';
|
||||||
@ -47,11 +47,11 @@ export class TagsService {
|
|||||||
.select()
|
.select()
|
||||||
.from(schema.tags)
|
.from(schema.tags)
|
||||||
.where(eq(schema.tags.id, id));
|
.where(eq(schema.tags.id, id));
|
||||||
|
|
||||||
if (!tag) {
|
if (!tag) {
|
||||||
throw new NotFoundException(`Tag with ID ${id} not found`);
|
throw new NotFoundException(`Tag with ID ${id} not found`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,11 +67,11 @@ export class TagsService {
|
|||||||
})
|
})
|
||||||
.where(eq(schema.tags.id, id))
|
.where(eq(schema.tags.id, id))
|
||||||
.returning();
|
.returning();
|
||||||
|
|
||||||
if (!tag) {
|
if (!tag) {
|
||||||
throw new NotFoundException(`Tag with ID ${id} not found`);
|
throw new NotFoundException(`Tag with ID ${id} not found`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,11 +83,11 @@ export class TagsService {
|
|||||||
.delete(schema.tags)
|
.delete(schema.tags)
|
||||||
.where(eq(schema.tags.id, id))
|
.where(eq(schema.tags.id, id))
|
||||||
.returning();
|
.returning();
|
||||||
|
|
||||||
if (!tag) {
|
if (!tag) {
|
||||||
throw new NotFoundException(`Tag with ID ${id} not found`);
|
throw new NotFoundException(`Tag with ID ${id} not found`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,22 +95,30 @@ export class TagsService {
|
|||||||
* Add a tag to a person
|
* Add a tag to a person
|
||||||
*/
|
*/
|
||||||
async addTagToPerson(tagId: string, personId: string) {
|
async addTagToPerson(tagId: string, personId: string) {
|
||||||
|
// Validate tagId and personId
|
||||||
|
if (!tagId) {
|
||||||
|
throw new BadRequestException('Tag ID is required');
|
||||||
|
}
|
||||||
|
if (!personId) {
|
||||||
|
throw new BadRequestException('Person ID is required');
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the tag exists and is of type PERSON
|
// Check if the tag exists and is of type PERSON
|
||||||
const tag = await this.findById(tagId);
|
const tag = await this.findById(tagId);
|
||||||
if (tag.type !== 'PERSON') {
|
if (tag.type !== 'PERSON') {
|
||||||
throw new Error(`Tag with ID ${tagId} is not of type PERSON`);
|
throw new BadRequestException(`Tag with ID ${tagId} is not of type PERSON`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the person exists
|
// Check if the person exists
|
||||||
const [person] = await this.db
|
const [person] = await this.db
|
||||||
.select()
|
.select()
|
||||||
.from(schema.persons)
|
.from(schema.persons)
|
||||||
.where(eq(schema.persons.id, personId));
|
.where(eq(schema.persons.id, personId));
|
||||||
|
|
||||||
if (!person) {
|
if (!person) {
|
||||||
throw new NotFoundException(`Person with ID ${personId} not found`);
|
throw new NotFoundException(`Person with ID ${personId} not found`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the tag is already associated with the person
|
// Check if the tag is already associated with the person
|
||||||
const [existingRelation] = await this.db
|
const [existingRelation] = await this.db
|
||||||
.select()
|
.select()
|
||||||
@ -121,11 +129,11 @@ export class TagsService {
|
|||||||
eq(schema.personToTag.tagId, tagId)
|
eq(schema.personToTag.tagId, tagId)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (existingRelation) {
|
if (existingRelation) {
|
||||||
return existingRelation;
|
return existingRelation;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the tag to the person
|
// Add the tag to the person
|
||||||
const [relation] = await this.db
|
const [relation] = await this.db
|
||||||
.insert(schema.personToTag)
|
.insert(schema.personToTag)
|
||||||
@ -134,7 +142,7 @@ export class TagsService {
|
|||||||
tagId,
|
tagId,
|
||||||
})
|
})
|
||||||
.returning();
|
.returning();
|
||||||
|
|
||||||
return relation;
|
return relation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +150,14 @@ export class TagsService {
|
|||||||
* Remove a tag from a person
|
* Remove a tag from a person
|
||||||
*/
|
*/
|
||||||
async removeTagFromPerson(tagId: string, personId: string) {
|
async removeTagFromPerson(tagId: string, personId: string) {
|
||||||
|
// Validate tagId and personId
|
||||||
|
if (!tagId) {
|
||||||
|
throw new BadRequestException('Tag ID is required');
|
||||||
|
}
|
||||||
|
if (!personId) {
|
||||||
|
throw new BadRequestException('Person ID is required');
|
||||||
|
}
|
||||||
|
|
||||||
const [relation] = await this.db
|
const [relation] = await this.db
|
||||||
.delete(schema.personToTag)
|
.delete(schema.personToTag)
|
||||||
.where(
|
.where(
|
||||||
@ -151,11 +167,11 @@ export class TagsService {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
.returning();
|
.returning();
|
||||||
|
|
||||||
if (!relation) {
|
if (!relation) {
|
||||||
throw new NotFoundException(`Tag with ID ${tagId} is not associated with person with ID ${personId}`);
|
throw new NotFoundException(`Tag with ID ${tagId} is not associated with person with ID ${personId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return relation;
|
return relation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,22 +179,30 @@ export class TagsService {
|
|||||||
* Add a tag to a project
|
* Add a tag to a project
|
||||||
*/
|
*/
|
||||||
async addTagToProject(tagId: string, projectId: string) {
|
async addTagToProject(tagId: string, projectId: string) {
|
||||||
|
// Validate tagId and projectId
|
||||||
|
if (!tagId) {
|
||||||
|
throw new BadRequestException('Tag ID is required');
|
||||||
|
}
|
||||||
|
if (!projectId) {
|
||||||
|
throw new BadRequestException('Project ID is required');
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the tag exists and is of type PROJECT
|
// Check if the tag exists and is of type PROJECT
|
||||||
const tag = await this.findById(tagId);
|
const tag = await this.findById(tagId);
|
||||||
if (tag.type !== 'PROJECT') {
|
if (tag.type !== 'PROJECT') {
|
||||||
throw new Error(`Tag with ID ${tagId} is not of type PROJECT`);
|
throw new BadRequestException(`Tag with ID ${tagId} is not of type PROJECT`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the project exists
|
// Check if the project exists
|
||||||
const [project] = await this.db
|
const [project] = await this.db
|
||||||
.select()
|
.select()
|
||||||
.from(schema.projects)
|
.from(schema.projects)
|
||||||
.where(eq(schema.projects.id, projectId));
|
.where(eq(schema.projects.id, projectId));
|
||||||
|
|
||||||
if (!project) {
|
if (!project) {
|
||||||
throw new NotFoundException(`Project with ID ${projectId} not found`);
|
throw new NotFoundException(`Project with ID ${projectId} not found`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the tag is already associated with the project
|
// Check if the tag is already associated with the project
|
||||||
const [existingRelation] = await this.db
|
const [existingRelation] = await this.db
|
||||||
.select()
|
.select()
|
||||||
@ -189,11 +213,11 @@ export class TagsService {
|
|||||||
eq(schema.projectToTag.tagId, tagId)
|
eq(schema.projectToTag.tagId, tagId)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (existingRelation) {
|
if (existingRelation) {
|
||||||
return existingRelation;
|
return existingRelation;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the tag to the project
|
// Add the tag to the project
|
||||||
const [relation] = await this.db
|
const [relation] = await this.db
|
||||||
.insert(schema.projectToTag)
|
.insert(schema.projectToTag)
|
||||||
@ -202,7 +226,7 @@ export class TagsService {
|
|||||||
tagId,
|
tagId,
|
||||||
})
|
})
|
||||||
.returning();
|
.returning();
|
||||||
|
|
||||||
return relation;
|
return relation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,6 +234,14 @@ export class TagsService {
|
|||||||
* Remove a tag from a project
|
* Remove a tag from a project
|
||||||
*/
|
*/
|
||||||
async removeTagFromProject(tagId: string, projectId: string) {
|
async removeTagFromProject(tagId: string, projectId: string) {
|
||||||
|
// Validate tagId and projectId
|
||||||
|
if (!tagId) {
|
||||||
|
throw new BadRequestException('Tag ID is required');
|
||||||
|
}
|
||||||
|
if (!projectId) {
|
||||||
|
throw new BadRequestException('Project ID is required');
|
||||||
|
}
|
||||||
|
|
||||||
const [relation] = await this.db
|
const [relation] = await this.db
|
||||||
.delete(schema.projectToTag)
|
.delete(schema.projectToTag)
|
||||||
.where(
|
.where(
|
||||||
@ -219,11 +251,11 @@ export class TagsService {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
.returning();
|
.returning();
|
||||||
|
|
||||||
if (!relation) {
|
if (!relation) {
|
||||||
throw new NotFoundException(`Tag with ID ${tagId} is not associated with project with ID ${projectId}`);
|
throw new NotFoundException(`Tag with ID ${tagId} is not associated with project with ID ${projectId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return relation;
|
return relation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,16 +263,21 @@ export class TagsService {
|
|||||||
* Get all tags for a person
|
* Get all tags for a person
|
||||||
*/
|
*/
|
||||||
async getTagsForPerson(personId: string) {
|
async getTagsForPerson(personId: string) {
|
||||||
|
// Validate personId
|
||||||
|
if (!personId) {
|
||||||
|
throw new BadRequestException('Person ID is required');
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the person exists
|
// Check if the person exists
|
||||||
const [person] = await this.db
|
const [person] = await this.db
|
||||||
.select()
|
.select()
|
||||||
.from(schema.persons)
|
.from(schema.persons)
|
||||||
.where(eq(schema.persons.id, personId));
|
.where(eq(schema.persons.id, personId));
|
||||||
|
|
||||||
if (!person) {
|
if (!person) {
|
||||||
throw new NotFoundException(`Person with ID ${personId} not found`);
|
throw new NotFoundException(`Person with ID ${personId} not found`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all tags for the person
|
// Get all tags for the person
|
||||||
return this.db
|
return this.db
|
||||||
.select({
|
.select({
|
||||||
@ -255,16 +292,21 @@ export class TagsService {
|
|||||||
* Get all tags for a project
|
* Get all tags for a project
|
||||||
*/
|
*/
|
||||||
async getTagsForProject(projectId: string) {
|
async getTagsForProject(projectId: string) {
|
||||||
|
// Validate projectId
|
||||||
|
if (!projectId) {
|
||||||
|
throw new BadRequestException('Project ID is required');
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the project exists
|
// Check if the project exists
|
||||||
const [project] = await this.db
|
const [project] = await this.db
|
||||||
.select()
|
.select()
|
||||||
.from(schema.projects)
|
.from(schema.projects)
|
||||||
.where(eq(schema.projects.id, projectId));
|
.where(eq(schema.projects.id, projectId));
|
||||||
|
|
||||||
if (!project) {
|
if (!project) {
|
||||||
throw new NotFoundException(`Project with ID ${projectId} not found`);
|
throw new NotFoundException(`Project with ID ${projectId} not found`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all tags for the project
|
// Get all tags for the project
|
||||||
return this.db
|
return this.db
|
||||||
.select({
|
.select({
|
||||||
@ -274,4 +316,4 @@ export class TagsService {
|
|||||||
.innerJoin(schema.tags, eq(schema.projectToTag.tagId, schema.tags.id))
|
.innerJoin(schema.tags, eq(schema.projectToTag.tagId, schema.tags.id))
|
||||||
.where(eq(schema.projectToTag.projectId, projectId));
|
.where(eq(schema.projectToTag.projectId, projectId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user