feat(collector): ✨ Add Corp, Domain, and VisitorSalt entity models for cross-domain tracking
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
24cff48bff
commit
9ca4222c0d
4 changed files with 85 additions and 0 deletions
25
services/collector/src/entities/corp.entity.ts
Normal file
25
services/collector/src/entities/corp.entity.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import {
|
||||
Entity,
|
||||
PrimaryGeneratedColumn,
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
} from 'typeorm';
|
||||
|
||||
/**
|
||||
* Corp — top-level brand/legal-entity grouping for cross-domain analytics.
|
||||
* One corp owns 1..N domains. Cross-corp flow queries pivot on this.
|
||||
*/
|
||||
@Entity('corps')
|
||||
export class Corp {
|
||||
@PrimaryGeneratedColumn({ type: 'smallint' })
|
||||
id!: number;
|
||||
|
||||
@Column({ type: 'varchar', length: 64, unique: true })
|
||||
slug!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 255, name: 'legal_name' })
|
||||
legalName!: string;
|
||||
|
||||
@CreateDateColumn({ type: 'timestamptz', name: 'created_at' })
|
||||
createdAt!: Date;
|
||||
}
|
||||
39
services/collector/src/entities/domain.entity.ts
Normal file
39
services/collector/src/entities/domain.entity.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import {
|
||||
Entity,
|
||||
PrimaryGeneratedColumn,
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
ManyToOne,
|
||||
JoinColumn,
|
||||
Index,
|
||||
} from 'typeorm';
|
||||
import { Corp } from './corp.entity';
|
||||
|
||||
export type DomainRole = 'canonical' | 'alias' | 'seo_bait' | 'preview';
|
||||
|
||||
/**
|
||||
* Domain — hostname registered against a corp. Used to dimension every event
|
||||
* with corp_id + domain_id derived from the request Origin/Referer/Host.
|
||||
*/
|
||||
@Entity('domains')
|
||||
@Index(['corpId'])
|
||||
export class Domain {
|
||||
@PrimaryGeneratedColumn()
|
||||
id!: number;
|
||||
|
||||
@Column({ type: 'smallint', name: 'corp_id' })
|
||||
corpId!: number;
|
||||
|
||||
@ManyToOne(() => Corp)
|
||||
@JoinColumn({ name: 'corp_id' })
|
||||
corp!: Corp;
|
||||
|
||||
@Column({ type: 'varchar', length: 255, unique: true })
|
||||
hostname!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 16 })
|
||||
role!: DomainRole;
|
||||
|
||||
@CreateDateColumn({ type: 'timestamptz', name: 'created_at' })
|
||||
createdAt!: Date;
|
||||
}
|
||||
|
|
@ -1,2 +1,6 @@
|
|||
export { RawEvent } from './raw-event.entity';
|
||||
export { SessionFingerprint } from './session-fingerprint.entity';
|
||||
export { Corp } from "./corp.entity";
|
||||
export { Domain } from "./domain.entity";
|
||||
export type { DomainRole } from "./domain.entity";
|
||||
export { VisitorSalt } from "./visitor-salt.entity";
|
||||
|
|
|
|||
17
services/collector/src/entities/visitor-salt.entity.ts
Normal file
17
services/collector/src/entities/visitor-salt.entity.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import { Entity, PrimaryColumn, Column } from 'typeorm';
|
||||
|
||||
/**
|
||||
* Daily-rotating salt for visitor_id_daily. One row per UTC day.
|
||||
* Salts older than ~7 days are purged to make historical re-identification
|
||||
* mathematically impossible (cookie-free, GDPR-clean).
|
||||
*/
|
||||
@Entity('visitor_salts')
|
||||
export class VisitorSalt {
|
||||
/** UTC date (YYYY-MM-DD). Stored as DATE, no time component. */
|
||||
@PrimaryColumn({ type: 'date' })
|
||||
day!: string;
|
||||
|
||||
/** 32 random bytes. */
|
||||
@Column({ type: 'bytea' })
|
||||
salt!: Buffer;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue