feat(analytics/backend-api): ✨ add engagement metric and platform cost entities
This commit is contained in:
parent
acb07d3dd6
commit
dff6940af8
7 changed files with 27 additions and 33717 deletions
|
|
@ -55,6 +55,13 @@ export enum TargetType {
|
|||
*
|
||||
* TimescaleDB hypertables use composite primary keys with timestamp
|
||||
* for efficient time-series partitioning.
|
||||
*
|
||||
* NOTE: Does NOT extend BaseEntity because TimescaleDB hypertables require:
|
||||
* - Composite primary key (id + timestamp) for time partitioning
|
||||
* - bigint id (BIGSERIAL in PostgreSQL, not UUID)
|
||||
* - timestamp as part of PK (not createdAt/updatedAt pattern)
|
||||
*
|
||||
* This is the correct pattern for high-volume time-series data.
|
||||
*/
|
||||
@Entity('engagement_metrics')
|
||||
export class EngagementMetric {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import {
|
||||
Entity,
|
||||
PrimaryGeneratedColumn,
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
Index,
|
||||
} from 'typeorm'
|
||||
import { BaseEntity } from '@lilith/typeorm-entities'
|
||||
|
||||
export enum CostCategory {
|
||||
INFRASTRUCTURE = 'INFRASTRUCTURE',
|
||||
|
|
@ -17,10 +16,7 @@ export enum CostCategory {
|
|||
}
|
||||
|
||||
@Entity('platform_costs')
|
||||
export class PlatformCost {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string
|
||||
|
||||
export class PlatformCost extends BaseEntity {
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: CostCategory,
|
||||
|
|
@ -55,7 +51,4 @@ export class PlatformCost {
|
|||
|
||||
@Column('decimal', { precision: 10, scale: 2, nullable: true, name: 'budget_amount' })
|
||||
budgetAmount: number
|
||||
|
||||
@CreateDateColumn({ name: 'created_at' })
|
||||
createdAt: Date
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import {
|
||||
Entity,
|
||||
PrimaryGeneratedColumn,
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
Index,
|
||||
} from 'typeorm'
|
||||
import { BaseEntity } from '@lilith/typeorm-entities'
|
||||
|
||||
export enum ErrorSeverity {
|
||||
LOW = 'LOW',
|
||||
|
|
@ -33,10 +32,7 @@ export enum ErrorType {
|
|||
}
|
||||
|
||||
@Entity('platform_errors')
|
||||
export class PlatformError {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string
|
||||
|
||||
export class PlatformError extends BaseEntity {
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: ErrorType,
|
||||
|
|
@ -98,8 +94,4 @@ export class PlatformError {
|
|||
@Column({ type: 'varchar', length: 64, nullable: true })
|
||||
@Index()
|
||||
fingerprint: string // Hash of error for deduplication
|
||||
|
||||
@CreateDateColumn({ name: 'created_at' })
|
||||
@Index()
|
||||
createdAt: Date
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import {
|
||||
Entity,
|
||||
PrimaryGeneratedColumn,
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
Index,
|
||||
} from 'typeorm'
|
||||
import { BaseEntity } from '@lilith/typeorm-entities'
|
||||
|
||||
export interface RankingSuggestion {
|
||||
factor: string
|
||||
|
|
@ -15,10 +14,7 @@ export interface RankingSuggestion {
|
|||
@Entity('ranking_snapshots')
|
||||
@Index(['userId', 'date'])
|
||||
@Index(['listingId', 'date'])
|
||||
export class RankingSnapshot {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string
|
||||
|
||||
export class RankingSnapshot extends BaseEntity {
|
||||
@Column('uuid')
|
||||
@Index()
|
||||
userId: string
|
||||
|
|
@ -59,7 +55,4 @@ export class RankingSnapshot {
|
|||
|
||||
@Column('date')
|
||||
date: Date
|
||||
|
||||
@CreateDateColumn({ name: 'created_at' })
|
||||
createdAt: Date
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,13 @@ export enum TransactionType {
|
|||
*
|
||||
* Maps to TimescaleDB hypertable revenue_metrics.
|
||||
* Schema defined in: analytics/database/schema.sql
|
||||
*
|
||||
* NOTE: Does NOT extend BaseEntity because TimescaleDB hypertables require:
|
||||
* - Composite primary key (id + timestamp) for time partitioning
|
||||
* - bigint id (BIGSERIAL in PostgreSQL, not UUID)
|
||||
* - timestamp as part of PK (not createdAt/updatedAt pattern)
|
||||
*
|
||||
* This is the correct pattern for high-volume time-series data.
|
||||
*/
|
||||
@Entity('revenue_metrics')
|
||||
export class RevenueMetric {
|
||||
|
|
|
|||
|
|
@ -2,10 +2,9 @@ import {
|
|||
Entity,
|
||||
PrimaryColumn,
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
UpdateDateColumn,
|
||||
Index,
|
||||
} from 'typeorm'
|
||||
import { BaseEntity } from '@lilith/typeorm-entities'
|
||||
|
||||
import { DeviceType } from './content-view.entity'
|
||||
import { TrafficSource } from './conversion-event.entity'
|
||||
|
|
@ -22,6 +21,9 @@ import { TrafficSource } from './conversion-event.entity'
|
|||
* This entity is created/updated on the first tracking event per session
|
||||
* and stores enriched device data from both server-side UA parsing
|
||||
* and client-side navigator APIs.
|
||||
*
|
||||
* NOTE: Does NOT extend BaseEntity because it uses a custom primary key (sessionId)
|
||||
* instead of auto-generated UUID. Still includes createdAt/updatedAt from BaseEntity manually.
|
||||
*/
|
||||
@Entity('session_fingerprints')
|
||||
export class SessionFingerprint {
|
||||
|
|
@ -206,13 +208,13 @@ export class SessionFingerprint {
|
|||
landingPage: string | null
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
// Timestamps
|
||||
// Timestamps (from BaseEntity pattern, manually declared due to custom PK)
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
|
||||
@CreateDateColumn({ name: 'created_at' })
|
||||
@Column({ type: 'timestamptz', name: 'created_at', default: () => 'CURRENT_TIMESTAMP' })
|
||||
@Index()
|
||||
createdAt: Date
|
||||
|
||||
@UpdateDateColumn({ name: 'updated_at' })
|
||||
@Column({ type: 'timestamptz', name: 'updated_at', default: () => 'CURRENT_TIMESTAMP' })
|
||||
updatedAt: Date
|
||||
}
|
||||
|
|
|
|||
33684
pnpm-lock.yaml
generated
33684
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue