# Project export: Zorg - Health Records Reimagined

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: TreeHacks 2024
- Tagline: Automated healthcare with Zorg: secure, decentralized storage and instant access to encrypted patient records, ensuring life-saving info is available in emergencies.
- Devpost: https://devpost.com/software/zorg-7ubd4x
- GitHub: https://github.com/rohan-patra/Zorg
- Video: https://player.vimeo.com/video/914178456?byline=0&portrait=0&title=0#t=
- Result: winner (Blockchain & Security Grand Prize (4x JBL Partybox))
- Team: 2 GitHub contributor(s) — Rohan Patra (7 commits), Aditya Rai (6 commits)

## Devpost submission (written by the team)

### Inspiration

Last week, one of our team members was admitted to the hospital with brain trauma. Doctors hesitated to treat them because of their lack of insight into the patient’s medical history. This prompted us to store EVERYONE’s health records on a single, decentralized chain. The catch? The process is end-to-end encrypted, ensuring only yourself and your designated providers can access your data.

### How we built it

Zorg was built across 3 verticals: a frontend client, a backend server, and the chain. The frontend client… We poured our hearts and ingenuity into crafting a seamless user interface, a harmonious blend of aesthetics and functionality designed to resonate across the spectrum of users. Our aim? To simplify the process for patients to effortlessly navigate and control their medical records while enabling doctors and healthcare providers to seamlessly access and request patient information. Leveraging the synergy of Bun, React, Next, and Shadcn, we crafted a performant portal. To safeguard privacy, we fortified client-side interactions with encryption, ensuring sensitive data remains inaccessible to central servers. This fusion of technology and design principles heralds a new era of secure, user-centric digital healthcare record keeping. The backend server… The backend server of Zorg is the crux of our mission to revolutionize healthcare records management, ensuring secure, fast, and reliable access to encrypted patient data. Utilizing Zig for its performance and security advantages, our backend encrypts health records using a doctor's public key and stores them on IPFS for decentralized access. These records are then indexed on the blockchain via unique identifiers (CIDs), ensuring both privacy and immutability. Upon request, the system retrieves and decrypts the data for authorized users, transforming it into a vectorized format suitable for semantic search. This process not only safeguards patient information but also enables healthcare providers to efficiently parse through detailed medical histories. Our use of Zig ensures that these operations are executed swiftly, maintaining our commitment to providing immediate access to critical medical information while prioritizing patient privacy and data integrity. The chain… The chain stores the encrypted key and the CID, allowing seemless access to a patient’s file stored on decentralized storage (IPFS). The cool part? The complex protocols and keys governing this system is completely abstracted away and wrapped up modern UI/UX, giving easy access to senior citizens and care providers.

### Challenges we ran into

Our biggest challenges were during integration, near the end of the hackathon. We had divided the project, with each person focusing on a different area—machine learning and queries, blockchain and key sharing, encryption and IPFS, and the frontend design. However, when we began to put things together, we quickly realized that we had failed to communicate with each other the specific details of how each of our systems worked. As a result we had to spend a few hours just tweaking each of our systems so that they could work with each other. Another smaller (but enjoyable!) challenge we faced was learning to use a new language (Zig!). We ended up building our entire encryption and decryption system in Zig (as it needed to be incredibly fast due to the potentially vast amounts of data it would be processing) and had to piece together both how to build these systems in Zig, and how to integrate the resulting Zig binaries into the rest of our project.

### What's next

for Zorg In the future, we hope to devise a cryptographically sound way to revoke access to records after they have been granted. Additionally, our system would best benefit the population if we were able to partner with the government to include patient private keys in something everyone carries with them like their phone or ID so that in an emergency situation, first responders can access the patient data and identify things like allergies to medications.

## README (from the GitHub repository)

# Zorg

## Detected evidence (automated analysis)

Indexed codebase: 55 recognized source files, 124 KB.
- CSS (language) — detected in the code
- Express (technology) — detected in the code
- HTML (language) — detected in the code
- JavaScript (language) — detected in the code
- Next.js (technology) — detected in the code
- Python (language) — detected in the code
- React (technology) — detected in the code
- Solidity (language) — detected in the code
- Tailwind CSS (technology) — detected in the code
- TypeScript (language) — detected in the code
- Docker (technology) — claimed on Devpost, not found in the code
- Flask (technology) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (120 of 481)

