team -> ts

This commit is contained in:
Alex Holliday
2026-01-21 11:46:49 -08:00
parent 9fa0113f2b
commit 36e02e0a9a
10 changed files with 110 additions and 21 deletions
+7
View File
@@ -80,6 +80,7 @@ import {
MongoSettingsRepository,
MongoNotificationsRepository,
MongoIncidentRepository,
MongoTeamsRepository,
IMonitorsRepository,
IChecksRepository,
IMonitorStatsRepository,
@@ -90,6 +91,7 @@ import {
ISettingsRepository,
INotificationsRepository,
IIncidentsRepository,
ITeamsRepository,
} from "@/repositories/index.js";
import { ILogger } from "@/utils/logger.js";
import { EnvConfig } from "@/service/system/settingsService.js";
@@ -124,6 +126,7 @@ export type InitializedServices = {
settingsRepository: ISettingsRepository;
notificationsRepository: INotificationsRepository;
incidentsRepository: IIncidentsRepository;
teamsRepository: ITeamsRepository;
};
export const initializeServices = async ({
@@ -171,6 +174,8 @@ export const initializeServices = async ({
const settingsRepository = new MongoSettingsRepository();
const notificationsRepository = new MongoNotificationsRepository();
const incidentsRepository = new MongoIncidentRepository();
const teamsRepository = new MongoTeamsRepository();
const networkService = new NetworkService({
axios,
got,
@@ -254,6 +259,7 @@ export const initializeServices = async ({
invitesRepository,
recoveryTokensRepository,
settingsRepository,
teamsRepository,
});
const diagnosticService = new DiagnosticService();
@@ -311,6 +317,7 @@ export const initializeServices = async ({
settingsRepository,
notificationsRepository,
incidentsRepository,
teamsRepository,
};
return services;
-14
View File
@@ -1,14 +0,0 @@
import mongoose from "mongoose";
const TeamSchema = mongoose.Schema(
{
email: {
type: String,
required: true,
unique: true,
},
},
{
timestamps: true,
}
);
export default mongoose.model("Team", TeamSchema);
+27
View File
@@ -0,0 +1,27 @@
import { Schema, model, type Types } from "mongoose";
import type { Team } from "@/types/index.js";
interface TeamDocument extends Team {
_id: Types.ObjectId;
createdAt: Date;
updatedAt: Date;
}
const TeamSchema = new Schema<TeamDocument>(
{
email: {
type: String,
required: true,
unique: true,
},
},
{
timestamps: true,
}
);
const TeamModel = model<TeamDocument>("Team", TeamSchema);
export type { TeamDocument };
export { TeamModel };
export default TeamModel;
+3
View File
@@ -27,3 +27,6 @@ export { default as NotificationModel } from "@/db/models/Notification.js";
export * from "@/db/models/Incident.js";
export { default as IncidentModel } from "@/db/models/Incident.js";
export * from "@/db/models/Team.js";
export { default as TeamModel } from "@/db/models/Team.js";
+3
View File
@@ -27,3 +27,6 @@ export { default as MongoNotificationsRepository } from "@/repositories/notifica
export * from "@/repositories/incidents/IIncidentsRepository.js";
export { default as MongoIncidentRepository } from "@/repositories/incidents/MongoIncidentRepository.js";
export * from "@/repositories/teams/ITeamsRepository.js";
export { default as MongoTeamsRepository } from "@/repositories/teams/MongoTeamsRepository.js";
@@ -0,0 +1,9 @@
import type { Team } from "@/types/index.js";
export interface ITeamRepository {
// create
create(email: string): Promise<Team>;
// fetch
// update
// delete
// other
}
@@ -0,0 +1,36 @@
import { Team } from "@/types/index.js";
import { TeamDocument, TeamModel } from "@/db/models/index.js";
import { ITeamRepository } from "@/repositories/index.js";
import mongoose from "mongoose";
class MongoTeamRepository implements ITeamRepository {
private toStringId = (value?: mongoose.Types.ObjectId | string | null): string => {
if (!value) {
return "";
}
return value instanceof mongoose.Types.ObjectId ? value.toString() : String(value);
};
private toDateString = (value?: Date | string | null): string => {
if (!value) {
return new Date(0).toISOString();
}
return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
};
private toEntity = (doc: TeamDocument): Team => {
return {
id: this.toStringId(doc._id),
email: doc.email,
createdAt: this.toDateString(doc.createdAt),
updatedAt: this.toDateString(doc.updatedAt),
};
};
create = async (email: string) => {
const team = await TeamModel.create({ email });
return this.toEntity(team);
};
}
export default MongoTeamRepository;
+18 -7
View File
@@ -1,9 +1,15 @@
import { IInvitesRepository, IMonitorsRepository, IRecoveryTokensRepository, IUsersRepository, ISettingsRepository } from "@/repositories/index.js";
import Team from "@/db/models/Team.js";
import {
IInvitesRepository,
IMonitorsRepository,
IRecoveryTokensRepository,
IUsersRepository,
ISettingsRepository,
ITeamRepository,
} from "@/repositories/index.js";
import type { User } from "@/types/index.js";
import bcrypt from "bcryptjs";
import { AppError } from "@/utils/AppError.js";
import { ISuperSimpleQueue } from "../infrastructure/SuperSimpleQueue/SuperSimpleQueue.js";
import { ISuperSimpleQueue } from "@/service/infrastructure/SuperSimpleQueue/SuperSimpleQueue.js";
const SERVICE_NAME = "userService";
@@ -21,6 +27,7 @@ class UserService {
private invitesRepository: IInvitesRepository;
private recoveryTokensRepository: IRecoveryTokensRepository;
private settingsRepository: ISettingsRepository;
private teamsRepository: ITeamRepository;
constructor({
crypto,
@@ -34,6 +41,7 @@ class UserService {
invitesRepository,
recoveryTokensRepository,
settingsRepository,
teamsRepository,
}: {
crypto: any;
emailService: any;
@@ -47,6 +55,7 @@ class UserService {
invitesRepository: IInvitesRepository;
recoveryTokensRepository: IRecoveryTokensRepository;
settingsRepository: ISettingsRepository;
teamsRepository: ITeamRepository;
}) {
this.emailService = emailService;
this.settingsService = settingsService;
@@ -59,6 +68,7 @@ class UserService {
this.invitesRepository = invitesRepository;
this.recoveryTokensRepository = recoveryTokensRepository;
this.settingsRepository = settingsRepository;
this.teamsRepository = teamsRepository;
}
get serviceName() {
@@ -85,10 +95,11 @@ class UserService {
const jwtSecret = this.crypto.randomBytes(64).toString("hex");
await this.settingsRepository.update({ jwtSecret });
// Create a new team
const team = new Team({
email: user.email,
});
user.teamId = team._id;
if (!user.email) {
throw new AppError({ message: "Email is required for first user", service: SERVICE_NAME, method: "registerUser", status: 400 });
}
const team = await this.teamsRepository.create(user.email);
user.teamId = team.id;
}
const newUser = await this.usersRepository.create({ ...user }, file);
+1
View File
@@ -11,3 +11,4 @@ export * from "@/types/notification.js";
export * from "@/types/alert.js";
export * from "@/types/incident.js";
export * from "@/types/email.js";
export * from "@/types/team.js";
+6
View File
@@ -0,0 +1,6 @@
export interface Team {
id: string;
email: string;
createdAt: string;
updatedAt: string;
}