Function bodies 223 total
handle_subscription_deleted function · python · L186-L217 (32 LOC)app/services/stripe_billing.py
async def handle_subscription_deleted(db: AsyncSession, event_data: dict) -> None:
"""
Handle customer.subscription.deleted — subscription canceled or expired.
Downgrades user to free tier (does NOT delete the subscription row).
"""
sub_obj = event_data.get("object", {})
stripe_sub_id = sub_obj.get("id")
sub = await db.scalar(
select(Subscription).where(Subscription.stripe_subscription_id == stripe_sub_id)
)
if not sub:
log.warning("stripe_sub_delete_not_found", stripe_sub_id=stripe_sub_id)
return
sub.status = "canceled"
sub.tier = "free"
sub.stripe_subscription_id = None
sub.stripe_price_id = None
sub.cancel_at_period_end = False
await db.flush()
await write_audit_event(
db,
action="subscription_canceled",
user_id=sub.user_id,
resource_type="subscription",
resource_id=sub.id,
)
log.info("stripe_subscription_canceled", sub_id=str(sub.id), user_id=process_webhook_event function · python · L229-L240 (12 LOC)app/services/stripe_billing.py
async def process_webhook_event(
db: AsyncSession, event_type: str, event_data: dict
) -> bool:
"""
Dispatch a Stripe webhook event to the appropriate handler.
Returns True if handled, False if event type is not relevant.
"""
handler = WEBHOOK_HANDLERS.get(event_type)
if not handler:
return False
await handler(db, event_data)
return Truecreate_checkout_session function · python · L245-L327 (83 LOC)app/services/stripe_billing.py
async def create_checkout_session(
db: AsyncSession,
user: "User",
price_id: str,
success_url: str,
cancel_url: str,
) -> str:
"""
Create a Stripe checkout session for subscription upgrade.
If the user doesn't have a stripe_customer_id, create a Stripe customer first.
Args:
db: Database session
user: Current authenticated user
price_id: Stripe price ID for the plan
success_url: URL to redirect on successful checkout
cancel_url: URL to redirect if user cancels
Returns:
Stripe checkout session URL
Raises:
HTTPException: If Stripe is not configured or API call fails
"""
if not settings.stripe_secret_key or settings.stripe_secret_key == "sk_test_REPLACE":
log.error("stripe_not_configured")
from fastapi import HTTPException, status
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail="Stripe is not configured"create_portal_session function · python · L330-L393 (64 LOC)app/services/stripe_billing.py
async def create_portal_session(
db: AsyncSession,
user: "User",
return_url: str,
) -> str:
"""
Create a Stripe customer portal session for subscription management.
Args:
db: Database session
user: Current authenticated user
return_url: URL to return to after portal session
Returns:
Stripe customer portal session URL
Raises:
HTTPException: If Stripe is not configured or user has no customer ID
"""
if not settings.stripe_secret_key or settings.stripe_secret_key == "sk_test_REPLACE":
log.error("stripe_not_configured")
from fastapi import HTTPException, status
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail="Stripe is not configured",
)
if not user.stripe_customer_id:
log.warning("portal_session_no_customer", user_id=str(user.id))
from fastapi import HTTPException, status
raise HTTPException(
_build_structured_system_prompt function · python · L71-L79 (9 LOC)app/services/structured_generation.py
def _build_structured_system_prompt(language: str = "en") -> str:
"""Combine clinical system prompt with JSON output instructions.
Uses the language-appropriate system prompt (EN or ES) so the model
receives clinical documentation guidance in the target language.
"""
schema_str = get_structured_note_json_instruction()
base_prompt = get_system_prompt(language)
return base_prompt + STRUCTURED_OUTPUT_INSTRUCTION.format(schema=schema_str)StructuredGenerationError class · python · L82-L88 (7 LOC)app/services/structured_generation.py
class StructuredGenerationError(Exception):
"""Raised when structured generation fails parsing or validation."""
def __init__(self, message: str, raw_output: str | None = None):
self.message = message
self.raw_output = raw_output
super().__init__(message)__init__ method · python · L85-L88 (4 LOC)app/services/structured_generation.py
def __init__(self, message: str, raw_output: str | None = None):
self.message = message
self.raw_output = raw_output
super().__init__(message)Powered by Repobility — scan your code at https://repobility.com
generate_structured_note function · python · L91-L175 (85 LOC)app/services/structured_generation.py
async def generate_structured_note(
input_text: str,
note_type: str,
specialty: str = "internal_medicine",
language: str = "en",
) -> tuple[StructuredNote, dict]:
"""
Generate a validated structured note via OpenAI JSON mode.
Args:
input_text: Raw physician dictation / transcript.
note_type: One of the supported note types.
specialty: Physician specialty (default: internal_medicine).
Returns:
Tuple of (StructuredNote, generation_metadata).
Metadata keys: model_used, prompt_version, schema_version,
tokens_used, generation_time_ms.
Raises:
StructuredGenerationError: If JSON parsing or Pydantic validation fails.
"""
user_prompt = build_prompt(
input_text=input_text,
note_type=note_type,
specialty=specialty,
language=language,
)
system_prompt = _build_structured_system_prompt(language=language)
temperature = NOTE_TYPE_TEMPERATURETranscriptionError class · python · L17-L22 (6 LOC)app/services/transcription.py
class TranscriptionError(Exception):
"""Transcription service error. Mirrors NoteError pattern."""
def __init__(self, message: str, status_code: int = 400):
self.message = message
self.status_code = status_code
super().__init__(message)__init__ method · python · L19-L22 (4 LOC)app/services/transcription.py
def __init__(self, message: str, status_code: int = 400):
self.message = message
self.status_code = status_code
super().__init__(message)transcribe_audio function · python · L25-L139 (115 LOC)app/services/transcription.py
async def transcribe_audio(
audio_data: bytes,
filename: str,
language: str = "en",
) -> tuple[str, dict]:
"""
Transcribe audio using OpenAI Whisper API.
Args:
audio_data: Raw audio bytes (transient, never persisted or logged)
filename: Original filename (used for validation, not storage)
language: ISO 639-1 language code ('en', 'es', etc.). Defaults to 'en'.
Used as a hint for Whisper; does not restrict output.
Returns:
(transcription_text, metadata_dict)
where metadata_dict contains:
- 'language': detected language (ISO 639-1 code)
- 'model': model name used (e.g., 'whisper-1')
- 'audio_length_seconds': estimated duration (best-effort, may be None)
Raises:
TranscriptionError: on invalid audio, unsupported format, network error, timeout, etc.
Warning:
Audio data is transient — never logged, never persisted.
Transcription accuracywrite_audit_event function · python · L9-L40 (32 LOC)app/utils/audit.py
async def write_audit_event(
db: AsyncSession,
*,
action: str,
user_id: uuid.UUID | None = None,
resource_type: str | None = None,
resource_id: uuid.UUID | None = None,
metadata: dict[str, Any] | None = None,
ip_address: str | None = None,
) -> None:
"""
Write a structured audit event to the database.
Never raises — audit failures must not block primary operations.
PHI must NOT be passed in metadata. Use resource IDs only.
"""
try:
event = AuditEvent(
user_id=user_id,
action=action,
resource_type=resource_type,
resource_id=resource_id,
metadata_=metadata or {},
ip_address=ip_address,
)
db.add(event)
# Flush without committing — the calling request's session will commit
await db.flush([event])
except Exception:
# Audit failures are logged but never raised
import structlog
log = structlog.get_lo_is_phi_key function · python · L28-L31 (4 LOC)app/utils/logging.py
def _is_phi_key(key: str) -> bool:
"""Return True if *key* contains any PHI-sensitive fragment."""
lower = key.lower()
return any(fragment in lower for fragment in _PHI_KEY_FRAGMENTS)_redact_value function · python · L34-L41 (8 LOC)app/utils/logging.py
def _redact_value(value: object) -> object:
"""Recursively redact PHI from dicts; leave other types as-is."""
if isinstance(value, dict):
return {
k: "[REDACTED]" if _is_phi_key(k) else _redact_value(v)
for k, v in value.items()
}
return valueredact_phi function · python · L44-L64 (21 LOC)app/utils/logging.py
def redact_phi(
logger: object,
method_name: str,
event_dict: dict,
) -> dict:
"""
structlog processor that replaces PHI-bearing values with ``[REDACTED]``.
Any top-level or nested key whose name contains one of the sensitive
fragments is replaced. The ``event`` key (structlog's default message
key) is intentionally NOT matched against "message" so that ordinary
log lines like ``log.info("startup")`` pass through unchanged.
"""
return {
k: (
"[REDACTED]"
if _is_phi_key(k)
else _redact_value(v)
)
for k, v in event_dict.items()
}Provenance: Repobility (https://repobility.com) — every score reproducible from /scan/
configure_logging function · python · L67-L111 (45 LOC)app/utils/logging.py
def configure_logging(
log_level: str = "INFO",
is_production: bool = False,
) -> None:
"""
Configure structlog (and stdlib logging) for the application.
Args:
log_level: Root log level string (e.g. "INFO", "DEBUG").
is_production: When True, use JSONRenderer; otherwise ConsoleRenderer.
"""
shared_processors: list[structlog.types.Processor] = [
structlog.contextvars.merge_contextvars,
structlog.stdlib.add_log_level,
structlog.processors.TimeStamper(fmt="iso", utc=True),
redact_phi,
structlog.stdlib.ProcessorFormatter.wrap_for_formatter,
]
if is_production:
renderer = structlog.processors.JSONRenderer()
else:
renderer = structlog.dev.ConsoleRenderer()
formatter = structlog.stdlib.ProcessorFormatter(
processors=[
structlog.stdlib.ProcessorFormatter.remove_processors_meta,
renderer,
],
)
handler = logging.StreamHandler()
_footer_text function · python · L44-L47 (4 LOC)app/utils/pdf_export.py
def _footer_text(language: str) -> str:
if language and language.lower().startswith("es"):
return _FOOTER_ES
return _FOOTER_EN_PageCallback class · python · L50-L79 (30 LOC)app/utils/pdf_export.py
class _PageCallback:
"""Callable that draws header rule, page numbers, and footer on every page."""
def __init__(self, footer: str):
self.footer = footer
def __call__(self, canvas, doc):
canvas.saveState()
page_w, page_h = doc.pagesize
# ── Footer: draft disclaimer ─────────────────────────────────
canvas.setFont("Helvetica-Oblique", 7)
canvas.setFillColor(HexColor("#555555"))
canvas.drawCentredString(
page_w / 2,
0.45 * inch,
self.footer,
)
# ── Page number ──────────────────────────────────────────────
canvas.setFont("Helvetica", 8)
canvas.setFillColor(HexColor("#888888"))
page_num = canvas.getPageNumber()
canvas.drawRightString(
page_w - 1.0 * inch,
0.45 * inch,
f"Page {page_num}",
)
canvas.restoreState()__call__ method · python · L56-L79 (24 LOC)app/utils/pdf_export.py
def __call__(self, canvas, doc):
canvas.saveState()
page_w, page_h = doc.pagesize
# ── Footer: draft disclaimer ─────────────────────────────────
canvas.setFont("Helvetica-Oblique", 7)
canvas.setFillColor(HexColor("#555555"))
canvas.drawCentredString(
page_w / 2,
0.45 * inch,
self.footer,
)
# ── Page number ──────────────────────────────────────────────
canvas.setFont("Helvetica", 8)
canvas.setFillColor(HexColor("#888888"))
page_num = canvas.getPageNumber()
canvas.drawRightString(
page_w - 1.0 * inch,
0.45 * inch,
f"Page {page_num}",
)
canvas.restoreState()_PageCallbackWithTotal class · python · L82-L112 (31 LOC)app/utils/pdf_export.py
class _PageCallbackWithTotal(_PageCallback):
"""Second-pass callback that includes 'Page X of Y'."""
def __init__(self, footer: str, total_pages: int):
super().__init__(footer)
self.total_pages = total_pages
def __call__(self, canvas, doc):
canvas.saveState()
page_w, page_h = doc.pagesize
# Footer
canvas.setFont("Helvetica-Oblique", 7)
canvas.setFillColor(HexColor("#555555"))
canvas.drawCentredString(
page_w / 2,
0.45 * inch,
self.footer,
)
# Page X of Y
canvas.setFont("Helvetica", 8)
canvas.setFillColor(HexColor("#888888"))
page_num = canvas.getPageNumber()
canvas.drawRightString(
page_w - 1.0 * inch,
0.45 * inch,
f"Page {page_num} of {self.total_pages}",
)
canvas.restoreState()__init__ method · python · L85-L87 (3 LOC)app/utils/pdf_export.py
def __init__(self, footer: str, total_pages: int):
super().__init__(footer)
self.total_pages = total_pages__call__ method · python · L89-L112 (24 LOC)app/utils/pdf_export.py
def __call__(self, canvas, doc):
canvas.saveState()
page_w, page_h = doc.pagesize
# Footer
canvas.setFont("Helvetica-Oblique", 7)
canvas.setFillColor(HexColor("#555555"))
canvas.drawCentredString(
page_w / 2,
0.45 * inch,
self.footer,
)
# Page X of Y
canvas.setFont("Helvetica", 8)
canvas.setFillColor(HexColor("#888888"))
page_num = canvas.getPageNumber()
canvas.drawRightString(
page_w - 1.0 * inch,
0.45 * inch,
f"Page {page_num} of {self.total_pages}",
)
canvas.restoreState()_escape_xml function · python · L115-L121 (7 LOC)app/utils/pdf_export.py
def _escape_xml(text: str) -> str:
"""Escape XML special characters for ReportLab Paragraph."""
return (
text.replace("&", "&")
.replace("<", "<")
.replace(">", ">")
)Open data scored by Repobility · https://repobility.com
render_note_pdf function · python · L124-L201 (78 LOC)app/utils/pdf_export.py
def render_note_pdf(
output_text: str,
note_type: str = "",
model_used: str = "",
prompt_version: str = "",
draft_id: str = "",
patient_context: str = "",
language: str = "en",
) -> bytes:
"""Render a clinical note as a physician-ready PDF and return the bytes.
Parameters
----------
output_text : str
The rendered clinical note text.
note_type : str
Internal note type key (e.g. ``"soap_admission"``).
model_used, prompt_version, draft_id : str
Metadata for the PDF header.
patient_context : str
Optional patient context line from the NoteSession.
language : str
Language code (``"en"`` or ``"es"``). Controls footer language.
"""
footer = _footer_text(language)
# ── First pass: build to count pages ─────────────────────────────
buf_count = BytesIO()
first_pass_cb = _PageCallback(footer)
doc_count = SimpleDocTemplate(
buf_count,
pagesize=letter,
_build_story function · python · L206-L382 (177 LOC)app/utils/pdf_export.py
def _build_story(
*,
output_text: str,
note_type: str,
model_used: str,
prompt_version: str,
draft_id: str,
patient_context: str,
) -> list:
"""Build the platypus story (list of flowables) for the PDF."""
styles = getSampleStyleSheet()
# ── Styles ────────────────────────────────────────────────────────
logo_style = ParagraphStyle(
"Logo",
parent=styles["Normal"],
fontName="Helvetica-Bold",
fontSize=14,
alignment=TA_LEFT,
textColor=HexColor("#1a1a1a"),
spaceAfter=2,
)
note_type_style = ParagraphStyle(
"NoteType",
parent=styles["Normal"],
fontName="Helvetica-Bold",
fontSize=13,
alignment=TA_LEFT,
textColor=HexColor("#333333"),
spaceAfter=4,
)
patient_style = ParagraphStyle(
"PatientContext",
parent=styles["Normal"],
fontName="Helvetica",
fontSize=10,
alignment=TA_LEFT,
verify_password function · python · L21-L25 (5 LOC)app/utils/security.py
def verify_password(plain: str, hashed: str) -> bool:
try:
return _ph.verify(hashed, plain)
except (VerifyMismatchError, VerificationError, InvalidHashError):
return Falsecreate_access_token function · python · L34-L41 (8 LOC)app/utils/security.py
def create_access_token(data: dict[str, Any]) -> str:
payload = data.copy()
payload["jti"] = str(uuid.uuid4())
payload["exp"] = datetime.now(timezone.utc) + timedelta(
minutes=settings.jwt_expiry_minutes
)
payload["iat"] = datetime.now(timezone.utc)
return jwt.encode(payload, settings.jwt_secret, algorithm="HS256")decode_access_token function · python · L44-L50 (7 LOC)app/utils/security.py
def decode_access_token(token: str) -> dict[str, Any]:
"""
Returns decoded payload.
Raises jwt.PyJWTError (ExpiredSignatureError, InvalidTokenError) on failure.
Caller is responsible for handling.
"""
return jwt.decode(token, settings.jwt_secret, algorithms=["HS256"])BillingShell function · typescript · L10-L52 (43 LOC)frontend/src/app/billing/layout.tsx
function BillingShell({ children }: { children: React.ReactNode }) {
const { isAuthenticated, isLoading } = useAuth();
const router = useRouter();
useEffect(() => {
if (!isLoading && !isAuthenticated) {
router.push("/login");
}
}, [isAuthenticated, isLoading, router]);
if (isLoading) {
return (
<div className="flex min-h-screen items-center justify-center bg-medical-surface">
<div className="flex flex-col items-center gap-3">
<Loader2 className="h-8 w-8 animate-spin text-brand-600" />
<p className="text-sm text-medical-muted">Loading...</p>
</div>
</div>
);
}
if (!isAuthenticated) {
return null;
}
return (
<div className="flex min-h-screen flex-col">
<Navbar />
<div className="flex flex-1">
<div className="hidden lg:block">
<div className="sticky top-14 h-[calc(100vh-3.5rem)]">
<Sidebar />
</div>
</div>
<main className="BillingLayout function · typescript · L54-L64 (11 LOC)frontend/src/app/billing/layout.tsx
export default function BillingLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<AuthProvider>
<BillingShell>{children}</BillingShell>
</AuthProvider>
);
}formatDate function · typescript · L51-L58 (8 LOC)frontend/src/app/billing/page.tsx
function formatDate(dateString: string): string {
const date = new Date(dateString);
return date.toLocaleDateString("en-US", {
month: "long",
day: "numeric",
year: "numeric",
});
}Want this analysis on your repo? https://repobility.com/scan/
BillingPage function · typescript · L60-L415 (356 LOC)frontend/src/app/billing/page.tsx
export default function BillingPage() {
const [subscription, setSubscription] = useState<SubscriptionStatus | null>(
null,
);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [upgrading, setUpgrading] = useState(false);
const [managingBilling, setManagingBilling] = useState(false);
const fetchSubscription = useCallback(async () => {
setLoading(true);
setError(null);
try {
const { data } = await api.get<SubscriptionStatus>(
"/stripe/subscription",
);
setSubscription(data);
} catch (err: unknown) {
const axiosErr = err as { response?: { status?: number; data?: { detail?: string } } };
if (axiosErr?.response?.status === 503) {
// Stripe not configured — show free tier info without error
setSubscription({
tier: "free",
status: "active",
cancel_at_period_end: false,
current_period_end: null,
notDashboardShell function · typescript · L11-L53 (43 LOC)frontend/src/app/dashboard/layout.tsx
function DashboardShell({ children }: { children: React.ReactNode }) {
const { isAuthenticated, isLoading } = useAuth();
const router = useRouter();
useEffect(() => {
if (!isLoading && !isAuthenticated) {
router.push("/login");
}
}, [isAuthenticated, isLoading, router]);
if (isLoading) {
return (
<div className="flex min-h-screen items-center justify-center bg-medical-surface">
<div className="flex flex-col items-center gap-3">
<Loader2 className="h-8 w-8 animate-spin text-brand-600" />
<p className="text-sm text-medical-muted">Loading...</p>
</div>
</div>
);
}
if (!isAuthenticated) {
return null;
}
return (
<div className="flex min-h-screen flex-col">
<Navbar />
<div className="flex flex-1">
<div className="hidden lg:block">
<div className="sticky top-14 h-[calc(100vh-3.5rem)]">
<Sidebar />
</div>
</div>
<main classNameDashboardLayout function · typescript · L55-L67 (13 LOC)frontend/src/app/dashboard/layout.tsx
export default function DashboardLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<ErrorBoundary>
<AuthProvider>
<DashboardShell>{children}</DashboardShell>
</AuthProvider>
</ErrorBoundary>
);
}DashboardPage function · typescript · L12-L152 (141 LOC)frontend/src/app/dashboard/page.tsx
export default function DashboardPage() {
const { user } = useAuth();
const [sessions, setSessions] = useState<NoteSession[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const tier: SubscriptionTier = user?.subscription?.tier || "free";
const fetchSessions = useCallback(async () => {
setLoading(true);
setError(null);
try {
const { data } = await api.get<NoteSession[]>("/notes/sessions");
setSessions(data);
} catch (err: unknown) {
const axiosErr = err as { response?: { data?: { detail?: string } } };
setError(
axiosErr?.response?.data?.detail ||
"Failed to load sessions. Please try again.",
);
} finally {
setLoading(false);
}
}, []);
useEffect(() => {
fetchSessions();
}, [fetchSessions]);
const draftCount = sessions.filter((s) => s.status === "draft").length;
const completeCount = sessions.filter((s) => s.status === DeIdPage function · typescript · L41-L248 (208 LOC)frontend/src/app/deid/page.tsx
export default function DeIdPage() {
const [inputText, setInputText] = useState("");
const [result, setResult] = useState<DeIdResult | null>(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [copied, setCopied] = useState(false);
const handleScan = async () => {
if (!inputText.trim()) {
setError("Please enter some text to scan.");
return;
}
setLoading(true);
setError(null);
try {
const { data } = await api.post<DeIdResult>("/deid", {
text: inputText,
});
setResult(data);
} catch (err: unknown) {
const axiosErr = err as {
response?: { data?: { detail?: string } };
};
setError(
axiosErr?.response?.data?.detail ||
"Failed to scan for PHI. Please try again."
);
} finally {
setLoading(false);
}
};
const handleCopyRedacted = async () => {
if (!result?.redacted_text) return;
tRootLayout function · typescript · L41-L51 (11 LOC)frontend/src/app/layout.tsx
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en" className={inter.variable}>
<body className={`${inter.className} min-h-screen`}>{children}</body>
</html>
);
}LoginForm function · typescript · L10-L138 (129 LOC)frontend/src/app/login/page.tsx
function LoginForm() {
const { login, isLoading, error, clearError } = useAuth();
const [showPassword, setShowPassword] = useState(false);
const {
register,
handleSubmit,
formState: { errors },
} = useForm<UserLogin>();
const onSubmit = async (data: UserLogin) => {
clearError();
await login(data);
};
return (
<div className="flex min-h-screen items-center justify-center bg-medical-surface px-4">
<div className="w-full max-w-md">
<div className="mb-8 text-center">
<Link href="/" className="inline-flex items-center gap-2">
<Stethoscope className="h-8 w-8 text-brand-600" />
<span className="text-2xl font-semibold text-medical-dark">
MedScribe AI
</span>
</Link>
<p className="mt-2 text-sm text-medical-muted">
Sign in to your account
</p>
</div>
<div className="card p-6">
{error && (
<div classNameLoginPage function · typescript · L140-L146 (7 LOC)frontend/src/app/login/page.tsx
export default function LoginPage() {
return (
<AuthProvider>
<LoginForm />
</AuthProvider>
);
}Powered by Repobility — scan your code at https://repobility.com
NoteDetailPage function · typescript · L23-L391 (369 LOC)frontend/src/app/notes/[id]/page.tsx
export default function NoteDetailPage() {
const params = useParams();
const router = useRouter();
const sessionId = params.id as string;
const [session, setSession] = useState<NoteSession | null>(null);
const [currentDraft, setCurrentDraft] = useState<NoteDraft | null>(null);
const [editedText, setEditedText] = useState("");
const [loading, setLoading] = useState(true);
const [saving, setSaving] = useState(false);
const [regenerating, setRegenerating] = useState(false);
const [error, setError] = useState<string | null>(null);
const [saveSuccess, setSaveSuccess] = useState(false);
const [hasEdits, setHasEdits] = useState(false);
const [deleting, setDeleting] = useState(false);
const fetchSession = useCallback(async () => {
setLoading(true);
setError(null);
try {
const { data } = await api.get<NoteSession>(
`/notes/sessions/${sessionId}`,
);
setSession(data);
const latest =
data.drafts && data.drafts.lengtNotesShell function · typescript · L11-L53 (43 LOC)frontend/src/app/notes/layout.tsx
function NotesShell({ children }: { children: React.ReactNode }) {
const { isAuthenticated, isLoading } = useAuth();
const router = useRouter();
useEffect(() => {
if (!isLoading && !isAuthenticated) {
router.push("/login");
}
}, [isAuthenticated, isLoading, router]);
if (isLoading) {
return (
<div className="flex min-h-screen items-center justify-center bg-medical-surface">
<div className="flex flex-col items-center gap-3">
<Loader2 className="h-8 w-8 animate-spin text-brand-600" />
<p className="text-sm text-medical-muted">Loading...</p>
</div>
</div>
);
}
if (!isAuthenticated) {
return null;
}
return (
<div className="flex min-h-screen flex-col">
<Navbar />
<div className="flex flex-1">
<div className="hidden lg:block">
<div className="sticky top-14 h-[calc(100vh-3.5rem)]">
<Sidebar />
</div>
</div>
<main className="flNotesLayout function · typescript · L55-L67 (13 LOC)frontend/src/app/notes/layout.tsx
export default function NotesLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<ErrorBoundary>
<AuthProvider>
<NotesShell>{children}</NotesShell>
</AuthProvider>
</ErrorBoundary>
);
}NewNotePage function · typescript · L44-L428 (385 LOC)frontend/src/app/notes/new/page.tsx
export default function NewNotePage() {
const router = useRouter();
const [step, setStep] = useState<"setup" | "input" | "result">("setup");
const [generating, setGenerating] = useState(false);
const [error, setError] = useState<string | null>(null);
const [generatedNote, setGeneratedNote] = useState<string>("");
const [sessionId, setSessionId] = useState<string | null>(null);
const [genStats, setGenStats] = useState<{
tokens: number;
timeMs: number;
model: string;
} | null>(null);
const {
register,
handleSubmit,
watch,
formState: { errors },
setValue,
} = useForm<NoteFormData>({
defaultValues: {
note_type: "progress_note",
language: "en",
patient_context: "",
input_text: "",
},
});
// Check for prefilled text from transcription
useEffect(() => {
if (typeof window !== "undefined") {
const prefilledText = sessionStorage.getItem(
"medscribe_prefilled_text"
);
const prNotFound function · typescript · L3-L42 (40 LOC)frontend/src/app/not-found.tsx
export default function NotFound() {
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50">
<div className="text-center px-6 max-w-md">
<div className="mb-6">
<span className="text-6xl font-bold text-blue-800">404</span>
</div>
<h1 className="text-2xl font-semibold text-gray-900 mb-3">
Page not found
</h1>
<p className="text-gray-600 mb-8">
The page you're looking for doesn't exist or has been moved.
</p>
<div className="flex flex-col sm:flex-row gap-3 justify-center">
<Link
href="/dashboard"
className="inline-flex items-center justify-center px-5 py-2.5 bg-blue-800 text-white font-medium rounded-lg hover:bg-blue-700 transition-colors"
>
Go to Dashboard
</Link>
<Link
href="/"
className="inline-flex items-center justify-center px-5 py-2.5 border border-gray-300 tePrivacyPolicyPage function · typescript · L6-L241 (236 LOC)frontend/src/app/privacy/page.tsx
export default function PrivacyPolicyPage() {
return (
<div className="min-h-screen bg-white">
{/* Header */}
<header className="border-b border-medical-border bg-white">
<div className="mx-auto max-w-4xl px-4 sm:px-6 lg:px-8">
<div className="flex h-16 items-center justify-between">
<Link href="/" className="flex items-center gap-2">
<Stethoscope className="h-7 w-7 text-brand-600" />
<span className="text-xl font-semibold text-medical-dark">
MedScribe AI
</span>
</Link>
<Link href="/" className="btn-ghost gap-2">
<ArrowLeft className="h-4 w-4" />
Back
</Link>
</div>
</div>
</header>
<main className="mx-auto max-w-4xl px-4 py-16 sm:px-6 lg:px-8">
<h1 className="text-4xl font-bold text-medical-dark">Privacy Policy</h1>
<p className="mt-2 text-sm text-medical-muted">
RegisterForm function · typescript · L32-L309 (278 LOC)frontend/src/app/register/page.tsx
function RegisterForm() {
const { register: registerUser, isLoading, error, clearError } = useAuth();
const [showPassword, setShowPassword] = useState(false);
const {
register,
handleSubmit,
formState: { errors },
watch,
} = useForm<UserCreate & { confirm_password: string; agree_terms: boolean }>({
defaultValues: {
specialty: "internal_medicine",
},
});
const password = watch("password");
const onSubmit = async (data: UserCreate & { confirm_password: string; agree_terms: boolean }) => {
clearError();
const { confirm_password, agree_terms, ...userData } = data;
void confirm_password;
void agree_terms;
await registerUser(userData);
};
return (
<div className="flex min-h-screen items-center justify-center bg-medical-surface px-4 py-8">
<div className="w-full max-w-md">
<div className="mb-8 text-center">
<Link href="/" className="inline-flex items-center gap-2">
<Stethoscope clasRegisterPage function · typescript · L311-L317 (7 LOC)frontend/src/app/register/page.tsx
export default function RegisterPage() {
return (
<AuthProvider>
<RegisterForm />
</AuthProvider>
);
}Provenance: Repobility (https://repobility.com) — every score reproducible from /scan/
SettingsShell function · typescript · L10-L52 (43 LOC)frontend/src/app/settings/layout.tsx
function SettingsShell({ children }: { children: React.ReactNode }) {
const { isAuthenticated, isLoading } = useAuth();
const router = useRouter();
useEffect(() => {
if (!isLoading && !isAuthenticated) {
router.push("/login");
}
}, [isAuthenticated, isLoading, router]);
if (isLoading) {
return (
<div className="flex min-h-screen items-center justify-center bg-medical-surface">
<div className="flex flex-col items-center gap-3">
<Loader2 className="h-8 w-8 animate-spin text-brand-600" />
<p className="text-sm text-medical-muted">Loading...</p>
</div>
</div>
);
}
if (!isAuthenticated) {
return null;
}
return (
<div className="flex min-h-screen flex-col">
<Navbar />
<div className="flex flex-1">
<div className="hidden lg:block">
<div className="sticky top-14 h-[calc(100vh-3.5rem)]">
<Sidebar />
</div>
</div>
<main className=SettingsLayout function · typescript · L54-L64 (11 LOC)frontend/src/app/settings/layout.tsx
export default function SettingsLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<AuthProvider>
<SettingsShell>{children}</SettingsShell>
</AuthProvider>
);
}TermsOfServicePage function · typescript · L6-L271 (266 LOC)frontend/src/app/terms/page.tsx
export default function TermsOfServicePage() {
return (
<div className="min-h-screen bg-white">
{/* Header */}
<header className="border-b border-medical-border bg-white">
<div className="mx-auto max-w-4xl px-4 sm:px-6 lg:px-8">
<div className="flex h-16 items-center justify-between">
<Link href="/" className="flex items-center gap-2">
<Stethoscope className="h-7 w-7 text-brand-600" />
<span className="text-xl font-semibold text-medical-dark">
MedScribe AI
</span>
</Link>
<Link href="/" className="btn-ghost gap-2">
<ArrowLeft className="h-4 w-4" />
Back
</Link>
</div>
</div>
</header>
<main className="mx-auto max-w-4xl px-4 py-16 sm:px-6 lg:px-8">
<h1 className="text-4xl font-bold text-medical-dark">
Terms of Service
</h1>
<p className="mt-2 text-sm text-