```
.gitignore
Archive/decrypt
Archive/encrypt
Archive/src/build.zig
Archive/src/decrypt
Archive/src/decrypt.o
Archive/src/decrypt.zig
Archive/src/encrypt
Archive/src/encrypt.o
Archive/src/encrypt.zig
Archive/src/output_output_test.txt
Archive/src/output_test.txt
Archive/src/src/main.zig
Archive/src/test.txt
Archive/src/zig-cache/h/312d3dbf202ba241463c01d6852fda8b.txt
Archive/src/zig-cache/h/timestamp
Archive/src/zig-cache/o/11034a8868483b303dbbe633fefb66ac/builtin.zig
Archive/src/zig-cache/o/74c27f1902f95e35c91bb05395a1a801/dependencies.zig
Archive/src/zig-cache/o/8f8995ad8e128d536e2742eaafeb6b6f/builtin.zig
Archive/src/zig-cache/o/eec6ea8cc0d354d83e967b464fc01fe5/builtin.zig
Archive/src/zig-cache/o/f57a1775a33c8178216b92323a15eb0b/build.o
Archive/src/zig-cache/z/422b7cc7dfd23003fdfe7314599cf950
Archive/src/zig-cache/z/9cf7ebd7921fca2dae9c20b0a215a249
Archive/src/zig-cache/z/dfde954e90af00c859d620b8e4e9b143
Archive/test.txt
backend/bafybeigeje2gr4l3w7c32vcntlzwiqyo5zi6pomn7w5xxe4cihnmm4yfim/README.md
backend/blockchain/package.json
backend/blockchain/queryEndooint.js
backend/blockchain/testCaldera.js
backend/data/patient_data_21.json
backend/data/patient_data_22.json
backend/data/patient_data_23.json
backend/data/patient_data_24.json
backend/data/patient_data_25.json
backend/data/patient_data_26.json
backend/data/patient_data_27.json
backend/data/patient_data_28.json
backend/data/patient_data_29.json
backend/Embeddings.py
backend/llm.py
backend/output_fhir_data.xml
backend/sample_fhir_json_data.json
backend/sample.hl7
backend/series-00000/image-00000.dcm
backend/series-00000/image-00001.dcm
backend/series-00000/image-00002.dcm
backend/series-00000/image-00003.dcm
backend/series-00000/image-00004.dcm
backend/series-00000/image-00005.dcm
backend/series-00000/image-00006.dcm
backend/series-00000/image-00007.dcm
backend/series-00000/image-00008.dcm
backend/series-00000/image-00009.dcm
backend/series-00000/image-00010.dcm
backend/series-00000/image-00011.dcm
backend/series-00000/image-00012.dcm
backend/series-00000/image-00013.dcm
backend/series-00000/image-00014.dcm
backend/series-00000/image-00015.dcm
backend/series-00000/image-00016.dcm
backend/series-00000/image-00017.dcm
backend/series-00000/image-00018.dcm
backend/series-00000/image-00019.dcm
backend/series-00000/image-00020.dcm
backend/series-00000/image-00021.dcm
backend/series-00000/image-00022.dcm
backend/series-00000/image-00023.dcm
backend/series-00000/image-00024.dcm
backend/series-00000/image-00025.dcm
backend/series-00000/image-00026.dcm
backend/series-00000/image-00027.dcm
backend/series-00000/image-00028.dcm
backend/series-00000/image-00029.dcm
backend/series-00000/image-00030.dcm
backend/series-00000/image-00031.dcm
backend/series-00000/image-00032.dcm
backend/series-00000/image-00033.dcm
backend/series-00000/image-00034.dcm
backend/series-00000/image-00035.dcm
backend/series-00000/image-00036.dcm
backend/series-00000/image-00037.dcm
backend/series-00000/image-00038.dcm
backend/series-00000/image-00039.dcm
backend/series-00000/image-00040.dcm
backend/series-00000/image-00041.dcm
backend/series-00000/image-00042.dcm
backend/series-00000/image-00043.dcm
backend/series-00000/image-00044.dcm
backend/series-00000/image-00045.dcm
backend/series-00000/image-00046.dcm
backend/series-00000/image-00047.dcm
backend/series-00000/image-00048.dcm
backend/series-00000/image-00049.dcm
backend/series-00000/image-00050.dcm
backend/series-00000/image-00051.dcm
backend/series-00000/image-00052.dcm
backend/series-00000/image-00053.dcm
backend/series-00000/image-00054.dcm
backend/series-00000/image-00055.dcm
backend/series-00000/image-00056.dcm
backend/series-00000/image-00057.dcm
backend/series-00000/image-00058.dcm
backend/series-00000/image-00059.dcm
backend/series-00000/image-00060.dcm
backend/series-00000/image-00061.dcm
backend/series-00000/image-00062.dcm
backend/series-00000/image-00063.dcm
backend/series-00000/image-00064.dcm
backend/series-00000/image-00065.dcm
backend/series-00000/image-00066.dcm
backend/series-00000/image-00067.dcm
backend/series-00000/image-00068.dcm
backend/series-00000/image-00069.dcm
backend/series-00000/image-00070.dcm
backend/series-00000/image-00071.dcm
backend/series-00000/image-00072.dcm
backend/series-00000/image-00073.dcm
backend/series-00000/image-00074.dcm
backend/series-00000/image-00075.dcm
backend/series-00000/image-00076.dcm
[361 more files omitted for size]
```

