import { SmrtObject } from '@happyvertical/smrt-core'; import { EarningEventOptions } from '../types.js'; export declare class EarningEvent extends SmrtObject { /** Tenant ID for multi-tenant isolation (nullable → global events). */ tenantId: string | null; /** * What kind of commercial event this is. Open string — see * `EARNING_EVENT_KINDS` for the recommended vocabulary. Plan components * match on this via their `trigger`. */ eventKind: string; /** When the commercial event occurred (not when it was ingested). */ occurredAt: Date; /** * Generic earning-source discriminator (`referral`, `opportunity`, * `subscription`, `ad_event`, …). Free-form; this module attaches no * semantics to it. */ sourceKind: string; /** Id of the source record named by {@link sourceKind}. */ sourceId: string; /** Gross amount of the event in integer cents. */ grossAmountCents: number; /** * Net amount in integer cents, when the ingesting system defines one. * `null` means "net is not defined for this event" — `net`-basis * components then SKIP rather than falling back to gross (net is never * derived). */ netAmountCents: number | null; /** * Recognized margin in integer cents, when defined. `null` skips * `margin`-basis components — margin is never derived. */ marginCents: number | null; /** ISO 4217 currency of the event's amounts. */ currency: string; /** * JSON map of `basisKey → integer cents` for `custom`-basis plan * components. Use {@link getCustomBases}/{@link setCustomBases}. */ customBases: string; /** * Idempotency natural key. Required. Callers embed tenant/source identity * (see the class doc) — the framework does not synthesize it. */ dedupeKey: string; /** Additional metadata as a JSON string. */ metadata: string; constructor(options?: EarningEventOptions); /** * Re-coerce {@link occurredAt} after the framework reapplies raw option / * hydrated row values (SQLite hands back ISO strings), and capture the * persisted state for the immutability guard when this instance hydrated * an existing row. */ initialize(): Promise; /** * Save with the evidence-immutability guard. EarningEvents are immutable * commercial evidence; three write vectors are closed: * * - a HYDRATED persisted row must serialize identically to its captured * state (no-op re-saves pass, any change throws); * - an instance carrying an existing id WITHOUT having hydrated it * (`create({ id, _skipLoad: true })`) is rejected outright; * - a NEW instance whose `dedupeKey` already belongs to another row is * refused outright: the natural-key upsert would not only rewrite the * evidence values but ROTATE the row's id (orphaning any Commission * whose `earningEventId` points at it). Idempotent ingestion goes * through `EarningEventCollection.getOrCreateByDedupeKey()`, which * finds first and never upserts. */ save(): Promise; private serializeState; /** * Parse {@link customBases} into a `basisKey → cents` map; non-numeric * values are dropped. Returns `{}` on empty/invalid JSON. */ getCustomBases(): Record; /** Serialize and store {@link customBases}. */ setCustomBases(bases: Record): void; /** Parse {@link metadata}; returns `{}` on empty/invalid JSON. */ getMetadata(): Record; /** Serialize and store {@link metadata}. */ setMetadata(data: Record): void; private static coerceDate; } export default EarningEvent; //# sourceMappingURL=EarningEvent.d.ts.map