mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-17 08:19:40 +02:00
✨ feat(admin): add user data dashboard for cross-project data visualization
Add comprehensive admin dashboard to view and manage user data across all projects: Backend: - Add admin endpoints to Chat, Todo, Contacts, Calendar, Picture, Zitare, Presi - Each backend exposes GET/DELETE /api/v1/admin/user-data/:userId - Service-to-service auth via X-Service-Key header Aggregation (mana-core-auth): - GET /api/v1/admin/users - Paginated user list with search - GET /api/v1/admin/users/:userId/data - Aggregated data from all backends - DELETE /api/v1/admin/users/:userId/data - GDPR deletion across all projects Frontend (ManaCore web): - New User Data tab in admin navigation - User search page at /admin/user-data - User detail page with ProjectDataCard components - GDPR deletion dialog with email confirmation Presi: - Migrate user_id from UUID to TEXT for Better Auth compatibility - Add SQL migration script
This commit is contained in:
parent
5b6f231e1a
commit
a2e2a5b73c
57 changed files with 3847 additions and 465 deletions
66
services/mana-core-auth/src/admin/user-data.controller.ts
Normal file
66
services/mana-core-auth/src/admin/user-data.controller.ts
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Delete,
|
||||
Param,
|
||||
Query,
|
||||
UseGuards,
|
||||
Logger,
|
||||
HttpCode,
|
||||
HttpStatus,
|
||||
} from '@nestjs/common';
|
||||
import { UserDataService } from './user-data.service';
|
||||
import { AdminGuard } from './guards/admin.guard';
|
||||
import { UserDataSummary, DeleteUserDataResponse, UserListResponse } from './dto/user-data.dto';
|
||||
|
||||
/**
|
||||
* Admin controller for cross-project user data management
|
||||
* All endpoints require admin authentication (role=admin or in ADMIN_USER_IDS)
|
||||
*/
|
||||
@Controller('api/v1/admin')
|
||||
@UseGuards(AdminGuard)
|
||||
export class UserDataController {
|
||||
private readonly logger = new Logger(UserDataController.name);
|
||||
|
||||
constructor(private readonly userDataService: UserDataService) {}
|
||||
|
||||
/**
|
||||
* List all users with pagination and search
|
||||
* GET /api/v1/admin/users?page=1&limit=20&search=email
|
||||
*/
|
||||
@Get('users')
|
||||
async getUsers(
|
||||
@Query('page') page?: string,
|
||||
@Query('limit') limit?: string,
|
||||
@Query('search') search?: string
|
||||
): Promise<UserListResponse> {
|
||||
const pageNum = parseInt(page || '1', 10);
|
||||
const limitNum = Math.min(parseInt(limit || '20', 10), 100);
|
||||
|
||||
this.logger.log(
|
||||
`Admin request: getUsers page=${pageNum} limit=${limitNum} search=${search || ''}`
|
||||
);
|
||||
return this.userDataService.getUsers(pageNum, limitNum, search);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get aggregated user data from all projects
|
||||
* GET /api/v1/admin/users/:userId/data
|
||||
*/
|
||||
@Get('users/:userId/data')
|
||||
async getUserData(@Param('userId') userId: string): Promise<UserDataSummary> {
|
||||
this.logger.log(`Admin request: getUserData for userId=${userId}`);
|
||||
return this.userDataService.getUserDataSummary(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all user data across all projects (GDPR right to be forgotten)
|
||||
* DELETE /api/v1/admin/users/:userId/data
|
||||
*/
|
||||
@Delete('users/:userId/data')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
async deleteUserData(@Param('userId') userId: string): Promise<DeleteUserDataResponse> {
|
||||
this.logger.log(`Admin request: deleteUserData for userId=${userId}`);
|
||||
return this.userDataService.deleteUserData(userId);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue