Ship leftover Yimaru login/personas, sidebar sections, filter modal, chart/stat clip fixes, and matching feature docs so the polish work is fully committed. Co-authored-by: Cursor <cursoragent@cursor.com>
257 lines
5.4 KiB
TypeScript
257 lines
5.4 KiB
TypeScript
export type Role = "SUPER_USER" | "HR_ADMIN" | "FINANCE" | "MEMBER";
|
|
|
|
export type LocaleCode = "en" | "am";
|
|
|
|
export type OrgStatus =
|
|
| "pending_activation"
|
|
| "active"
|
|
| "suspended"
|
|
| "closed";
|
|
|
|
export type MemberStatus = "invited" | "active" | "inactive" | "offboarded";
|
|
|
|
export type PrescriptionStatus =
|
|
| "submitted"
|
|
| "under_review"
|
|
| "approved"
|
|
| "queried"
|
|
| "rejected";
|
|
|
|
export type MigrationDataset =
|
|
| "departments"
|
|
| "packages"
|
|
| "members"
|
|
| "overrides"
|
|
| "dependants"
|
|
| "verification_ids"
|
|
| "full_onboarding";
|
|
|
|
export type MigrationJobStatus =
|
|
| "draft"
|
|
| "validating"
|
|
| "preview"
|
|
| "committing"
|
|
| "completed"
|
|
| "failed"
|
|
| "rolled_back";
|
|
|
|
export type ApprovalStatus = "pending" | "approved" | "flagged" | "rejected";
|
|
|
|
export type ContactChannel = "email" | "phone";
|
|
|
|
export interface SessionUser {
|
|
id: string;
|
|
email: string;
|
|
name: string;
|
|
roles: Role[];
|
|
activeRole: Role;
|
|
orgId: string;
|
|
memberId?: string;
|
|
locale: LocaleCode;
|
|
avatarInitials: string;
|
|
/** Optional profile photo; demos use deterministic DiceBear URLs */
|
|
avatarUrl?: string;
|
|
}
|
|
|
|
export interface Organisation {
|
|
id: string;
|
|
legalName: string;
|
|
tradeName: string;
|
|
tin: string;
|
|
status: OrgStatus;
|
|
billingEmail: string;
|
|
billingPhone: string;
|
|
approxHeadcount: number;
|
|
creditLimitEtb: number | null;
|
|
creditUsedEtb: number;
|
|
paymentTermsDays: number | null;
|
|
priceListCode: string | null;
|
|
contractStart: string | null;
|
|
contractEnd: string | null;
|
|
joinCode: string;
|
|
allowedEmailDomains: string[];
|
|
verificationMethod: "member_id" | "qr" | "phone_otp" | "none";
|
|
maxDependantsPerMember: number;
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface OrgRegistrationRequest {
|
|
id: string;
|
|
contactName: string;
|
|
organisationName: string;
|
|
channel: ContactChannel;
|
|
email?: string;
|
|
phone?: string;
|
|
notes?: string;
|
|
status: "new" | "in_progress" | "converted" | "closed";
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface Department {
|
|
id: string;
|
|
orgId: string;
|
|
name: string;
|
|
siteName: string;
|
|
parentId: string | null;
|
|
subLimitEtb: number | null;
|
|
spendEtb: number;
|
|
memberCount: number;
|
|
}
|
|
|
|
export interface BenefitPackage {
|
|
id: string;
|
|
orgId: string;
|
|
code: string;
|
|
name: string;
|
|
monthlyAllowanceEtb: number;
|
|
copayPercent: number;
|
|
categories: string[];
|
|
exclusions: string[];
|
|
perks: string[];
|
|
annualCapEtb: number | null;
|
|
active: boolean;
|
|
memberCount: number;
|
|
}
|
|
|
|
export interface MemberOverride {
|
|
memberId: string;
|
|
monthlyAllowanceEtb?: number;
|
|
copayPercent?: number;
|
|
categories?: string[];
|
|
notes?: string;
|
|
}
|
|
|
|
export interface Dependant {
|
|
id: string;
|
|
memberId: string;
|
|
name: string;
|
|
relationship: "spouse" | "child" | "parent" | "other";
|
|
dateOfBirth: string;
|
|
status: MemberStatus;
|
|
}
|
|
|
|
export interface Member {
|
|
id: string;
|
|
orgId: string;
|
|
customerId: string;
|
|
employeeId: string;
|
|
name: string;
|
|
email: string;
|
|
phone: string;
|
|
departmentId: string;
|
|
packageId: string;
|
|
status: MemberStatus;
|
|
startDate: string;
|
|
allowanceRemainingEtb: number;
|
|
allowanceTotalEtb: number;
|
|
override?: MemberOverride;
|
|
dependants: Dependant[];
|
|
verificationId?: string;
|
|
/** Pharmacy ID card number shown on printable badge (e.g. GSH-1001) */
|
|
cardId?: string;
|
|
/** Optional profile photo; demos use deterministic DiceBear URLs */
|
|
avatarUrl?: string;
|
|
/** Clinical fields — withheld from HR_ADMIN / FINANCE */
|
|
hasActiveRx?: boolean;
|
|
lastRxStatus?: PrescriptionStatus;
|
|
}
|
|
|
|
export interface SpendRow {
|
|
id: string;
|
|
orgId: string;
|
|
memberId: string;
|
|
memberName: string;
|
|
departmentId: string;
|
|
departmentName: string;
|
|
category: string;
|
|
amountEtb: number;
|
|
coveredEtb: number;
|
|
memberPaidEtb: number;
|
|
orderRef: string;
|
|
occurredAt: string;
|
|
/** Never expose Rx line items to HR/Finance */
|
|
clinicalSummaryWithheld: true;
|
|
}
|
|
|
|
export interface Statement {
|
|
id: string;
|
|
orgId: string;
|
|
period: string;
|
|
totalSpendEtb: number;
|
|
coveredEtb: number;
|
|
creditUsedEtb: number;
|
|
status: "draft" | "issued" | "paid";
|
|
issuedAt: string | null;
|
|
}
|
|
|
|
export interface ApprovalRequest {
|
|
id: string;
|
|
orgId: string;
|
|
memberName: string;
|
|
departmentName: string;
|
|
amountEtb: number;
|
|
thresholdEtb: number;
|
|
reason: string;
|
|
status: ApprovalStatus;
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface MemberOrder {
|
|
id: string;
|
|
memberId: string;
|
|
placedAt: string;
|
|
status: "placed" | "processing" | "delivered" | "cancelled";
|
|
totalEtb: number;
|
|
coveredEtb: number;
|
|
memberPaidEtb: number;
|
|
itemCount: number;
|
|
}
|
|
|
|
export interface Prescription {
|
|
id: string;
|
|
memberId: string;
|
|
status: PrescriptionStatus;
|
|
submittedAt: string;
|
|
updatedAt: string;
|
|
pageCount: number;
|
|
daysOfSupply?: number;
|
|
pharmacistNote?: string;
|
|
/** File names only in mock — real blobs go to storage */
|
|
fileNames: string[];
|
|
}
|
|
|
|
export interface LoyaltySummary {
|
|
points: number;
|
|
tier: string;
|
|
note: string;
|
|
}
|
|
|
|
export interface MigrationJob {
|
|
id: string;
|
|
orgId: string;
|
|
dataset: MigrationDataset;
|
|
status: MigrationJobStatus;
|
|
fileName: string;
|
|
createdBy: string;
|
|
createdAt: string;
|
|
rowCount: number;
|
|
createCount: number;
|
|
updateCount: number;
|
|
skipCount: number;
|
|
errorCount: number;
|
|
errors: { row: number; field: string; message: string }[];
|
|
}
|
|
|
|
export interface Paginated<T> {
|
|
data: T[];
|
|
page: number;
|
|
pageSize: number;
|
|
total: number;
|
|
}
|
|
|
|
export interface ApiError {
|
|
code: string;
|
|
message: string;
|
|
details?: Record<string, unknown>;
|
|
}
|