Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x | import {
Column,
CreateDateColumn,
Entity,
Index,
PrimaryGeneratedColumn,
} from 'typeorm';
/**
* Append-only projection of the Kafka stream. The bigserial id doubles as the
* feed cursor: monotonic, gapless enough for keyset pagination, and cheap.
* (Contrast with the services' UUID keys: an internal, single-writer,
* append-only table is exactly where serial keys shine.)
*/
@Entity('audit_events')
export class AuditEvent {
@PrimaryGeneratedColumn({ type: 'bigint' })
id!: string;
// The consumer's idempotency key: at-least-once delivery means the same
// event WILL arrive twice; the unique index makes the second insert a no-op.
@Index({ unique: true })
@Column({ name: 'event_id', type: 'uuid' })
eventId!: string;
@Column({ name: 'event_type', length: 50 })
eventType!: string;
@Index()
@Column({ name: 'work_order_id', type: 'uuid' })
workOrderId!: string;
@Column({ name: 'property_id', type: 'uuid' })
propertyId!: string;
@Column({
name: 'correlation_id',
type: 'varchar',
length: 64,
nullable: true,
})
correlationId!: string | null;
/** Who performed the action (JWT subject) — null for system-initiated
* events (AI triage) and events from before authentication existed. */
@Column({ name: 'actor_id', type: 'varchar', length: 320, nullable: true })
actorId!: string | null;
@Column({ name: 'occurred_at', type: 'timestamptz' })
occurredAt!: Date;
@Column({ type: 'jsonb' })
payload!: Record<string, unknown>;
@CreateDateColumn({ name: 'recorded_at', type: 'timestamptz' })
recordedAt!: Date;
}
|