### Dependencies

- backend/blockchain/package.json: axios@^1.6.7, dotenv@^16.4.4, ethers@^5.7.2, express@^4.18.2, node-fetch@^3.3.2
- contracts/package.json: @nomiclabs/hardhat-ethers@^2.2.3, chai@^5.1.0, dotenv@^16.4.4, ethers@^5.7.2, hardhat@^2.20.1
- frontend/package.json: @ianvs/prettier-plugin-sort-imports@4.1.1, @radix-ui/react-avatar@^1.0.4, @radix-ui/react-dialog@^1.0.5, @radix-ui/react-dropdown-menu@^2.0.6, @radix-ui/react-label@^2.0.2, @radix-ui/react-slot@latest, @radix-ui/react-tabs@^1.0.4, @radix-ui/react-toast@^1.1.5, @types/node@20.11.19, @types/react@18.2.56, @types/react-dom@18.2.19, @typescript-eslint/parser@7.0.1, autoprefixer@10.4.17, class-variance-authority@0.7.0, clsx@2.1.0, eslint@8.56.0, eslint-config-next@14.1.0, eslint-config-prettier@9.1.0, eslint-plugin-react@7.33.2, eslint-plugin-tailwindcss@3.14.2, lucide-react@0.331.0, next@14.1.0, next-themes@latest, postcss@8.4.35, prettier@3.2.5, react@latest, react-dom@latest, sharp@0.33.2, tailwind-merge@2.2.1, tailwindcss@3.4.1, tailwindcss-animate@1.0.7, typescript@5.3.3, upgradeps@latest, vaul@^0.9.0
- ipfs/package.json: @web3-storage/w3up-client@^12.4.1, axios@^1.6.7, cors@^2.8.5, express@^4.18.2, express-fileupload@^1.4.3
- ipfs/test_app/package.json: @testing-library/jest-dom@^5.17.0, @testing-library/react@^13.4.0, @testing-library/user-event@^13.5.0, react@^18.2.0, react-dom@^18.2.0, react-scripts@5.0.1, web-vitals@^2.1.4

### Recent commits (newest first)

- frontend done
- everything I have done
- everything I have done
- Intersystems
- Intersystems
- blockchain
- Merge branch 'main' of https://github.com/rohan-patra/Zorg
- almost done w backend
- Merge branch 'main' of https://github.com/rohan-patra/Zorg
- starting point for frontend
- changes
- added backend folder
- Delete .DS_Store
- remove DS Store
- initial
- Initial commit

## Key source files (fetched from GitHub, selected and truncated for size)

### ipfs/package.json

```
{ "dependencies": { "@web3-storage/w3up-client": "^12.4.1", "axios": "^1.6.7", "cors": "^2.8.5", "express": "^4.18.2", "express-fileupload": "^1.4.3" } }
```

### contracts/package.json

```
{
  "name": "contracts",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@nomiclabs/hardhat-ethers": "^2.2.3",
    "ethers": "^5.7.2",
    "hardhat": "^2.20.1"
  },
  "dependencies": {
    "chai": "^5.1.0",
    "dotenv": "^16.4.4"
  }
}

```

### frontend/package.json

