alepha
Version:
Easy-to-use modern TypeScript framework for building many kind of applications.
202 lines (201 loc) • 5.79 kB
JavaScript
import { $inject, $module, Alepha, z } from "alepha";
import { $secure } from "alepha/security";
import { $action, okSchema } from "alepha/server";
import { $entity, $repository, db, pageQuerySchema } from "alepha/orm";
import { $logger } from "alepha/logger";
//#region ../../src/api/organizations/schemas/createOrganizationSchema.ts
const createOrganizationSchema = z.object({
name: z.text(),
slug: z.text({
minLength: 2,
maxLength: 100
}),
enabled: z.boolean().optional()
});
//#endregion
//#region ../../src/api/organizations/schemas/organizationQuerySchema.ts
const organizationQuerySchema = pageQuerySchema.extend({
name: z.text({ description: "Filter by name (partial match)" }).optional(),
enabled: z.boolean().describe("Filter by enabled status").optional()
});
//#endregion
//#region ../../src/api/organizations/entities/organizations.ts
const organizations = $entity({
name: "organizations",
schema: z.object({
id: db.primaryKey(z.uuid()),
version: db.version(),
createdAt: db.createdAt(),
updatedAt: db.updatedAt(),
name: z.text(),
slug: z.text({
minLength: 2,
maxLength: 100
}),
enabled: db.default(z.boolean(), true)
}),
indexes: [{
columns: ["slug"],
unique: true
}]
});
//#endregion
//#region ../../src/api/organizations/schemas/organizationResourceSchema.ts
const organizationResourceSchema = organizations.schema;
//#endregion
//#region ../../src/api/organizations/schemas/updateOrganizationSchema.ts
const updateOrganizationSchema = createOrganizationSchema.partial();
//#endregion
//#region ../../src/api/organizations/services/OrganizationService.ts
var OrganizationService = class {
alepha = $inject(Alepha);
log = $logger();
repo = $repository(organizations);
/**
* Find organizations with pagination and filtering.
*/
async find(query = {}) {
query.sort ??= "-createdAt";
const where = this.repo.createQueryWhere();
if (query.name) where.name = { like: `%${query.name}%` };
if (query.enabled !== void 0) where.enabled = { eq: query.enabled };
return this.repo.paginate(query, { where }, { count: true });
}
/**
* Get an organization by ID.
*/
async getById(id) {
return this.repo.getById(id);
}
/**
* Get an organization by slug.
*/
async getBySlug(slug) {
return this.repo.getOne({ where: { slug: { eq: slug } } });
}
/**
* Create a new organization.
*/
async create(data) {
return this.repo.create(data);
}
/**
* Update an organization.
*/
async update(id, data) {
return this.repo.updateById(id, data);
}
/**
* Delete an organization.
*/
async delete(id) {
await this.repo.deleteById(id);
}
};
//#endregion
//#region ../../src/api/organizations/controllers/AdminOrganizationController.ts
var AdminOrganizationController = class {
url = "/organizations";
group = "admin:organizations";
organizationService = $inject(OrganizationService);
/**
* Find organizations with pagination and filtering.
*/
findOrganizations = $action({
path: this.url,
group: this.group,
use: [$secure({ permissions: ["admin:organization:read"] })],
description: "Find organizations with pagination and filtering",
schema: {
query: organizationQuerySchema,
response: z.page(organizationResourceSchema)
},
handler: ({ query }) => this.organizationService.find(query)
});
/**
* Get an organization by ID.
*/
getOrganization = $action({
path: `${this.url}/:id`,
group: this.group,
use: [$secure({ permissions: ["admin:organization:read"] })],
description: "Get an organization by ID",
schema: {
params: z.object({ id: z.uuid() }),
response: organizationResourceSchema
},
handler: ({ params }) => this.organizationService.getById(params.id)
});
/**
* Create a new organization.
*/
createOrganization = $action({
method: "POST",
path: this.url,
group: this.group,
use: [$secure({ permissions: ["admin:organization:create"] })],
description: "Create a new organization",
schema: {
body: createOrganizationSchema,
response: organizationResourceSchema
},
handler: ({ body }) => this.organizationService.create(body)
});
/**
* Update an organization.
*/
updateOrganization = $action({
method: "PATCH",
path: `${this.url}/:id`,
group: this.group,
use: [$secure({ permissions: ["admin:organization:update"] })],
description: "Update an organization",
schema: {
params: z.object({ id: z.uuid() }),
body: updateOrganizationSchema,
response: organizationResourceSchema
},
handler: ({ params, body }) => this.organizationService.update(params.id, body)
});
/**
* Delete an organization.
*/
deleteOrganization = $action({
method: "DELETE",
path: `${this.url}/:id`,
group: this.group,
use: [$secure({ permissions: ["admin:organization:delete"] })],
description: "Delete an organization",
schema: {
params: z.object({ id: z.uuid() }),
response: okSchema
},
handler: async ({ params }) => {
await this.organizationService.delete(params.id);
return {
ok: true,
id: params.id
};
}
});
};
//#endregion
//#region ../../src/api/organizations/index.ts
/**
* Organization management for multi-tenancy.
*
* **Features:**
* - Admin CRUD for organizations
* - Organization scoping via `db.organization()` on entities
* - User with no organization = god mode (sees all resources)
* - User with an organization = scoped to that organization
*
* @module alepha.api.organizations
*/
const AlephaApiOrganizations = $module({
name: "alepha.api.organizations",
services: [OrganizationService, AdminOrganizationController]
});
//#endregion
export { AdminOrganizationController, AlephaApiOrganizations, OrganizationService, createOrganizationSchema, organizationQuerySchema, organizationResourceSchema, organizations, updateOrganizationSchema };
//# sourceMappingURL=index.js.map