← back to drhiramrodriguez__medscribe-ai

Function bodies 223 total

All specs Real LLM only Function bodies
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 True
create_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_TEMPERATURE
TranscriptionError 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 accuracy
write_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 value
redact_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("<", "&lt;")
        .replace(">", "&gt;")
    )
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 False
create_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,
          not
DashboardShell 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 className
DashboardLayout 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;
    t
RootLayout 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 className
LoginPage 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.lengt
NotesShell 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="fl
NotesLayout 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 pr
NotFound 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 te
PrivacyPolicyPage 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 clas
RegisterPage 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-
‹ prevpage 4 / 5next ›