```
{
  "name": "next-template",
  "version": "0.0.2",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "lint:fix": "next lint --fix",
    "preview": "next build && next start",
    "typecheck": "tsc --noEmit",
    "format:write": "prettier --write \"**/*.{ts,tsx,mdx}\" --cache",
    "format:check": "prettier --check \"**/*.{ts,tsx,mdx}\" --cache"
  },
  "dependencies": {
    "@radix-ui/react-avatar": "^1.0.4",
    "@radix-ui/react-dialog": "^1.0.5",
    "@radix-ui/react-dropdown-menu": "^2.0.6",
    "@radix-ui/react-label": "^2.0.2",
    "@radix-ui/react-slot": "latest",
    "@radix-ui/react-tabs": "^1.0.4",
    "@radix-ui/react-toast": "^1.1.5",
    "class-variance-authority": "0.7.0",
    "clsx": "2.1.0",
    "lucide-react": "0.331.0",
    "next": "14.1.0",
    "next-themes": "latest",
    "react": "latest",
    "react-dom": "latest",
    "sharp": "0.33.2",
    "tailwind-merge": "2.2.1",
    "tailwindcss-animate": "1.0.7",
    "upgradeps": "latest",
    "vaul": "^0.9.0"
  },
  "devDependencies": {
    "@ianvs/prettier-plugin-sort-imports": "4.1.1",
    "@types/node": "20.11.19",
    "@types/react": "18.2.56",
    "@types/react-dom": "18.2.19",
    "@typescript-eslint/parser": "7.0.1",
    "autoprefixer": "10.4.17",
    "eslint": "8.56.0",
    "eslint-config-next": "14.1.0",
    "eslint-config-prettier": "9.1.0",
    "eslint-plugin-react": "7.33.2",
    "eslint-plugin-tailwindcss": "3.14.2",
    "postcss": "8.4.35",
    "prettier": "3.2.5",
    "tailwindcss": "3.4.1",
    "typescript": "5.3.3"
  }
}
```

### backend/blockchain/package.json

```
{
  "name": "blockchain",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "axios": "^1.6.7",
    "dotenv": "^16.4.4",
    "ethers": "^5.7.2",
    "express": "^4.18.2",
    "node-fetch": "^3.3.2"
  }
}

```

### ipfs/test_app/package.json

```
{
  "name": "test_app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.17.0",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

```

### ipfs/main.js

