mirror of
https://github.com/temetro/temetro.git
synced 2026-08-19 06:36:21 +00:00
Add TypeScript + Express + Postgres backend with Better Auth
Implements the first temetro backend: an Express 5 API on Postgres via Drizzle ORM, with authentication and multi-tenant clinics powered by Better Auth. - Auth: email/password with required email verification, password reset, rate limiting, CSRF/trusted-origins, secure cookies, session audit hook. - Organizations (clinics) with RBAC (owner/admin/member/viewer) and an extended `patient` permission set; member invitations by email. - Org-scoped patient records mirroring the frontend Patient shape, with CRUD endpoints gated by permission (read/write/delete). - Email helper logs links to the console when SMTP is unset (zero-setup local dev); Dockerfile + docker-compose (db + backend + frontend) with migrations applied on startup and a configurable Postgres host port. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
// Request properties populated by our auth middleware.
|
||||
declare global {
|
||||
namespace Express {
|
||||
interface Request {
|
||||
user?: {
|
||||
id: string;
|
||||
email: string;
|
||||
name: string;
|
||||
emailVerified: boolean;
|
||||
};
|
||||
session?: {
|
||||
id: string;
|
||||
userId: string;
|
||||
activeOrganizationId?: string | null;
|
||||
};
|
||||
organizationId?: string;
|
||||
memberRole?: string;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export {};
|
||||
@@ -0,0 +1,72 @@
|
||||
// Canonical patient shape — mirrors frontend/lib/patients.ts so API responses
|
||||
// can be consumed by the chat record cards without any reshaping on the client.
|
||||
|
||||
export type AllergySeverity = "mild" | "moderate" | "severe";
|
||||
export type LabFlag = "normal" | "high" | "low" | "critical";
|
||||
export type Sex = "M" | "F";
|
||||
export type PatientStatus = "active" | "inpatient" | "discharged";
|
||||
|
||||
export type Allergy = {
|
||||
substance: string;
|
||||
reaction: string;
|
||||
severity: AllergySeverity;
|
||||
};
|
||||
|
||||
export type Medication = {
|
||||
name: string;
|
||||
dose: string;
|
||||
frequency: string;
|
||||
};
|
||||
|
||||
export type Problem = {
|
||||
label: string;
|
||||
since: string;
|
||||
};
|
||||
|
||||
export type Vitals = {
|
||||
bp: string;
|
||||
hr: string;
|
||||
temp: string;
|
||||
spo2: string;
|
||||
takenAt: string;
|
||||
};
|
||||
|
||||
export type Lab = {
|
||||
name: string;
|
||||
value: string;
|
||||
flag: LabFlag;
|
||||
takenAt: string;
|
||||
};
|
||||
|
||||
export type Encounter = {
|
||||
date: string;
|
||||
type: string;
|
||||
provider: string;
|
||||
summary: string;
|
||||
};
|
||||
|
||||
// A short series for a sparkline; `points` are most-recent-last.
|
||||
export type Trend = {
|
||||
label: string;
|
||||
unit: string;
|
||||
points: number[];
|
||||
};
|
||||
|
||||
export type Patient = {
|
||||
fileNumber: string; // MRN / file number, e.g. "10293"
|
||||
name: string;
|
||||
age: number;
|
||||
sex: Sex;
|
||||
pcp: string; // primary care provider
|
||||
status: PatientStatus;
|
||||
initials: string; // for AvatarFallback
|
||||
allergies: Allergy[];
|
||||
alerts: string[];
|
||||
medications: Medication[];
|
||||
problems: Problem[];
|
||||
vitals: Vitals;
|
||||
vitalsTrend: Trend; // headline vital plotted as a sparkline
|
||||
labs: Lab[];
|
||||
labTrend: Trend; // headline lab plotted as a sparkline
|
||||
encounters: Encounter[];
|
||||
};
|
||||
Reference in New Issue
Block a user