Chat about this codebase

AI-powered code exploration

Online

Project Overview

Aarogya-AI delivers AI-powered health tools tailored for Indian users. It combines conversational care, diagnostic analysis and personalized reminders on web and mobile.

Purpose

Provide accessible, intelligent health support:

  • Offer an AI chatbot for symptom checks and health advice
  • Analyze skin conditions and sleep patterns using computer vision
  • Send timely medication reminders
  • Store prescriptions and enable voice interactions (upcoming)

Audience

  • End users seeking at-home health insights
  • Developers extending AI modules or integrating new features
  • Healthcare startups building localized solutions for India

Key Features

  • AI Chatbot: Multilingual conversational agent for symptom analysis
  • Skin Analysis: Image-based assessment of common dermatological issues
  • Sleep Analysis: Sleep pattern detection via mobile camera
  • Medication Reminders: Scheduled notifications on web/mobile
  • Roadmap: Prescription storage, voice support, advanced health insights

Tech Stack

  • Frontend: Next.js, React, Tailwind CSS
  • Backend: Node.js, Express, Supabase
  • AI Services: OpenAI API, TensorFlow.js
  • Database: Supabase (PostgreSQL, Auth, Storage)

Core Modules

  • /components: Reusable UI elements
  • /pages: Next.js routes for web views
  • /api: Serverless endpoints (chat, analysis, reminders)
  • /services: AI integration and data processing
  • /mobile: React Native wrappers for cross-platform support

Roadmap

  • Integrate advanced AI-driven health insights
  • Enable multilingual support (Hindi, regional languages)
  • Add prescription upload and secure storage
  • Implement voice-based chatbot & analysis

Quick Start

Clone, install dependencies and launch the development server.

git clone https://github.com/sarvankumar-fsdp/Aarogya-AI.git
cd Aarogya-AI
npm install
npm run dev         # Starts Next.js on http://localhost:3000
## Getting Started

Follow these steps to clone, install, configure, and launch Aarogya AI locally or in a cloud workspace.

### Prerequisites

- Node.js v16 or higher  
- npm (v8+) or Yarn  
- Git  
- Supabase account (for database, auth, AI integrations)

### 1. Clone the Repository

Navigate to your workspace and clone the project:

