feat: implement account settings and API tokens management
- 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.
This commit is contained in:
100
ts/models/team.ts
Normal file
100
ts/models/team.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user