import { BaseEntity } from "@edr/api-common"; import { Column, Entity } from "typeorm"; /** * Whether the stored fallback rate was written by the automatic sync (after a * successful CBE fetch) or typed in by an operator in the backoffice. */ export type ExchangeFallbackSource = "AUTO" | "MANUAL"; /** * Single-row table holding the USD→ETB fallback used when the CBE endpoint is * unreachable. The live CBE rate always wins; this is only consulted on * failure, and is overwritten by every successful fetch so it tracks the last * known good rate. */ @Entity({ schema: "freight", name: "exchange_settings" }) export class ExchangeSetting extends BaseEntity { /** USD→ETB rate served while the CBE endpoint is failing. */ @Column({ name: "fallback_rate", type: "numeric", precision: 18, scale: 6, transformer: { to: (value: number) => value, from: (value: string | null) => (value === null ? null : Number(value)), }, }) fallbackRate!: number; /** `AUTO` when written by the sync, `MANUAL` when set in the backoffice. */ @Column({ name: "fallback_source", type: "varchar", length: 16, default: "AUTO", }) fallbackSource!: ExchangeFallbackSource; /** When the fallback last changed — i.e. the last successful CBE fetch. */ @Column({ name: "last_synced_at", type: "timestamptz", nullable: true }) lastSyncedAt?: Date | null; /** * Whether Djiboutian Franc may be chosen as a billing currency. * * Off by default: DJF pricing goes live only once Finance says so, so enabling it is a * deliberate act rather than something a deploy switches on. The rate itself is always * available (CBE quotes DJF in the same payload as USD) — this gates the *offer*, not * the conversion. */ @Column({ name: "djf_enabled", type: "boolean", default: false }) djfEnabled!: boolean; /** IAM user id of the last operator to set the rate manually. */ @Column({ name: "updated_by_id", type: "uuid", nullable: true }) updatedById?: string | null; }