Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | 33x 8x 8x 1x 7x 7x 1x 6x 1x 5x 1x 4x 1x 3x 3x 3x 8x 8x 2x 6x 1x 5x 1x 4x 1x 3x 3x 1x 2x 4x 4x 2x 2x | // Leadership Service - Leadership team management
import type { Dal } from "../../dal";
import type { ProLeadership } from "../../db/schema";
import type { AddLeadershipInput, UpdateLeadershipInput } from "./types";
import { NotFoundError, ValidationError } from "../../lib/errors";
export class LeadershipService {
constructor(private dal: Dal) {}
async addLeadershipMember(
proId: string,
data: AddLeadershipInput,
): Promise<ProLeadership> {
// Verify pro exists
const pro = await this.dal.pros.findById(proId);
if (!pro) {
throw new NotFoundError("Pro not found");
}
// Check max limit (5 members)
const count = await this.dal.companyProfile.countLeadership(proId);
if (count >= 5) {
throw new ValidationError("You can add up to 5 team members");
}
// Validate fields
if (!data.name || data.name.length > 100) {
throw new ValidationError("Name is required (max 100 characters)");
}
if (!data.role || data.role.length > 50) {
throw new ValidationError("Role is required (max 50 characters)");
}
if (data.bio && data.bio.length > 300) {
throw new ValidationError("Bio must be 300 characters or less");
}
const maxOrder =
await this.dal.companyProfile.getMaxLeadershipOrder(proId);
const member = await this.dal.companyProfile.createLeadership({
proId,
name: data.name,
role: data.role,
bio: data.bio,
photoUrl: data.photoUrl,
linkedinUrl: data.linkedinUrl,
instagramHandle: data.instagramHandle,
videoUrl: data.videoUrl,
displayOrder: maxOrder + 1,
});
return member;
}
async updateLeadershipMember(
proId: string,
memberId: number,
data: UpdateLeadershipInput,
): Promise<ProLeadership> {
const member = await this.dal.companyProfile.getLeadershipById(memberId);
if (!member || member.proId !== proId) {
throw new NotFoundError("Team member not found");
}
// Validate fields
if (data.name !== undefined && (!data.name || data.name.length > 100)) {
throw new ValidationError("Name is required (max 100 characters)");
}
if (data.role !== undefined && (!data.role || data.role.length > 50)) {
throw new ValidationError("Role is required (max 50 characters)");
}
if (data.bio && data.bio.length > 300) {
throw new ValidationError("Bio must be 300 characters or less");
}
const updated = await this.dal.companyProfile.updateLeadership(
memberId,
data,
);
if (!updated) {
throw new NotFoundError("Team member not found");
}
return updated;
}
async deleteLeadershipMember(
proId: string,
memberId: number,
): Promise<void> {
const member = await this.dal.companyProfile.getLeadershipById(memberId);
if (!member || member.proId !== proId) {
throw new NotFoundError("Team member not found");
}
await this.dal.companyProfile.deleteLeadership(memberId);
}
}
|