Files
app/ts/reception/classes.organizationmanager.ts
T
jkunz 833cf3b4b8 feat: Update organization member management and bulk invite functionality
- Marked the status of "Invite and Manage Team Members" story as Complete in README.
- Updated the status of ORG-002 to Complete in the corresponding markdown file.
- Modified OrganizationManager to assign roles as 'owner' during organization creation.
- Implemented bulk invitation feature in UserInvitationManager, allowing multiple users to be invited via CSV upload.
- Added IReq_BulkCreateInvitations interface for bulk invitation requests.
- Enhanced CreateOrgForm to update state with new roles upon organization creation.
- Introduced BulkInviteModal for bulk inviting users, including email validation and role assignment.
- Updated UsersView to support ownership transfer and bulk invitation functionality.
- Improved account state management to handle new roles and organizations.
2025-12-05 09:34:19 +00:00

117 lines
3.9 KiB
TypeScript

import * as plugins from '../plugins.js';
import { Reception } from './classes.reception.js';
import { Organization } from './classes.organization.js';
import { User } from './classes.user.js';
export class OrganizationManager {
public receptionRef: Reception;
public get db() {
return this.receptionRef.db.smartdataDb;
}
public typedrouter = new plugins.typedrequest.TypedRouter();
public COrganization = plugins.smartdata.setDefaultManagerForDoc(this, Organization);
constructor(receptionRefArg: Reception) {
this.receptionRef = receptionRefArg;
this.receptionRef.typedrouter.addTypedRouter(this.typedrouter);
this.typedrouter.addTypedHandler(
new plugins.typedrequest.TypedHandler<plugins.idpInterfaces.request.IReq_CreateOrganization>(
'createOrganization',
async (requestArg) => {
const nameIsAvailable = async () => {
const existingOrg = await this.COrganization.getInstance({
data: {
slug: requestArg.organizationSlug,
},
});
const nameAvailable = !existingOrg;
return nameAvailable;
};
switch (requestArg.action) {
case 'checkAvailability':
return {
nameAvailable: await nameIsAvailable(),
};
break;
case 'manifest':
const nameCheckedOk = await nameIsAvailable();
const userData = await this.receptionRef.userManager.getUserByJwtValidation(
requestArg.jwt
);
const newOrg = await this.COrganization.createNewOrganizationForUser(
this,
userData.id,
requestArg.organizationName,
requestArg.organizationSlug
);
const role = await this.receptionRef.roleManager.modifyRoleForUserAtOrg({
action: 'create',
organizationId: newOrg.id,
userId: userData.id,
roles: ['owner'],
});
newOrg.data.roleIds.push(role.id);
await newOrg.save();
return {
nameAvailable: true,
resultingOrganization: await newOrg.createSavableObject(),
role: await role.createSavableObject(),
}
break;
}
}
)
);
this.typedrouter.addTypedHandler(
new plugins.typedrequest.TypedHandler<plugins.idpInterfaces.request.IReq_GetOrganizationById>(
'getOrganizationById',
async (requestArg) => {
const verifiedJwt = await this.receptionRef.jwtManager.verifyJWTAndGetData(
requestArg.jwt
);
const user = await this.receptionRef.userManager.CUser.getInstance({
id: verifiedJwt.data.userId,
});
const organization = await this.COrganization.getInstance({
id: requestArg.id
});
const role = await this.receptionRef.roleManager.CRole.getInstance({
data: {
organizationId: organization.id,
userId: user.id,
}
});
if (!role) {
throw new plugins.typedrequest.TypedResponseError('User not authorized for the requested organization.');
}
return {
organization: await organization.createSavableObject()
};
}
)
);
}
public async getAllOrganizationsForUser(
userArg: User,
) {
const organizations: Organization[] = [];
const userRoles = await this.receptionRef.roleManager.getAllRolesForUser(userArg);
for (const role of userRoles) {
const organization = await this.receptionRef.organizationmanager.COrganization.getInstance({
id: role.data.organizationId
});
if (!organizations.find(orgArg => orgArg.id === organization.id)) {
organizations.push(organization);
}
}
return organizations;
}
}