```javascript
const express = require('express')
const app = express()
const fileUpload = require('express-fileupload');
const cors = require('cors');
const axios = require('axios');

app.use(cors());

app.use(fileUpload());

import { create } from '@web3-storage/w3up-client'
var port = 5002
const client = await create()
const space = await client.createSpace('zorg')
const myAccount = await client.login('adyrai05@gmail.com')


// did:key:z6MkhR1HpBEqWH8zgqDUSnY5WkGuvSijZSgbweuVUCtCxpC7
// Y6Jlcm9vdHOC2CpYJQABcRIgkl8SEEALWFKgOkYGeBUIKJx4roc3jjnuRY3NdzFPZCfYKlglAAFxEiDh4ZGaveTfPEzwQe0qR-f6bZf-8xqCsi1qL4hHqQwO72d2ZXJzaW9uAaoCAXESIIQo0tYyYoGnMujwFJLAMRudJkj76naTkcsA3E2AYpBYqGFzWETtoQNAy1zfgBcFgb9_Xa261doEkxVuZcwwzx7J5RVRmqETvqqUXHXMfRd8Gx1mI4BeOSWEh98rw2DVGOCV2hdbyoJ8AWF2ZTAuOS4xY2F0dIGiY2NhbmEqZHdpdGh4OGRpZDprZXk6ejZNa3RITG40aUtMaVlUeHhHaHlDOUI1UVI4WHJFa0Vqd2NnRUV6UWJLcTJXMnpzY2F1ZFgbnRptYWlsdG86Z21haWwuY29tOmFkeXJhaTA1Y2V4cPZjZmN0gaFlc3BhY2WhZG5hbWVkWm9yZ2Npc3NYIu0BzXko4sHKWjS7pRbg3cAMttXflsp3egus1PhB2lJ0TlhjcHJmgL4CAXESIJJfEhBAC1hSoDpGBngVCCiceK6HN4457kWNzXcxT2QnqGFzRICgAwBhdmUwLjkuMWNhdHSBomNjYW5hKmR3aXRoZnVjYW46KmNhdWRYIu0BK_83RAQqE8T8U_o35piD0f-SF8h1jX8PTH5Jnqr-MYhjZXhw9mNmY3SBom5hY2Nlc3MvY29uZmlybdgqWCUAAXESIOoOKoGgIJUIDVjVpoAg720QkKylwtZRDLt88QQrY8qCbmFjY2Vzcy9yZXF1ZXN02CpYJQABcRIgOEkvGacsDeiAxOt6SyHKilphfZs1RJxCFK_kpvODw79jaXNzWBudGm1haWx0bzpnbWFpbC5jb206YWR5cmFpMDVjcHJmgdgqWCUAAXESIIQo0tYyYoGnMujwFJLAMRudJkj76naTkcsA3E2AYpBYlwMBcRIg4eGRmr3k3zxM8EHtKkfn-m2X_vMagrItai-IR6kMDu-oYXNYRO2hA0C99fv1bNkNdk9RmsRPgqToZQ8z1ZK8vXGBmgxuwPpB7TVZdy0TVObYN4ymOf9VYHbef4zZIRkel3oSnfy4T54EYXZlMC45LjFjYXR0gaNibmKhZXByb29m2CpYJQABcRIgkl8SEEALWFKgOkYGeBUIKJx4roc3jjnuRY3NdzFPZCdjY2Fua3VjYW4vYXR0ZXN0ZHdpdGh0ZGlkOndlYjp3ZWIzLnN0b3JhZ2VjYXVkWCLtASv_N0QEKhPE_FP6N-aYg9H_khfIdY1_D0x-SZ6q_jGIY2V4cPZjZmN0gaJuYWNjZXNzL2NvbmZpcm3YKlglAAFxEiDqDiqBoCCVCA1Y1aaAIO9tEJCspcLWUQy7fPEEK2PKgm5hY2Nlc3MvcmVxdWVzdNgqWCUAAXESIDhJLxmnLA3ogMTrekshyopaYX2bNUScQhSv5Kbzg8O_Y2lzc1KdGndlYjp3ZWIzLnN0b3JhZ2VjcHJmgA

await myAccount.provision(space.did())
await space.save()

app.post('/storeToIPFS', async function (req, res) {
    // res.send('Hello World')
    // console.log(req);
    if (!req.files) {
        console.log("issue");
        return res.status(500).send({ msg: "file is not found" })
    }
    let returnJson = {};
    const files = [];
    for(const [key, value] of Object.entries(req.files)) {
        // console.log(key, value);
        console.log(value.data);
        console.log(value.name);
        files.push(new File([value.data], value.name))
        // let data = value.data.toString();
        // let file = makeFile(data);
        // let cid = await storeFiles(file);

        // if(key[0] === "/") {
        //     returnJson[key] = cid;
        // } else {
        //     returnJson[`/${key}`] = cid;
        // }
    }
    const directoryCid = await client.uploadDirectory(files);
    returnJson["cid"] = directoryCid;
    console.log(returnJson);


    // return res.send({cid: JSON.stringify(returnJson)});
    return res.send(returnJson);
})

app.get("/getFromIPFS", async function (req, res) {
    var cid = req.query.cid;
    var fileName = req.query.fileName;
    const url = `https://${cid}.ipfs.w3s.link/${fileName}`;

    try {
        const response = await axios.get(url, { responseType: 'arraybuffer' });
        res.writeHead(200, {
            'Content-Disposition': `attachment; filename="${fileName}"`,
            'Content-Type': response.headers['content-type'],
        });
        res.end(Buffer.from(response.data, 'binary'));
    } catch (error) {
        console.error('Error fetching file:', error);
        res.status(500).send('Failed to fetch file');
    }
});



// const files = [
//     new File(['some-file-content'], 'readme.md'),
//     new File(['import foo'], 'src/main.py'),
// ]
// const directoryCid = await client.uploadDirectory(files)
// console.log(directoryCid)

app.listen(port, () => {
    console.log(`Example app listening on port ${port}`)
})
```

### frontend/app/layout.tsx

```typescript
import "@/styles/globals.css"
import { Metadata, Viewport } from "next"

import { siteConfig } from "@/config/site"
import { fontSans } from "@/lib/fonts"
import { cn } from "@/lib/utils"
import { MainNav } from "@/components/main-nav"
import { ThemeProvider } from "@/components/theme-provider"

