From 0b6e94877c047a6c58548e68712287c67bb774c9 Mon Sep 17 00:00:00 2001 From: Claude Code Date: Sat, 4 Apr 2026 23:57:42 -0700 Subject: [PATCH] =?UTF-8?q?refactor(processor):=20=E2=99=BB=EF=B8=8F=20Sta?= =?UTF-8?q?ndardize=20and=20optimize=20entity=20definitions=20in=20Aggrega?= =?UTF-8?q?tedMetric=20and=20RawEvent=20by=20adjusting=20fields=20and=20ty?= =?UTF-8?q?pes=20for=20improved=20data=20model=20consistency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- .../src/entities/aggregated-metric.entity.ts | 2 + .../src/entities/raw-event.entity.ts | 58 +++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 services/processor/src/entities/raw-event.entity.ts diff --git a/services/processor/src/entities/aggregated-metric.entity.ts b/services/processor/src/entities/aggregated-metric.entity.ts index cbf8d6a..290d412 100644 --- a/services/processor/src/entities/aggregated-metric.entity.ts +++ b/services/processor/src/entities/aggregated-metric.entity.ts @@ -4,6 +4,7 @@ import { PrimaryGeneratedColumn, CreateDateColumn, Index, + Unique, } from 'typeorm'; export enum MetricType { @@ -36,6 +37,7 @@ export enum TimeGranularity { } @Entity('aggregated_metrics') +@Unique(['metricType', 'granularity', 'timestamp', 'dimension', 'dimensionValue']) @Index(['metricType', 'granularity', 'timestamp']) @Index(['metricType', 'dimension', 'dimensionValue', 'timestamp']) export class AggregatedMetric { diff --git a/services/processor/src/entities/raw-event.entity.ts b/services/processor/src/entities/raw-event.entity.ts new file mode 100644 index 0000000..b9e5f9b --- /dev/null +++ b/services/processor/src/entities/raw-event.entity.ts @@ -0,0 +1,58 @@ +import { + Entity, + PrimaryGeneratedColumn, + Column, + CreateDateColumn, + Index, +} from 'typeorm'; + +/** + * Raw analytics event - mirrors the collector's raw_events table. + * Used by the processor to fetch full event data from the queue job's eventId. + */ +@Entity('raw_events') +@Index(['sessionId', 'timestamp']) +@Index(['eventType', 'timestamp']) +@Index(['processed', 'timestamp']) +export class RawEvent { + @PrimaryGeneratedColumn('uuid') + id!: string; + + @Column({ type: 'varchar', length: 100 }) + @Index() + eventType!: string; + + @Column({ type: 'varchar', length: 64 }) + @Index() + sessionId!: string; + + @Column({ type: 'varchar', length: 64, nullable: true }) + @Index() + userId?: string | null; + + @Column({ type: 'text', nullable: true }) + pageUrl?: string | null; + + @Column({ type: 'text', nullable: true }) + referrer?: string | null; + + @Column({ type: 'varchar', length: 20, nullable: true }) + deviceType?: string | null; + + @Column({ type: 'jsonb', nullable: true }) + metadata?: Record | null; + + @Column({ type: 'timestamptz' }) + @Index() + timestamp!: Date; + + @CreateDateColumn({ type: 'timestamptz' }) + receivedAt!: Date; + + @Column({ type: 'boolean', default: false }) + @Index() + processed!: boolean; + + @Column({ type: 'timestamptz', nullable: true }) + processedAt?: Date | null; +}