feat(organization): add organization rename redirects and redirect management endpoints

This commit is contained in:
2026-03-20 17:07:12 +00:00
parent c60a0ed536
commit 8cb5e4fa96
10 changed files with 224 additions and 8 deletions

View File

@@ -15,6 +15,9 @@ export { ApiToken } from './apitoken.ts';
export { Session } from './session.ts';
export { AuditLog } from './auditlog.ts';
// Organization redirects
export { OrgRedirect } from './org.redirect.ts';
// External authentication models
export { AuthProvider } from './auth.provider.ts';
export { ExternalIdentity } from './external.identity.ts';

59
ts/models/org.redirect.ts Normal file
View File

@@ -0,0 +1,59 @@
/**
* OrgRedirect model - stores old org handles as redirect aliases
* When an org is renamed, the old name becomes a redirect pointing to the org.
* Redirects can be explicitly deleted by org admins.
*/
import * as plugins from '../plugins.ts';
import { db } from './db.ts';
@plugins.smartdata.Collection(() => db)
export class OrgRedirect extends plugins.smartdata.SmartDataDbDoc<OrgRedirect, OrgRedirect> {
@plugins.smartdata.unI()
public id: string = '';
@plugins.smartdata.svDb()
@plugins.smartdata.index({ unique: true })
public oldName: string = '';
@plugins.smartdata.svDb()
@plugins.smartdata.index()
public organizationId: string = '';
@plugins.smartdata.svDb()
public createdAt: Date = new Date();
/**
* Create a redirect from an old org name to the current org
*/
public static async create(oldName: string, organizationId: string): Promise<OrgRedirect> {
const redirect = new OrgRedirect();
redirect.id = `redirect:${oldName}`;
redirect.oldName = oldName;
redirect.organizationId = organizationId;
redirect.createdAt = new Date();
await redirect.save();
return redirect;
}
/**
* Find a redirect by the old name
*/
public static async findByName(name: string): Promise<OrgRedirect | null> {
return await OrgRedirect.getInstance({ oldName: name } as any);
}
/**
* Get all redirects for an organization
*/
public static async getByOrgId(organizationId: string): Promise<OrgRedirect[]> {
return await OrgRedirect.getInstances({ organizationId } as any);
}
/**
* Find a redirect by ID
*/
public static async findById(id: string): Promise<OrgRedirect | null> {
return await OrgRedirect.getInstance({ id } as any);
}
}