export const metadata: Metadata = {
  title: {
    default: siteConfig.name,
    template: `%s - ${siteConfig.name}`,
  },
  description: siteConfig.description,
  icons: {
    icon: "/favicon.ico",
    shortcut: "/favicon-16x16.png",
    apple: "/apple-touch-icon.png",
  },
}

export const viewport: Viewport = {
  themeColor: [
    { media: "(prefers-color-scheme: light)", color: "white" },
    { media: "(prefers-color-scheme: dark)", color: "black" },
  ],
}

interface RootLayoutProps {
  children: React.ReactNode
}

export default function RootLayout({ children }: RootLayoutProps) {
  return (
    <>
      <html lang="en" suppressHydrationWarning>
        <head />
        <body
          className={cn(
            "min-h-screen bg-background font-sans antialiased",
            fontSans.variable
          )}
        >
          <ThemeProvider attribute="class" defaultTheme="system" enableSystem>
            <div className="relative flex min-h-screen flex-col">
              <MainNav />
              {children}
            </div>
          </ThemeProvider>
        </body>
      </html>
    </>
  )
}

```

### ipfs/pyserver/app.py

```python
from flask import Flask, request, jsonify
import os
import requests  # Import the requests library
from flask_cors import CORS

app = Flask(__name__)
CORS(app)







import pandas as pd
from sentence_transformers import SentenceTransformer
from sqlalchemy import create_engine, text
# import os
import json

username = 'SUPERUSER'
password = 'Grover1234!'
hostname = 'localhost'
port = '1972'
namespace = 'USER'
CONNECTION_STRING = f"iris://{username}:{password}@{hostname}:{port}/{namespace}"

engine = create_engine(CONNECTION_STRING)
conn = engine.connect()


def create_table():
    sql = f"""
            CREATE TABLE embeddings_reviews (
        cid VARCHAR(255),
        type VARCHAR(255),
        description VARCHAR(3000),
        description_vector VECTOR(DOUBLE, 384)
    )
            """
    conn.execute(text(sql))

# create_table()

model = SentenceTransformer('all-MiniLM-L6-v2')


def chunkify(text, size):
    """Yield successive size chunks from text."""
    for i in range(0, len(text), size):
        yield text[i:i + size] 


def read_json_files(folder_path):
    # trans = conn.begin()
    json_files = [f for f in os.listdir(folder_path) if f.endswith('.json')]

    for file_name in json_files:
        file_path = os.path.join(folder_path, file_name)
        with open(file_path, 'r', encoding='utf-8') as file:
            data = json.load(file)
            data_str = json.dumps(data)
            chunks = list(chunkify(data_str, 200))
            embeddings = model.encode(chunks, normalize_embeddings=True)
            embeddings.tolist()
            # for row in embeddings:
            for i in range(len(embeddings)):
                # print(type(row))
                with engine.connect() as conn:
                    with conn.begin():
                        sql = text("""
                            INSERT INTO embeddings_reviews 
                            (cid, type, description, description_vector) 
                            VALUES (:cid, :type, :description, TO_VECTOR(:description_vector))
                        """)
                        # print(row)
                        conn.execute(sql, {
                            'cid': 'aeruqioweuyrcon9y4o823qy4083q70c8ewya',
                            'type': 'json',
                            'description': chunks[i],
                            'description_vector': str(list(embeddings[i]))
                        })

# @app.route("/getFromIPFS", methods=["POST"])
# def get_from_ipfs():
#     cid = request.form.get('cid', '')
#     filename = request.form.get("filename", '')
#     key = request.form.get("key", '')
#     response = requests.get(f'http://localhost:5002/getFromIPFS?cid={cid}&fileName={filename}')
#     if response.status_code == 200:
#         # Assuming the Express server returns the file
#         file = response.content
#         os.makedirs("downloads", exist_ok=True)
#         file.save(f'downloads/{filename}')

#         # Decrypt the file
#         decrypted_path = os.path.join('decrypted', filename)
#         os.makedirs("decrypted", exist_ok=True)
#         os.system(f"./decrypt {key} downloads/{filename} {decrypted_path}")

