GenoBank.io

Biosample Details Page Architecture

Overview

The biosampleDetails page (https://genobank.io/laboratories/profile/biosampleDetails/?biosampleSerial={serial}) is a critical interface for viewing comprehensive information about genomic biosamples, including blockchain records, Story Protocol IP assets, and associated files.

Page URL Structure

https://genobank.io/laboratories/profile/biosampleDetails/?biosampleSerial=41230711101565

File Structure

/laboratories/profile/biosampleDetails/
├── index.html          # Main HTML template
├── custom.js           # Core page logic and data rendering
├── service.js          # API service layer
├── components.js       # Reusable UI components
├── ancestry-chart.js   # Ancestry visualization
├── aiDescriptoFunctions.js  # AI descriptor integration
└── css/
    └── style.css       # Page-specific styles

Request Flow

1. Page Load Sequence

graph TD
    A[User visits biosampleDetails page] --> B[index.html loads]
    B --> C[Load JS dependencies]
    C --> D[custom.js initializes]
    D --> E[Extract biosampleSerial from URL]
    E --> F[Check user authentication]
    F --> G[Fetch biosample data]
    G --> H[Render biosample details]
    H --> I[Display Story Protocol data if available]

2. API Request Flow

// service.js - API call to fetch biosample data
GET https://genobank.app/biosample_details_proxy?biosample_serial={serial}&requester_serial={userSerial}

// Response format
{
  serial: 41230711101565,
  owner: "0xbba236F126D40DF943C9Fa90593477f55C50b2A1",
  status: "ACTIVE",
  chainID: 43113,
  tokenId: "0x257fc5e3980000...",
  txHash: "0xb45d25dc259b9ffe...",
  delivered: true,
  story_record: {
    ip_asset_id: "0x...",
    tx_hash: "0x...",
    tx_link: "https://explorer.story.foundation/tx/...",
    token_id: 1,
    created_date: "2024-09-03",
    // Additional metadata fields...
  },
  file_names: ["file1.vcf", "file2.txt"],
  profile: {
    text: '{"name": "Lab Name", "investigator": "Dr. Smith"}'
  }
}

Key Components

1. Authentication Check (custom.js)

async function pageLoaded(biosampleSerial) {
    if (isLoggedIn()) {
        const user_address = getUserWallet();
        // Fetch user balance and permittee status
        const isPermittee = isCurrentUserPermittee();
        if (isPermittee) {
            userSerial = await getPermitteeSerialByAddress(user_address);
        }
    }
    await renderBiosampleDetails(biosampleSerial);
}

2. Data Fetching (service.js)

async function getBiosampleDetails(biosampleSerial, requester_serial) {
    const url = new URL(`${window.NEW_API_BASE}/biosample_details_proxy`);
    url.searchParams.append('biosample_serial', biosampleSerial);
    url.searchParams.append('requester_serial', requester_serial || 0);
    
    const response = await fetch(url);
    return response.json();
}

3. Story Protocol Display (custom.js)

The page dynamically displays Story Protocol IP asset information when available:

if (!isEmpty(biosample?.story_record)) {
    $("#story-record-section").show();
    
    // Display IP Asset ID with link to explorer
    $("#id-ip-asset-id").html(`
        <a href="https://explorer.story.foundation/ipa/${biosample.story_record.ip_asset_id}">
            ${biosample.story_record.ip_asset_id}
        </a>
    `);
    
    // Display transaction hash
    $("#id-ip-asset-transaction").html(`
        <a href="${biosample.story_record.tx_link}">
            ${biosample.story_record.tx_hash}
        </a>
    `);
    
    // Display additional metadata if provided by API
    // - NFT image
    // - Collection info
    // - License terms
    // - Token ID
    // - Creation date
}

Error Handling

The page implements comprehensive error handling:

  1. Missing Serial: Shows error if biosampleSerial not provided
  2. API Failures: Displays user-friendly error messages
  3. Permission Denied: Shows appropriate message for unauthorized access
  4. Network Errors: Graceful degradation with retry logic

Security Considerations

  1. Authentication: Uses Web3 signatures for authentication
  2. Authorization: Checks if user is biosample owner or permittee
  3. CORS: API configured to accept requests from genobank.io
  4. Data Validation: All user inputs are validated before API calls

Story Protocol Integration

Display Rules

  1. NO MOCK DATA: Only display data returned by API
  2. Dynamic Fields: Show only fields that have values
  3. Placeholder Content: Show appropriate placeholders for missing data
  4. Responsive Design: Adapts to different screen sizes

Supported Story Protocol Fields

story_record: {
    ip_asset_id: string,          // IP Asset address
    tx_hash: string,              // Transaction hash
    tx_link: string,              // Explorer link
    token_id: number,             // NFT token ID
    created_date: string,         // Creation date
    nft_image_url: string,        // NFT image URL (optional)
    collection_address: string,   // Collection contract (optional)
    collection_name: string,      // Collection name (optional)
    license_terms: {              // License details (optional)
        license_type: string,
        commercial_use: boolean,
        derivatives_allowed: boolean,
        attribution_required: boolean
    },
    ipfs_metadata_url: string,    // IPFS metadata link (optional)
    file_size: string            // File size (optional)
}

Environment Configuration

The page uses environment detection from /js/env.js:

window.NEW_API_BASE = "https://genobank.app"  // Production
window.WWW_BASE = "https://genobank.io"       // Frontend base

Performance Optimizations

  1. Loading States: Shows skeleton loaders while fetching data
  2. Lazy Loading: Images load on demand
  3. Error Image Handling: Hides broken images gracefully
  4. Caching: Browser caches static assets

Testing Checklist

Common Issues and Solutions

Issue: Empty API Response

Symptom: API returns {} Cause: Biosample not activated or doesn’t exist Solution: Activate biosample through proper channels

Issue: Story Protocol Section Not Showing

Symptom: Section hidden despite biosample having Story data Cause: API not returning story_record field Solution: Check API response includes story_record data

Issue: Authentication Loop

Symptom: Page keeps redirecting to login Cause: Invalid or expired Web3 signature Solution: Clear localStorage and re-authenticate

Future Enhancements

  1. Real-time Updates: WebSocket for live biosample status
  2. Enhanced Visualizations: More interactive charts
  3. Batch Operations: Handle multiple biosamples
  4. Export Features: Download biosample reports
  5. Advanced Filtering: Search within biosample files