2025-11-27 22:15:38 +00:00
|
|
|
/**
|
|
|
|
|
* OrganizationMember model - links users to organizations with roles
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import * as plugins from '../plugins.ts';
|
|
|
|
|
import type { IOrganizationMember, TOrganizationRole } from '../interfaces/auth.interfaces.ts';
|
2025-11-27 23:47:33 +00:00
|
|
|
import { db } from './db.ts';
|
2025-11-27 22:15:38 +00:00
|
|
|
|
2025-11-27 23:47:33 +00:00
|
|
|
@plugins.smartdata.Collection(() => db)
|
|
|
|
|
export class OrganizationMember extends plugins.smartdata.SmartDataDbDoc<OrganizationMember, OrganizationMember> implements IOrganizationMember {
|
2025-11-27 22:15:38 +00:00
|
|
|
@plugins.smartdata.unI()
|
|
|
|
|
public id: string = '';
|
|
|
|
|
|
|
|
|
|
@plugins.smartdata.svDb()
|
|
|
|
|
@plugins.smartdata.index()
|
|
|
|
|
public organizationId: string = '';
|
|
|
|
|
|
|
|
|
|
@plugins.smartdata.svDb()
|
|
|
|
|
@plugins.smartdata.index()
|
|
|
|
|
public userId: string = '';
|
|
|
|
|
|
|
|
|
|
@plugins.smartdata.svDb()
|
|
|
|
|
@plugins.smartdata.index()
|
|
|
|
|
public role: TOrganizationRole = 'member';
|
|
|
|
|
|
|
|
|
|
@plugins.smartdata.svDb()
|
|
|
|
|
public invitedBy?: string;
|
|
|
|
|
|
|
|
|
|
@plugins.smartdata.svDb()
|
|
|
|
|
public joinedAt: Date = new Date();
|
|
|
|
|
|
|
|
|
|
@plugins.smartdata.svDb()
|
|
|
|
|
@plugins.smartdata.index()
|
|
|
|
|
public createdAt: Date = new Date();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Add a member to an organization
|
|
|
|
|
*/
|
|
|
|
|
public static async addMember(data: {
|
|
|
|
|
organizationId: string;
|
|
|
|
|
userId: string;
|
|
|
|
|
role: TOrganizationRole;
|
|
|
|
|
invitedBy?: string;
|
|
|
|
|
}): Promise<OrganizationMember> {
|
|
|
|
|
// Check if member already exists
|
|
|
|
|
const existing = await OrganizationMember.getInstance({
|
|
|
|
|
organizationId: data.organizationId,
|
|
|
|
|
userId: data.userId,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (existing) {
|
|
|
|
|
throw new Error('User is already a member of this organization');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const member = new OrganizationMember();
|
|
|
|
|
member.id = await OrganizationMember.getNewId();
|
|
|
|
|
member.organizationId = data.organizationId;
|
|
|
|
|
member.userId = data.userId;
|
|
|
|
|
member.role = data.role;
|
|
|
|
|
member.invitedBy = data.invitedBy;
|
|
|
|
|
member.joinedAt = new Date();
|
|
|
|
|
member.createdAt = new Date();
|
|
|
|
|
await member.save();
|
|
|
|
|
return member;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Find membership for user in organization
|
|
|
|
|
*/
|
|
|
|
|
public static async findMembership(
|
|
|
|
|
organizationId: string,
|
|
|
|
|
userId: string
|
|
|
|
|
): Promise<OrganizationMember | null> {
|
|
|
|
|
return await OrganizationMember.getInstance({
|
|
|
|
|
organizationId,
|
|
|
|
|
userId,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get all members of an organization
|
|
|
|
|
*/
|
|
|
|
|
public static async getOrgMembers(organizationId: string): Promise<OrganizationMember[]> {
|
|
|
|
|
return await OrganizationMember.getInstances({
|
|
|
|
|
organizationId,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get all organizations a user belongs to
|
|
|
|
|
*/
|
|
|
|
|
public static async getUserOrganizations(userId: string): Promise<OrganizationMember[]> {
|
|
|
|
|
return await OrganizationMember.getInstances({
|
|
|
|
|
userId,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Lifecycle hook
|
|
|
|
|
*/
|
|
|
|
|
public async beforeSave(): Promise<void> {
|
|
|
|
|
if (!this.id) {
|
|
|
|
|
this.id = await OrganizationMember.getNewId();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|