#         return file, 200
#     else:
#         return jsonify({'error': 'Failed to get from IPFS', 'details': response.text}), 500
@app.route("/getFromIPFS", methods=["POST"])
def get_from_ipfs():
    cid = request.form.get('cid', '')
    filename = request.form.get("fileName", '')
    key = request.form.get("key", '')
    response = requests.get(f'http://localhost:5002/getFromIPFS?cid={cid}&fileName={filename}')
    if response.status_code == 200:
        # Create downloads directory if it doesn't exist
        os.makedirs("downloads", exist_ok=True)
        download_path = os.path.join('downloads', filename)
        
        # Write the content to a file
        with open(download_path, 'wb') as f:
            f.write(response.content)

        # Decrypt the file
        decrypted_path = os.path.join('decrypted', filename)
        os.makedirs("decrypted", exist_ok=True)
        os.system(f"./decrypt {key} {download_path} {decrypted_path}")

        # To return the file directly, use send_file from Flask
        from flask import send_file
        return send_file(decrypted_path, as_attachment=True)
    else:
        return jsonify({'error': 'Failed to get from IPFS', 'details': response.text}), 500


@app.route("/findRelevant", methods=["POST"])
def find_relevant_cids():
    description_search = request.form.get('searchQuery', '')
    search_vector = model.encode(description_search, normalize_embeddings=True).tolist() # Convert search phrase into a vector

    with engine.connect() as conn:
        with conn.begin():
            # sql = text("""
            #     SELECT TOP 3 * FROM embeddings_reviews 
            #     ORDER BY VECTOR_DOT_PRODUCT(description_vector, TO_VECTOR(:search_vector)) DESC
            # """)
            sql = text("""
                SELECT TOP 3 CID FROM embeddings_reviews 
                ORDER BY VECTOR_DOT_PRODUCT(description_vector, TO_VECTOR(:search_vector)) DESC
            """)
            
            results = conn.execute(sql, {'search_vector': str(search_vector)}).fetchall()
    print(results)
    resultCids = {}
    for index in range(len(results)):
        resultCids[index] = results[index][0]
    return jsonify(resultCids), 200