```bash
git clone https://github.com/sarvankumar-fsdp/Aarogya-AI.git
cd Aarogya-AI

2. Install Dependencies

Use your package manager of choice:

# npm
npm install

# Yarn
yarn install

3. Configure Environment Variables

Create a .env.local file in the project root. At minimum, define your Supabase credentials:

NEXT_PUBLIC_SUPABASE_URL=https://xyzcompany.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
  • NEXT_PUBLIC_SUPABASE_* variables expose keys to the client for real-time data and auth.
  • SUPABASE_SERVICE_ROLE_KEY remains server-only (used in API routes).

4. Run Locally

Start the development server with hot-reload:

npm run dev

Visit http://localhost:3000 in your browser. The app uses:

  • Next.js (frontend & API routes)
  • Tailwind CSS (styling via tailwind.config.ts + postcss.config.mjs)
  • Supabase (data, auth, AI extensions)

5. Build & Serve Production

Compile and start the optimized build:

npm run build
npm start

By default, the app listens on port 3000. You can override with PORT:

PORT=8080 npm start

6. Cloud Workspace (e.g., GitHub Codespaces)

  1. Open the repo in your cloud IDE.
  2. Expose port 3000 for preview.
  3. Install dependencies and run npm run dev as above.

All environment steps remain identical. Ensure your .env.local is set or use workspace secrets to inject Supabase keys.

Environment & Configuration

This section lists all environment variables, third-party keys, and foundational configs required before running builds or tests.

1. Environment Variables

Create a .env.local at project root:

# Supabase (client & server)
NEXT_PUBLIC_SUPABASE_URL=https://xyz.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=public-anon-key
SUPABASE_SERVICE_ROLE_KEY=service-role-secret

# Clerk (authentication)
CLERK_SECRET_KEY=sk_test_...
CLERK_PUBLISHABLE_KEY=pk_test_...

# Optional: Next.js runtime configs
NEXT_PUBLIC_APP_ENV=development

• Prefix client-facing keys with NEXT_PUBLIC_.
• Never commit SUPABASE_SERVICE_ROLE_KEY or CLERK_SECRET_KEY.

2. Component Library (shadcn/ui)

components.json defines how @/components resolve, Tailwind CSS, RSC support and Lucide icons.

Root components.json excerpt:

{
  "$schema": "https://unpkg.com/@shadcn/ui@latest/schema.json",
  "output": "src/components",
  "css": "tailwind",
  "rsc": true,
  "aliases": {
    "@/components": "src/components"
  },
  "icons": "lucide-react"
}

Ensure your tsconfig.json includes the alias:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"],
      "@/components": ["src/components"]
    }
  }
}

Generate or update components:

npx shadcn-ui add button

Import in your code:

import { Button } from "@/components";

3. ESLint Setup

eslint.config.mjs uses Next.js recommended rules and TypeScript support:

import { FlatCompat } from "@eslint/eslintrc";
import next from "eslint-config-next";

const compat = new FlatCompat({
  baseDirectory: __dirname
});

export default [
  // Next.js base rules
  ...compat.extends("next/core-web-vitals"),
  // Custom rules
  {
    rules: {
      "@typescript-eslint/no-unused-vars": ["error"],
      "react/jsx-uses-react": "off"
    }
  }
];

Install dependencies:

npm install -D eslint eslint-config-next @eslint/eslintrc @typescript-eslint/parser @typescript-eslint/eslint-plugin

Run lint:

npx eslint .

4. Next.js Configuration

next.config.ts ignores type and lint errors in production builds:

import { NextConfig } from "next";

const nextConfig: NextConfig = {
  eslint: { ignoreDuringBuilds: true },
  typescript: { ignoreBuildErrors: true }
};

export default nextConfig;

5. Supabase Configuration

Client (browser): src/lib/supabase.ts

import { createClient } from "@supabase/supabase-js";

const url = process.env.NEXT_PUBLIC_SUPABASE_URL!;
const anonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!;

export const supabase = createClient(url, anonKey);

Server: src/lib/supabase-server.ts

import { createClient } from "@supabase/supabase-js";

const url = process.env.NEXT_PUBLIC_SUPABASE_URL!;
const serviceRole = process.env.SUPABASE_SERVICE_ROLE_KEY!;

export const supabaseAdmin = createClient(url, serviceRole, {
  auth: { persistSession: false }
});

Usage in API route:

import { supabaseAdmin } from "@/lib/supabase-server";

export async function GET() {
  const { data } = await supabaseAdmin.from("users").select("*");
  return new Response(JSON.stringify(data));
}

6. Clerk Middleware

src/middleware.ts protects routes via Clerk:

import { authMiddleware } from "@clerk/nextjs/server";

export default authMiddleware({
  publicRoutes: ["/", "/about", "/api/webhook"]
});

export const config = { matcher: ["/((?!_next/image|_next/static|favicon.ico).*)"] };

Ensure you have installed Clerk:

npm install @clerk/nextjs

With this setup, protected pages redirect to Clerk’s sign-in if unauthenticated, while listed publicRoutes remain open.

Architecture Overview

This section describes the high-level organization of Aarogya-AI, showing how browser requests traverse the Next.js app, leverage authentication, reach API routes, and invoke external providers like OpenAI.

Application Structure

Aarogya-AI follows Next.js 13’s /app directory convention with Server and Client Components.

Project tree (simplified):

src/
└─ app/
   ├─ layout.tsx         # RootLayout: global providers & theming
   ├─ page.tsx           # Home page (chat UI)
   ├─ globals.css        # Tailwind imports, CSS variables, dark mode
   └─ api/
      ├─ hello/route.ts  # Sample GET endpoint
      └─ openai/route.ts # Chat completions
└─ components/
   └─ ui/                # Reusable UI primitives (Button, Input, etc.)

Request Flow

  1. Initial SSR
    Browser requests /. Next.js renders layout.tsx (providers, fonts, theme), then page.tsx.
  2. User Interaction
    Client-side code in page.tsx (a Client Component) calls fetch('/api/openai') on form submit.
  3. API Route Handling
    The /api/openai/route.ts handler authenticates via Clerk (getAuth), then calls OpenAI SDK.
  4. Response
    API returns JSON; client updates the chat UI.

Authentication Flow

Clerk provides user sessions; guard server and API routes.

In layout.tsx:

// src/app/layout.tsx
import { ClerkProvider } from '@clerk/nextjs'
export default function RootLayout({ children }) {
  return (
    <ClerkProvider>
      <html lang="en">
        <body>{children}</body>
      </html>
    </ClerkProvider>
  )
}

Guard an API route:

// src/app/api/openai/route.ts
import { NextResponse } from 'next/server'
import { getAuth } from '@clerk/nextjs/server'

export const POST = async (req: Request) => {
  const { userId } = getAuth()           // throws if no session
  // ...proceed with authenticated logic
  return NextResponse.json({ userId })
}

API Routes

All routes use Next.js Edge Functions (default runtime). They export HTTP methods as async functions:

// src/app/api/hello/route.ts
import { NextResponse } from 'next/server'

export const GET = () => {
  return NextResponse.json({ message: 'Hello from Aarogya-AI!' })
}
// src/app/api/openai/route.ts
import { NextResponse } from 'next/server'
import OpenAI from 'openai'

const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY })

export const POST = async (req: Request) => {
  const { prompt } = await req.json()
  const res = await openai.chat.completions.create({
    model: 'gpt-4o-mini',
    messages: [{ role: 'user', content: prompt }],
  })
  return NextResponse.json(res.choices[0].message)
}

OpenAI Integration

  • Initialization: Use new OpenAI({ apiKey }).
  • Chat Completions: Call openai.chat.completions.create() with model and messages.
  • Streaming (advanced): Pass stream: true and handle for await (const chunk of stream) to push partial responses to the client.

Example streaming handler:

// src/app/api/openai/stream.ts
import { NextResponse } from 'next/server'
import OpenAI from 'openai'

const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY })

export const POST = async (req: Request) => {
  const { prompt } = await req.json()
  const stream = await openai.chat.completions.create({
    model: 'gpt-4o-mini',
    messages: [{ role: 'user', content: prompt }],
    stream: true,
  })
  return new NextResponse(stream)         // streams chunks to client
}

Client-Server Component Boundaries

  • Server Components (default in /app): fetch data on the server, use secret keys.
  • Client Components ('use client' at top): handle interactivity (forms, hooks).
  • Pass props from Server → Client; never import server-only modules (e.g. openai, getAuth) in clients.

With this architecture, Aarogya-AI cleanly separates layout, styling, auth, and data-fetching logic, enabling scalable feature development. Here are the available Feature Modules in the Aarogya-AI repo. Please let me know which one you’d like detailed documentation for:

• Invoking the AI Model and Handling Responses
• Streaming Sleep Tips Endpoint (/api/sleep-tip)
• Asha Chat API (/api/asha-chat)
• Diet Recommender API (/api/diet-recommender)
• Health Chat API (/api/health-chat)
• Lab Test Explainer API (/api/lab-test-explainer)
• Medicine Usage API (/api/medicine-usage)
• Prescriptions API: Uploading, Fetching & Deleting Prescription Files

Just reply with the module name or endpoint, and I’ll provide a focused, hands-on guide.

Data & Storage Design

This section describes database tables, storage buckets, and Supabase helper utilities used across API routes.

Database Schema Expectations

emergency_contacts

Columns:

  • id (uuid, PK)
  • user_id (uuid, FK → users.id)
  • name (text)
  • phone (text)
  • created_at (timestamp, default now())

Usage:

  • POST /api/emergency-contacts inserts a new row.
  • GET filters by user_id.
  • DELETE by id and user_id.

prescriptions

Columns:

  • id (uuid, PK)
  • user_id (uuid, FK → users.id)
  • file_name (text)
  • file_path (text)
  • uploaded_at (timestamp, default now())

Usage:

  • POST uploads file to storage and inserts metadata.
  • GET returns metadata and signed URLs.
  • DELETE removes both metadata and storage object.

sleep_analyzer

Columns:

  • id (uuid, PK)
  • user_id (uuid, FK → users.id)
  • date (date)
  • sleep_duration (integer, minutes)
  • created_at (timestamp, default now())

Usage:

  • POST adds a record.
  • GET returns records for a user, optional date filter.

Storage Bucket Usage

We use a private bucket named prescriptions for user files.

Uploading a File

import { supabase } from '@/lib/supabase';

const bucket = supabase.storage.from('prescriptions');
const path = `${userId}/${file.name}`;

// Upload file blob or Buffer
const { error: uploadError } = await bucket.upload(path, file);
if (uploadError) throw uploadError;

// Store metadata in table
await supabase
  .from('prescriptions')
  .insert({ user_id: userId, file_name: file.name, file_path: path });

Generating Signed URLs

// Expires in 2 days (172800 seconds)
const { data, error } = await supabase
  .storage
  .from('prescriptions')
  .createSignedUrl(record.file_path, 172800);

if (error) throw error;
const signedUrl = data.signedUrl;

Deleting Files

// Remove from storage
await supabase
  .storage
  .from('prescriptions')
  .remove([record.file_path]);

// Remove metadata
await supabase
  .from('prescriptions')
  .delete()
  .match({ id: record.id, user_id: userId });

Supabase Helper Utilities

Client-Side (src/lib/supabase.ts)

Creates a browser/mobile-safe client.

import { createClient } from '@supabase/supabase-js';

export const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
);

Use this in React components or non-SSR code:

import { supabase } from '@/lib/supabase';

const { data, error } = await supabase
  .from('sleep_analyzer')
  .select('*')
  .eq('user_id', user.id);

Server-Side (src/lib/supabase-server.ts)

Initializes with JWT from incoming request for secure operations.

import { NextRequest } from 'next/server';
import { createClient } from '@supabase/supabase-js';

export function supabaseServer(req: NextRequest) {
  const token = req.headers.get('authorization')?.replace('Bearer ', '');
  return createClient(
    process.env.SUPABASE_URL!,
    process.env.SUPABASE_SERVICE_ROLE_KEY!,
    { global: { headers: { Authorization: `Bearer ${token}` } } }
  );
}

Use inside Next.js route handlers:

import { NextRequest, NextResponse } from 'next/server';
import { supabaseServer } from '@/lib/supabase-server';

export async function GET(req: NextRequest) {
  const supabase = supabaseServer(req);
  const user = (await supabase.auth.getUser()).data.user;
  const { data } = await supabase
    .from('emergency_contacts')
    .select('*')
    .eq('user_id', user?.id);
  return NextResponse.json(data);
}

These tables, storage patterns, and helpers ensure consistent, secure data handling across the application.

Deployment & Hosting

This section explains how to build, test and deploy Aarogya-AI to Vercel or any Node-based hosting. It covers build commands, local testing, and sample configurations for production hosting.

Prerequisites

  • Node.js ≥18 and npm (or yarn)
  • Git access to the repository
  • Environment variables (e.g., AI API keys) set in your host or Vercel dashboard

1. Building the App

Aarogya-AI uses Next.js with custom build settings in next.config.ts:

// next.config.ts
import { NextConfig } from "next";
const nextConfig: NextConfig = {
  eslint: { ignoreDuringBuilds: true },
  typescript: { ignoreBuildErrors: true },
};
export default nextConfig;

Run the production build:

npm install
npm run build

Key npm scripts (package.json):

{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start -p $PORT",
    "lint": "next lint",
    "type-check": "tsc --noEmit"
  }
}

2. Testing Locally

Start the dev server with hot-reload and Tailwind CSS support:

npm run dev
# http://localhost:3000

Validate code quality before deploying:

npm run lint
npm run type-check

3. Deploying to Vercel

  1. Log into Vercel and import the GitHub repository.
  2. In Project Settings → Build & Development:
    • Install Command: npm install
    • Build Command: npm run build
    • Output Directory: .next (default)
  3. Add Environment Variables under Settings → Environment Variables.
  4. Deploy; Vercel automatically runs the build and serves the app.

4. Deploying to Any Node-Based Host

4.1 Direct Deployment

  1. Clone the repo and install:

    git clone https://github.com/sarvankumar-fsdp/Aarogya-AI.git
    cd Aarogya-AI
    npm ci --production
    npm run build
    
  2. Start the server:

    npm run start
    # Listens on PORT env or 3000
    
  3. Use a process manager (e.g., PM2):

    // ecosystem.config.js
    module.exports = {
      apps: [{
        name: "aarogya-ai",
        script: "npm",
        args: "start",
        env: { PORT: 3000, NODE_ENV: "production" }
      }]
    };
    
    pm2 start ecosystem.config.js
    

4.2 Docker Deployment

# Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm","start"]

Build and run:

docker build -t aarogya-ai .
docker run -e PORT=3000 -p 3000:3000 aarogya-ai

5. Tailwind & PostCSS Configuration

Both are integrated into the Next.js build pipeline:

// postcss.config.mjs
export default {
  plugins: {
    tailwindcss: {},
    autoprefixer: {}
  }
};
// tailwind.config.ts
import type { Config } from "tailwindcss";
const config: Config = {
  content: ["./app/**/*.{js,ts,jsx,tsx}", "./components/**/*.{js,ts,jsx,tsx}"],
  theme: {
    extend: {
      fontFamily: {
        sans: ["Inter", "sans-serif"],
        mono: ["Fira Code", "monospace"]
      }
    }
  }
};
export default config;

Modify plugins in postcss.config.mjs or theme in tailwind.config.ts to customize styling for your deployment.


Now you can build, test and deploy Aarogya-AI on Vercel or any Node-based environment with confidence.

Development & Contribution Guide

This guide describes the standards, tools, and workflows for developing and contributing to the Aarogya-AI Next.js application.

Prerequisites

  • Node.js ≥18, npm ≥8
  • Familiarity with TypeScript and Next.js

Setup & Installation

Clone the repository and install dependencies:

git clone https://github.com/sarvankumar-fsdp/Aarogya-AI.git
cd Aarogya-AI
npm install

Available NPM Scripts

Reference the package.json scripts:

  • npm run dev
    Starts Next.js in development mode (http://localhost:3000)
  • npm run build
    Compiles and type‐checks for production
  • npm run start
    Serves the production build
  • npm run lint
    Runs ESLint across .ts, .tsx, .js, .jsx
  • npm run lint:fix
    Auto‐fixes linting errors where possible

Linting & Code Style

Aarogya-AI uses ESLint with Next.js and TypeScript support. The configuration in eslint.config.mjs extends recommended rules and allows custom overrides:

// eslint.config.mjs
import { FlatCompat } from "@eslint/eslintrc";
const compat = new FlatCompat({ baseDirectory: import.meta.url });

export default [
  // Base and Next.js rules
  ...compat.extends(
    "eslint:recommended",
    "plugin:@next/next/recommended"
  ),
  {
    parserOptions: { ecmaVersion: 2022, sourceType: "module" },
    rules: {
      // Example override: enforce semicolons
      "semi": ["error", "always"],
      // Add or customize rules here
    }
  }
];

Run linting:

npm run lint
npm run lint:fix

Type Checking & Compiler Options

TypeScript compiler options in tsconfig.json enforce strict typing and modern module resolution:

{
  "compilerOptions": {
    "strict": true,
    "target": "es2022",
    "module": "esnext",
    "moduleResolution": "node",
    "jsx": "preserve",
    "incremental": true,
    "isolatedModules": true,
    "noEmit": true
  },
  "exclude": ["node_modules"]
}

To verify types:

npm run build

Managing Dependencies

  • Add a runtime dependency:
    npm install <package-name>
  • Add a development dependency:
    npm install --save-dev <package-name>
  • Check for updates:
    npm outdated
  • Update to latest compatible versions:
    npm update

Contribution Workflow

  1. Fork the repository and checkout a new branch:
    git checkout -b feature/your-short-description
  2. Implement your changes.
  3. Run lint and type checks locally:
    npm run lint && npm run build
  4. Commit with a clear, imperative message (e.g., “Add user-profile chart component”).
  5. Push and open a PR against main.
  6. Ensure CI passes (lint + build).

License

Aarogya-AI is licensed under MIT. Include the LICENSE file in any redistribution or derivative work.

Security & Privacy

This section covers user authentication, route protection, role-based access control, legal pages integration, and secure handling of health data.

Authentication with Clerk

Aarogya.me uses Clerk for user sign-in. Customize the sign-in page in src/app/sign-in/[[...sign-in]]/page.tsx.

Basic Sign-In Page

import { SignIn } from "@clerk/nextjs";
import { Box } from "@chakra-ui/react";

export default function SignInPage() {
  return (
    <Box
      display="flex"
      alignItems="center"
      justifyContent="center"
      height="100vh"
      bg="gray.50"
    >
      <SignIn
        routing={{
          afterSignInUrl: "/dashboard",
          signUpUrl: "/sign-up",
        }}
        path="/sign-in"
      />
    </Box>
  );
}

Customizing the Sign-In Component

Add or override fields, design system tokens, or multi-factor settings:

<SignIn
  appearance={{
    variables: { colorPrimary: "#2B6CB0" },
    elements: {
      card: "rounded-lg shadow-lg",
      socialButtonsBlockButton: "bg-blue-500",
    },
  }}
  signUpUrl="/sign-up"
  afterSignInUrl="/dashboard"
/>

Route Protection with Middleware

The Clerk middleware in src/middleware.ts enforces authentication on protected routes:

import { withClerkMiddleware, getAuth } from "@clerk/nextjs/server";
import type { NextRequest } from "next/server";

export default withClerkMiddleware((req: NextRequest) => {
  // Public pages
  if (req.nextUrl.pathname.startsWith("/sign-in") ||
      req.nextUrl.pathname.match(/^\/(privacy-policy|terms-conditions)$/)) {
    return;
  }
  // All other routes require auth
  return getAuth({ req }).userId ? undefined : Response.redirect(new URL("/sign-in", req.url));
});

export const config = { matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"] };

Role-Based Access Control (RBAC)

Use Clerk’s getAuth or requireAuth to enforce roles on server-side routes and API endpoints.

Protecting an API Route

import { NextResponse } from "next/server";
import { getAuth } from "@clerk/nextjs/server";

// Only users with the "doctor" role can access patient data
export async function GET(req: Request, { params }: { params: { id: string } }) {
  const { userId, orgRole } = getAuth({ req });
  if (!userId || orgRole !== "doctor") {
    return NextResponse.json({ error: "Unauthorized" }, { status: 403 });
  }
  const patientRecord = await fetchPatientRecord(params.id);
  return NextResponse.json(patientRecord);
}

Checking Roles in Server Components

import { getAuth } from "@clerk/nextjs/server";

export default async function Dashboard() {
  const { userId, claims } = getAuth();
  if (!userId) throw new Error("Not authenticated");
  const isDoctor = claims.orgRole === "doctor";
  return (
    <div>
      <h1>Welcome, {isDoctor ? "Doctor" : "Patient"}</h1>
      {/* Render doctor-only tools */}
      {isDoctor && <DoctorTools />}
    </div>
  );
}

Legal Pages

Privacy Policy

Path: src/app/privacy-policy/page.tsx
Renders data collection details, user rights, and security measures.

export default function PrivacyPolicy() {
  return (
    <article className="prose mx-auto my-10">
      <h1>Privacy Policy</h1>
      <p>Your health data is encrypted in transit and stored securely. You can request a data export or deletion at any time.</p>
      {/* Sections on cookies, third-party services, updates */}
    </article>
  );
}

Terms & Conditions

Path: src/app/terms-conditions/page.tsx
Outlines platform use, responsibilities, and policy links.

import Link from "next/link";

export default function TermsConditions() {
  return (
    <article className="prose mx-auto my-10">
      <h1>Terms & Conditions</h1>
      <p>By using Aarogya.me, you agree to our <Link href="/privacy-policy">Privacy Policy</Link>.</p>
      {/* Add sections on user obligations, updates, contacts */}
    </article>
  );
}

Include links to these pages in your global layout or footer for compliance:

import Link from "next/link";

export default function Footer() {
  return (
    <footer className="text-center py-6">
      <Link href="/privacy-policy" className="mx-4">Privacy Policy</Link>
      <Link href="/terms-conditions" className="mx-4">Terms & Conditions</Link>
    </footer>
  );
}

Secure Handling of Health Data

  • Always use HTTPS (Next.js defaults to secure).
  • Fetch sensitive data server-side (API routes or getServerSideProps/server components) to avoid exposing secrets.
  • Sanitize and validate all inputs in API routes.
  • Log access events for audit trails (e.g., wrap data fetch calls in logging middleware).

Example logging middleware for API routes:

import type { NextRequest } from "next/server";
export function logAccess(req: NextRequest) {
  console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
}

Apply in an API route:

import { logAccess } from "@/lib/logging";
export async function GET(req: Request, { params }: { params: { id: string } }) {
  logAccess(new Request(req));
  // ... authorization and data fetch
}

This setup ensures authenticated, role-aware access, transparent legal compliance, and secure treatment of user health information.