feat: add admin ideas management page with private notes
Adds a dedicated super admin page for managing idea submissions across all tenants. Includes status summary cards, filterable/searchable table, detail modal with status updates, and private admin notes for internal tracking (sprint refs, thoughts, follow-ups). Notes are not visible to tenant users. - Database: admin_note column on shared.ideas (019 migration) - Backend: PUT /admin/ideas/:id/note endpoint - Frontend: AdminIdeasPage with table, filters, detail modal - Sidebar: "Idea Submissions" nav link in admin sections - Routing: /admin/ideas route under SuperAdminRoute guard Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -218,6 +218,17 @@ export class AdminController {
|
||||
return { success: true, idea };
|
||||
}
|
||||
|
||||
@Put('ideas/:id/note')
|
||||
async updateIdeaNote(
|
||||
@Req() req: any,
|
||||
@Param('id') id: string,
|
||||
@Body() body: { adminNote: string },
|
||||
) {
|
||||
await this.requireSuperadmin(req);
|
||||
const idea = await this.ideasService.updateNote(id, body.adminNote);
|
||||
return { success: true, idea };
|
||||
}
|
||||
|
||||
@Put('organizations/:id/settings')
|
||||
async updateOrgSettings(
|
||||
@Req() req: any,
|
||||
|
||||
@@ -30,6 +30,9 @@ export class Idea {
|
||||
@Column({ length: 20, default: 'new' })
|
||||
status: string;
|
||||
|
||||
@Column({ name: 'admin_note', type: 'text', nullable: true })
|
||||
adminNote: string;
|
||||
|
||||
@CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
|
||||
createdAt: Date;
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ export class IdeasService {
|
||||
'idea.description AS description',
|
||||
'idea.status AS status',
|
||||
'idea.createdAt AS "createdAt"',
|
||||
'idea.adminNote AS "adminNote"',
|
||||
'org.id AS "orgId"',
|
||||
'org.name AS "orgName"',
|
||||
'user.id AS "userId"',
|
||||
@@ -75,4 +76,14 @@ export class IdeasService {
|
||||
idea.status = status;
|
||||
return this.ideasRepository.save(idea);
|
||||
}
|
||||
|
||||
async updateNote(id: string, adminNote: string): Promise<Idea> {
|
||||
const idea = await this.ideasRepository.findOne({ where: { id } });
|
||||
if (!idea) {
|
||||
throw new NotFoundException('Idea not found');
|
||||
}
|
||||
|
||||
idea.adminNote = adminNote;
|
||||
return this.ideasRepository.save(idea);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user