@app.route('/storeToIPFS', methods=['POST'])
def store_to_ipfs():
    if 'file' not in request.files:
        return jsonify({'error': 'No file part'}), 400
    file = request.files['file']
    encryption_key = request.form.get('encryptionKey', '')
    if file.filename == '':
        return jsonify({'error': 'No selected file'}), 400
    if file and encryption_key:
        filename = file.filename

        # Optionally use the encryption key here for actual encryption before saving
        save_path = os.path.join('uploads', filename)
        os.makedirs("uploads", exist_ok=True)
        file.save(save_path
[truncated — 2634 more characters]
```

### frontend/app/page.tsx

```typescript
"use client"

import { useState } from "react"

import { Button } from "@/components/ui/button"
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { Toaster } from "@/components/ui/toaster"
import { useToast } from "@/components/ui/use-toast"

export default function HealthRecordsPage() {
  const { toast } = useToast()

  const handleSubmit = () => {
    toast({
      title: "Access Granted",
      description: "You have successfully granted access to your records.",
    })
  }

  const patients = [
    {
      id: "PAT001",
      name: "John Doe",
      age: 32,
      gender: "Male",
      condition: "Condition A",
    },
    {
      id: "PAT002",
      name: "Jane Smith",
      age: 28,
      gender: "Female",
      condition: "Condition B",
    },
    {
      id: "PAT003",
      name: "Alice Johnson",
      age: 45,
      gender: "Female",
      condition: "Condition C",
    },
    {
      id: "PAT004",
      name: "Bob Brown",
      age: 52,
      gender: "Male",
      condition: "Condition D",
    },
    {
      id: "PAT005",
      name: "Charlie Green",
      age: 37,
      gender: "Male",
      condition: "Condition E",
    },
    {
      id: "PAT006",
      name: "Diana Hayes",
      age: 29,
      gender: "Female",
      condition: "Condition F",
    },
    {
      id: "PAT007",
      name: "Evan Turner",
      age: 41,
      gender: "Male",
      condition: "Condition G",
    },
    {
      id: "PAT008",
      name: "Fiona Gallagher",
      age: 34,
      gender: "Female",
      condition: "Condition H",
    },
    {
      id: "PAT009",
      name: "George King",
      age: 48,
      gender: "Male",
      condition: "Condition I",
    },
    {
      id: "PAT010",
      name: "Hannah Abbott",
      age: 26,
      gender: "Female",
      condition: "Condition J",
    },
    {
      id: "PAT011",
      name: "Ian Vance",
      age: 50,
      gender: "Male",
      condition: "Condition K",
    },
    {
      id: "PAT012",
      name: "Julia Mills",
      age: 30,
      gender: "Female",
      condition: "Condition L",
    },
    {
      id: "PAT013",
      name: "Kyle Nero",
      age: 39,
      gender: "Male",
      condition: "Condition M",
    },
    {
      id: "PAT014",
      name: "Luna Gold",
      age: 42,
      gender: "Female",
      condition: "Condition N",
    },
    {
      id: "PAT015",
      name: "Mason Ford",
      age: 29,
      gender: "Male",
      condition: "Condition O",
    },
    {
      id: "PAT016",
      name: "Nora Queen",
      age: 35,
      gender: "Female",
      condition: "Condition P",
    },
    {
      id: "PAT017",
      name: "Oliver Potts",
      age: 47,
      gender: "Male",
      condition: "Condition Q",
    },
    {
      id: "PAT018",
      name: "Piper Halliwell",
      age: 31,
      gender: "Female",
      condition: "Condition R",
    },
  ]

  const healthRecords = {
    demographics: { age: 29, weight: "180 lbs", height: "6 ft" },
    insurance: { provider: "HealthCare Inc.", policyNumber: "HC123456789" },
    imagingStudies: [{ date: "2021-01-01", description: "Chest X-Ray" }],
    labResults: [{ date: "2021-01-10", result: "CBC Normal" }],
    medicalHistory: ["Diabetes", "Hypertension"],
    patientFeedback: ["Satisfied with service", "Quick response times"],
  }

  const labResults = [
    {
      test: "Complete Blood Count (CBC)",
      date: "2023-03-01",
      result: "Normal",
    },
    {
      test: "Lipid Panel",
      date: "2023-03-15",
      result: "High cholesterol",
    },
    {
      test: "Thyroid-Stimulating Hormone (TSH)",
      date: "2023-04-10",
      result: "Normal",
    },
    {
      test: "Hemoglobin A1C",
      date: "2023-05-05",
      result: "Pre-diabetic",
    },
    // ...more lab results
  ]

  const medicalHistory = [
    "Hypertension diagnosed in 2018",
    "Type 2 diabetes diagnosed in 2019",
    "Underwent appendectomy in 2020",
    "Seasonal allergies",
    // ...more medical history entries
  ]

  // Dummy patient feedback data
  const patientFeedback = [
    "Very satisfied with the care received during hospital stay in March.",
    "The new patient portal is user-friendly and helpful.",
    "Would appreciate more follow-up on test results.",
    "Physical therapy sessions were extremely beneficial.",
    // ...more feedback entries
  ]

  const imagingStudies = [
    {
      type: "Chest X-Ray",
      date: "2023-02-14",
      findings: "No acute disease.",
    },
    {
      type: "Abdominal Ultrasound",
      date: "2023-02-20",
      findings: "Gallstones present.",
    },
    {
      type: "CT Head",
      date: "2023-03-05",
      findings: "Chronic sinusitis.",
    },
    {
      type: "MRI Lumbar Spine",
      date: "2023-03-18",
      findings: "Evidence of herniated disc.",
    },
    {
      type: "CT Abdomen/Pelvis",
      date: "2023-04-10",
      findings: "Normal study.",
    },
    // ...more imaging studies
  ]

  return (
    <div className="p-4">
      <Toaster />
      <h1 className="mb-4 text-xl font-bold">Manage Your Health Records</h1>
      <div className="mb-4 flex items-center justify-between">
        <h1 className="text-3xl font-bold text-gray-900 dark:text-gray-100">
          John Doe
        </h1>
        <div className="flex">
          <Dialog>
            <DialogTrigger asChild>
              <Button className="bg-gradient-to-r from-blue-500 to-teal-400 text-white transition-colors hover:from-blue-600 hover:to-teal-500 dark:from-blue-600 dark:to-teal-500 dark:hover:from-blue-700 dark:hover:to-teal-600">
                Grant Access
              </Button>
            </DialogTrigger>
            <DialogContent className="sm:max-w-[425px]">
              <DialogHeader>
       
[truncated — 6359 more characters]
```

### ipfs/test_app/src/index.js

```javascript
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

```

[46 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]