template-saas-backend-v2/src/modules/goals/entities/definition.entity.ts
Adrian Flores Cortes 09ea4d51b4 [SAAS-022] feat: Implement Goals module backend
- Added 4 entities: DefinitionEntity, AssignmentEntity, ProgressLogEntity, MilestoneNotificationEntity
- Added DTOs for definitions and assignments
- Added services for definitions and assignments CRUD
- Added controllers with full REST API endpoints
- Added GoalsModule and registered in AppModule

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 06:25:44 -06:00

149 lines
2.9 KiB
TypeScript

import {
Entity,
PrimaryGeneratedColumn,
Column,
CreateDateColumn,
UpdateDateColumn,
OneToMany,
} from 'typeorm';
import { AssignmentEntity } from './assignment.entity';
export enum GoalType {
TARGET = 'target',
LIMIT = 'limit',
MAINTAIN = 'maintain',
}
export enum MetricType {
NUMBER = 'number',
CURRENCY = 'currency',
PERCENTAGE = 'percentage',
BOOLEAN = 'boolean',
COUNT = 'count',
}
export enum PeriodType {
DAILY = 'daily',
WEEKLY = 'weekly',
MONTHLY = 'monthly',
QUARTERLY = 'quarterly',
YEARLY = 'yearly',
CUSTOM = 'custom',
}
export enum DataSource {
MANUAL = 'manual',
SALES = 'sales',
BILLING = 'billing',
COMMISSIONS = 'commissions',
CUSTOM = 'custom',
}
export enum GoalStatus {
DRAFT = 'draft',
ACTIVE = 'active',
PAUSED = 'paused',
COMPLETED = 'completed',
CANCELLED = 'cancelled',
}
export interface SourceConfig {
module?: string;
entity?: string;
filter?: Record<string, unknown>;
aggregation?: 'sum' | 'count' | 'avg';
field?: string;
}
export interface Milestone {
percentage: number;
notify: boolean;
}
@Entity({ schema: 'goals', name: 'definitions' })
export class DefinitionEntity {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ name: 'tenant_id', type: 'uuid' })
tenantId: string;
@Column({ type: 'varchar', length: 200 })
name: string;
@Column({ type: 'text', nullable: true })
description: string | null;
@Column({ type: 'varchar', length: 100, nullable: true })
category: string | null;
@Column({
type: 'enum',
enum: GoalType,
default: GoalType.TARGET,
})
type: GoalType;
@Column({
type: 'enum',
enum: MetricType,
default: MetricType.NUMBER,
})
metric: MetricType;
@Column({ name: 'target_value', type: 'decimal', precision: 15, scale: 2 })
targetValue: number;
@Column({ type: 'varchar', length: 50, nullable: true })
unit: string | null;
@Column({
type: 'enum',
enum: PeriodType,
default: PeriodType.MONTHLY,
})
period: PeriodType;
@Column({ name: 'starts_at', type: 'date' })
startsAt: Date;
@Column({ name: 'ends_at', type: 'date' })
endsAt: Date;
@Column({
type: 'enum',
enum: DataSource,
default: DataSource.MANUAL,
})
source: DataSource;
@Column({ name: 'source_config', type: 'jsonb', default: {} })
sourceConfig: SourceConfig;
@Column({ type: 'jsonb', default: [] })
milestones: Milestone[];
@Column({
type: 'enum',
enum: GoalStatus,
default: GoalStatus.DRAFT,
})
status: GoalStatus;
@Column({ type: 'jsonb', default: [] })
tags: string[];
@CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
createdAt: Date;
@UpdateDateColumn({ name: 'updated_at', type: 'timestamptz' })
updatedAt: Date;
@Column({ name: 'created_by', type: 'uuid', nullable: true })
createdBy: string | null;
// Relations
@OneToMany(() => AssignmentEntity, (assignment) => assignment.definition)
assignments: AssignmentEntity[];
}