- Added SettingsComponent for user profile management, including display name and password change functionality. - Introduced TokensComponent for managing API tokens, including creation and revocation. - Created LayoutComponent for consistent application layout with navigation and user information. - Established main application structure in index.html and main.ts. - Integrated Tailwind CSS for styling and responsive design. - Configured TypeScript settings for strict type checking and module resolution.
101 lines
2.5 KiB
TypeScript
101 lines
2.5 KiB
TypeScript
/**
|
|
* Team model for Stack.Gallery Registry
|
|
*/
|
|
|
|
import * as plugins from '../plugins.ts';
|
|
import type { ITeam } from '../interfaces/auth.interfaces.ts';
|
|
import { getDb } from './db.ts';
|
|
|
|
@plugins.smartdata.Collection(() => getDb())
|
|
export class Team extends plugins.smartdata.SmartDataDbDoc<Team, Team> implements ITeam {
|
|
@plugins.smartdata.unI()
|
|
public id: string = '';
|
|
|
|
@plugins.smartdata.svDb()
|
|
@plugins.smartdata.index()
|
|
public organizationId: string = '';
|
|
|
|
@plugins.smartdata.svDb()
|
|
@plugins.smartdata.searchable()
|
|
public name: string = '';
|
|
|
|
@plugins.smartdata.svDb()
|
|
public description?: string;
|
|
|
|
@plugins.smartdata.svDb()
|
|
public isDefaultTeam: boolean = false;
|
|
|
|
@plugins.smartdata.svDb()
|
|
@plugins.smartdata.index()
|
|
public createdAt: Date = new Date();
|
|
|
|
@plugins.smartdata.svDb()
|
|
public updatedAt: Date = new Date();
|
|
|
|
/**
|
|
* Create a new team
|
|
*/
|
|
public static async createTeam(data: {
|
|
organizationId: string;
|
|
name: string;
|
|
description?: string;
|
|
isDefaultTeam?: boolean;
|
|
}): Promise<Team> {
|
|
// Validate name
|
|
const nameRegex = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/;
|
|
if (!nameRegex.test(data.name.toLowerCase())) {
|
|
throw new Error('Team name must be lowercase alphanumeric with optional hyphens');
|
|
}
|
|
|
|
// Check for duplicate name in org
|
|
const existing = await Team.getInstance({
|
|
organizationId: data.organizationId,
|
|
name: data.name.toLowerCase(),
|
|
});
|
|
|
|
if (existing) {
|
|
throw new Error('Team with this name already exists in the organization');
|
|
}
|
|
|
|
const team = new Team();
|
|
team.id = await Team.getNewId();
|
|
team.organizationId = data.organizationId;
|
|
team.name = data.name.toLowerCase();
|
|
team.description = data.description;
|
|
team.isDefaultTeam = data.isDefaultTeam || false;
|
|
team.createdAt = new Date();
|
|
team.updatedAt = new Date();
|
|
await team.save();
|
|
return team;
|
|
}
|
|
|
|
/**
|
|
* Find team by name in organization
|
|
*/
|
|
public static async findByName(organizationId: string, name: string): Promise<Team | null> {
|
|
return await Team.getInstance({
|
|
organizationId,
|
|
name: name.toLowerCase(),
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get all teams in an organization
|
|
*/
|
|
public static async getOrgTeams(organizationId: string): Promise<Team[]> {
|
|
return await Team.getInstances({
|
|
organizationId,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Lifecycle hook
|
|
*/
|
|
public async beforeSave(): Promise<void> {
|
|
this.updatedAt = new Date();
|
|
if (!this.id) {
|
|
this.id = await Team.getNewId();
|
|
}
|
|
}
|
|
}
|