feat: add domains, ideas, layouts, widgets API modules

- Add DomainsModule with full CRUD, search, and activity logging
- Add IdeasModule with quick capture endpoint
- Add LayoutsModule for user dashboard layouts
- Add WidgetsModule for widget definitions (read-only)
- Update ActivityService with domain/idea logging methods
- Register all new modules in AppModule
This commit is contained in:
Jason Woltje
2026-01-29 13:47:03 -06:00
parent 973502f26e
commit f47dd8bc92
66 changed files with 4277 additions and 29 deletions

View File

@@ -1,6 +1,6 @@
import { Injectable, Logger } from "@nestjs/common";
import { PrismaService } from "../prisma/prisma.service";
import { ActivityAction, EntityType } from "@prisma/client";
import { ActivityAction, EntityType, Prisma } from "@prisma/client";
import type {
CreateActivityLogInput,
PaginatedActivityLogs,
@@ -23,7 +23,7 @@ export class ActivityService {
async logActivity(input: CreateActivityLogInput) {
try {
return await this.prisma.activityLog.create({
data: input,
data: input as unknown as Prisma.ActivityLogCreateInput,
});
} catch (error) {
this.logger.error("Failed to log activity", error);
@@ -167,7 +167,7 @@ export class ActivityService {
workspaceId: string,
userId: string,
taskId: string,
details?: Record<string, any>
details?: Prisma.JsonValue
) {
return this.logActivity({
workspaceId,
@@ -186,7 +186,7 @@ export class ActivityService {
workspaceId: string,
userId: string,
taskId: string,
details?: Record<string, any>
details?: Prisma.JsonValue
) {
return this.logActivity({
workspaceId,
@@ -205,7 +205,7 @@ export class ActivityService {
workspaceId: string,
userId: string,
taskId: string,
details?: Record<string, any>
details?: Prisma.JsonValue
) {
return this.logActivity({
workspaceId,
@@ -224,7 +224,7 @@ export class ActivityService {
workspaceId: string,
userId: string,
taskId: string,
details?: Record<string, any>
details?: Prisma.JsonValue
) {
return this.logActivity({
workspaceId,
@@ -262,7 +262,7 @@ export class ActivityService {
workspaceId: string,
userId: string,
eventId: string,
details?: Record<string, any>
details?: Prisma.JsonValue
) {
return this.logActivity({
workspaceId,
@@ -281,7 +281,7 @@ export class ActivityService {
workspaceId: string,
userId: string,
eventId: string,
details?: Record<string, any>
details?: Prisma.JsonValue
) {
return this.logActivity({
workspaceId,
@@ -300,7 +300,7 @@ export class ActivityService {
workspaceId: string,
userId: string,
eventId: string,
details?: Record<string, any>
details?: Prisma.JsonValue
) {
return this.logActivity({
workspaceId,
@@ -319,7 +319,7 @@ export class ActivityService {
workspaceId: string,
userId: string,
projectId: string,
details?: Record<string, any>
details?: Prisma.JsonValue
) {
return this.logActivity({
workspaceId,
@@ -338,7 +338,7 @@ export class ActivityService {
workspaceId: string,
userId: string,
projectId: string,
details?: Record<string, any>
details?: Prisma.JsonValue
) {
return this.logActivity({
workspaceId,
@@ -357,7 +357,7 @@ export class ActivityService {
workspaceId: string,
userId: string,
projectId: string,
details?: Record<string, any>
details?: Prisma.JsonValue
) {
return this.logActivity({
workspaceId,
@@ -375,7 +375,7 @@ export class ActivityService {
async logWorkspaceCreated(
workspaceId: string,
userId: string,
details?: Record<string, any>
details?: Prisma.JsonValue
) {
return this.logActivity({
workspaceId,
@@ -393,7 +393,7 @@ export class ActivityService {
async logWorkspaceUpdated(
workspaceId: string,
userId: string,
details?: Record<string, any>
details?: Prisma.JsonValue
) {
return this.logActivity({
workspaceId,
@@ -448,7 +448,7 @@ export class ActivityService {
async logUserUpdated(
workspaceId: string,
userId: string,
details?: Record<string, any>
details?: Prisma.JsonValue
) {
return this.logActivity({
workspaceId,
@@ -459,4 +459,118 @@ export class ActivityService {
...(details && { details }),
});
}
/**
* Log domain creation
*/
async logDomainCreated(
workspaceId: string,
userId: string,
domainId: string,
details?: Prisma.JsonValue
) {
return this.logActivity({
workspaceId,
userId,
action: ActivityAction.CREATED,
entityType: EntityType.DOMAIN,
entityId: domainId,
...(details && { details }),
});
}
/**
* Log domain update
*/
async logDomainUpdated(
workspaceId: string,
userId: string,
domainId: string,
details?: Prisma.JsonValue
) {
return this.logActivity({
workspaceId,
userId,
action: ActivityAction.UPDATED,
entityType: EntityType.DOMAIN,
entityId: domainId,
...(details && { details }),
});
}
/**
* Log domain deletion
*/
async logDomainDeleted(
workspaceId: string,
userId: string,
domainId: string,
details?: Prisma.JsonValue
) {
return this.logActivity({
workspaceId,
userId,
action: ActivityAction.DELETED,
entityType: EntityType.DOMAIN,
entityId: domainId,
...(details && { details }),
});
}
/**
* Log idea creation
*/
async logIdeaCreated(
workspaceId: string,
userId: string,
ideaId: string,
details?: Prisma.JsonValue
) {
return this.logActivity({
workspaceId,
userId,
action: ActivityAction.CREATED,
entityType: EntityType.IDEA,
entityId: ideaId,
...(details && { details }),
});
}
/**
* Log idea update
*/
async logIdeaUpdated(
workspaceId: string,
userId: string,
ideaId: string,
details?: Prisma.JsonValue
) {
return this.logActivity({
workspaceId,
userId,
action: ActivityAction.UPDATED,
entityType: EntityType.IDEA,
entityId: ideaId,
...(details && { details }),
});
}
/**
* Log idea deletion
*/
async logIdeaDeleted(
workspaceId: string,
userId: string,
ideaId: string,
details?: Prisma.JsonValue
) {
return this.logActivity({
workspaceId,
userId,
action: ActivityAction.DELETED,
entityType: EntityType.IDEA,
entityId: ideaId,
...(details && { details }),
});
}
}

View File

@@ -9,7 +9,7 @@ export interface CreateActivityLogInput {
action: ActivityAction;
entityType: EntityType;
entityId: string;
details?: Record<string, any>;
details?: Prisma.JsonValue;
ipAddress?: string;
userAgent?: string;
}