- Restructure: move backend from new_project/ to backend/ - Add full React/TypeScript frontend (37 pages, 17 services, 16 type defs, 11 query hooks) - Add docs/ with SRS specs, user stories, and workflow documentation - Update .gitignore for new directory layout Workflows implemented: WF1 User Signup, WF2 Placement Test, WF3 Exam Configuration, WF4 General English Exam, WF5 Course Generation, WF6 Entity Student Onboarding, AI Course Generation, Adaptive Learning Engine UI, White-Label Branding, Score Release Made-with: Cursor
76 lines
3.3 KiB
TypeScript
76 lines
3.3 KiB
TypeScript
import { api } from "@/lib/api-client";
|
|
import type {
|
|
Role, Permission, RoleCreateRequest, PermissionCreateRequest,
|
|
AuthorityMatrixData, UserWithRoles, UserRoleDetail, UserAuthorityMatrixData,
|
|
} from "@/types/role-permission";
|
|
|
|
interface PaginatedRoles { data: Role[]; total: number; page: number; size: number }
|
|
interface PaginatedUsers { data: UserWithRoles[]; total: number; page: number; size: number }
|
|
interface PermissionList { data: Permission[]; total: number }
|
|
|
|
type Params = Record<string, string | number | boolean | undefined>;
|
|
|
|
export const rolesService = {
|
|
// ── Roles ──
|
|
async listRoles(params?: { search?: string; entity_id?: number }): Promise<PaginatedRoles> {
|
|
return api.get<PaginatedRoles>("/roles", params as Params);
|
|
},
|
|
async getRole(id: number): Promise<{ data: Role }> {
|
|
return api.get<{ data: Role }>(`/roles/${id}`);
|
|
},
|
|
async createRole(data: RoleCreateRequest): Promise<{ data: Role }> {
|
|
return api.post<{ data: Role }>("/roles", data);
|
|
},
|
|
async updateRole(id: number, data: Partial<RoleCreateRequest>): Promise<{ data: Role }> {
|
|
return api.patch<{ data: Role }>(`/roles/${id}`, data);
|
|
},
|
|
async deleteRole(id: number): Promise<{ success: boolean }> {
|
|
return api.delete<{ success: boolean }>(`/roles/${id}`);
|
|
},
|
|
async updateRolePermissions(id: number, permissionIds: number[]): Promise<{ data: Role }> {
|
|
return api.patch<{ data: Role }>(`/roles/${id}/permissions`, { permission_ids: permissionIds });
|
|
},
|
|
|
|
// ── Permissions ──
|
|
async listPermissions(params?: { category?: string; search?: string }): Promise<PermissionList> {
|
|
return api.get<PermissionList>("/permissions", params as Params);
|
|
},
|
|
async createPermission(data: PermissionCreateRequest): Promise<{ data: Permission }> {
|
|
return api.post<{ data: Permission }>("/permissions", data);
|
|
},
|
|
async deletePermission(id: number): Promise<{ success: boolean }> {
|
|
return api.delete<{ success: boolean }>(`/permissions/${id}`);
|
|
},
|
|
|
|
// ── Role Authority Matrix ──
|
|
async getAuthorityMatrix(): Promise<AuthorityMatrixData> {
|
|
return api.get<AuthorityMatrixData>("/authority-matrix");
|
|
},
|
|
async toggleMatrixCell(roleId: number, permissionId: number) {
|
|
return api.post<{ role_id: number; permission_id: number; granted: boolean }>(
|
|
"/authority-matrix/toggle", { role_id: roleId, permission_id: permissionId },
|
|
);
|
|
},
|
|
|
|
// ── User-Role Assignment ──
|
|
async listUsersWithRoles(params?: { search?: string; role_id?: number; page?: number; size?: number }): Promise<PaginatedUsers> {
|
|
return api.get<PaginatedUsers>("/users/with-roles", params as Params);
|
|
},
|
|
async getUserRoles(userId: number): Promise<UserRoleDetail> {
|
|
return api.get<UserRoleDetail>(`/users/${userId}/roles`);
|
|
},
|
|
async updateUserRoles(userId: number, roleIds: number[]): Promise<{ success: boolean }> {
|
|
return api.patch<{ success: boolean }>(`/users/${userId}/roles`, { role_ids: roleIds });
|
|
},
|
|
async toggleUserRole(userId: number, roleId: number) {
|
|
return api.post<{ user_id: number; role_id: number; assigned: boolean }>(
|
|
`/users/${userId}/roles/toggle`, { role_id: roleId },
|
|
);
|
|
},
|
|
|
|
// ── User Authority Matrix ──
|
|
async getUserAuthorityMatrix(): Promise<UserAuthorityMatrixData> {
|
|
return api.get<UserAuthorityMatrixData>("/user-authority-matrix");
|
|
},
|
|
};
|