Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
# deepevents.ai
deepevents.ai main codebase

## Modules

- [`scientific-data-code-hosting`](./scientific-data-code-hosting) - runnable prototype for structured artifact storage, FAIR metadata, dataset versioning, executable environments, and compute triggers.
60 changes: 60 additions & 0 deletions scientific-data-code-hosting/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Scientific Data & Code Hosting

This module is a self-contained implementation for SCIBASE.AI issue #14. It models structured storage, metadata standards, FAIR compliance, upload versioning, artifact previews, executable environments, and compute triggers for reproducible scientific data/code hosting.

## What It Covers

- Storage manifest for datasets, metadata, code, notebooks, figures, models, and raw instrument output.
- Folder-based organization for `data/`, `code/`, `results/`, and `raw/`.
- Metadata-aware previews for CSV tables, notebooks, code, figures, and binary/model artifacts.
- Upload versioning and dataset diffing.
- JSON-LD, DataCite, and schema.org-style metadata.
- FAIR compliance flags for findability, accessibility, interoperability, and reusability.
- Scientific tagging for keywords, instruments, organisms, and variables.
- Docker/Kubernetes-style executable environments for Python, R, and Julia stacks.
- Sandboxed analysis execution and manual/cron compute triggers.

## Run Locally

```bash
cd scientific-data-code-hosting
npm test
npm start
```

Then open `http://localhost:4133`.

## API Surface

- `GET /api/dashboard`
- `GET /api/storage/manifest`
- `GET /api/metadata`
- `GET /api/execute?environment=env-python`

## Requirement Mapping

- Scalable storage engine: implemented by `buildStorageManifest`.
- Major file types and folder organization: represented in `artifactStore.folders` and `artifactStore.artifacts`.
- Metadata-aware previews: implemented by `buildPreview`.
- Upload versioning and diffing: implemented by `versions` and `diffDatasetVersions`.
- JSON-LD, DataCite, schema.org, and FAIR: implemented by `buildMetadataBundle`.
- Tagging system: returned in metadata tags and artifact tags.
- Executable environments: represented by Docker/Kubernetes environment definitions.
- Sandboxed execution and compute triggers: implemented by `runExecutableEnvironment` and dashboard trigger metadata.

## Verification

```bash
npm test
node src/server.js
```

Optional smoke checks:

```bash
curl -s http://localhost:4133/api/dashboard
curl -s http://localhost:4133/api/storage/manifest
curl -s "http://localhost:4133/api/execute?environment=env-python"
```

Demo artifacts are committed under `docs/demo/`, including `dashboard.png` and `scientific-data-code-hosting-demo.mp4`.
6 changes: 6 additions & 0 deletions scientific-data-code-hosting/docs/demo-script.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Demo Script

1. Run `npm test` to verify storage manifests, metadata standards, dataset diffs, executable environments, and dashboard payloads.
2. Run `npm start` and open `http://localhost:4133`.
3. Confirm the dashboard shows artifact previews, FAIR metadata, dataset version diff, and sandbox execution.
4. Smoke-test `/api/storage/manifest`, `/api/metadata`, and `/api/execute?environment=env-python`.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
14 changes: 14 additions & 0 deletions scientific-data-code-hosting/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "@scibase/scientific-data-code-hosting",
"version": "0.1.0",
"private": true,
"description": "Self-contained scientific data and code hosting prototype for SCIBASE.AI issue #14.",
"type": "module",
"scripts": {
"start": "node src/server.js",
"test": "node --test test/*.test.js"
},
"engines": {
"node": ">=20"
}
}
30 changes: 30 additions & 0 deletions scientific-data-code-hosting/public/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const dashboard = await fetch("/api/dashboard").then((response) => response.json());

document.querySelector("#storage").textContent = `${dashboard.manifest.artifacts.length} artifacts · ${dashboard.manifest.totalBytes} bytes`;
document.querySelector("#artifacts").innerHTML = dashboard.manifest.artifacts
.map((artifact) => `<div class="row"><strong>${artifact.path}</strong><span>${artifact.type} · ${artifact.preview.kind}</span></div>`)
.join("");

document.querySelector("#metadata").innerHTML = [
row("DOI", dashboard.metadata.dataCite.identifier.identifier),
row("Findable", dashboard.metadata.fair.findable),
row("Accessible", dashboard.metadata.fair.accessible),
row("Reusable", dashboard.metadata.fair.reusable)
].join("");

document.querySelector("#diff").innerHTML = [
row("Added samples", dashboard.versionDiff.addedSamples.join(", ") || "none"),
row("Removed samples", dashboard.versionDiff.removedSamples.join(", ") || "none"),
row("Row delta", dashboard.versionDiff.rowDelta)
].join("");

document.querySelector("#execution").innerHTML = [
row("Status", dashboard.execution.status),
row("Environment", dashboard.execution.environment.name),
row("Sandbox", `${dashboard.execution.sandbox.isolation}, network ${dashboard.execution.sandbox.network}`),
row("Score", dashboard.execution.reproducibilityScore)
].join("");

function row(label, value) {
return `<div class="row"><span>${label}</span><strong>${String(value)}</strong></div>`;
}
40 changes: 40 additions & 0 deletions scientific-data-code-hosting/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>SCIBASE Data & Code Hosting</title>
<link rel="stylesheet" href="/styles.css" />
</head>
<body>
<main class="shell">
<header>
<p>SCIBASE.AI / issue #14</p>
<h1>Scientific Data & Code Hosting</h1>
</header>
<section class="grid">
<article class="panel hero">
<p class="label">Storage Engine</p>
<h2 id="storage">Loading...</h2>
<div id="artifacts"></div>
</article>
<article class="panel">
<p class="label">Metadata & FAIR</p>
<h2>Standards bundle</h2>
<div id="metadata"></div>
</article>
<article class="panel">
<p class="label">Versioning</p>
<h2>Dataset diff</h2>
<div id="diff"></div>
</article>
<article class="panel">
<p class="label">Executable Environment</p>
<h2>Sandbox run</h2>
<div id="execution"></div>
</article>
</section>
</main>
<script type="module" src="/app.js"></script>
</body>
</html>
110 changes: 110 additions & 0 deletions scientific-data-code-hosting/public/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
:root {
--ink: #111715;
--muted: #64706b;
--line: #d8dfda;
--paper: #f3f5ef;
--panel: #ffffff;
--green: #17664d;
--blue: #265f8a;
}

* {
box-sizing: border-box;
}

body {
margin: 0;
background: var(--paper);
color: var(--ink);
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

.shell {
max-width: 1280px;
margin: 0 auto;
padding: 32px;
}

header {
display: flex;
align-items: end;
justify-content: space-between;
gap: 24px;
margin-bottom: 24px;
}

p,
h1,
h2 {
margin: 0;
}

header p,
.label {
color: var(--muted);
font-size: 12px;
font-weight: 900;
letter-spacing: 0.08em;
text-transform: uppercase;
}

h1 {
max-width: 820px;
font-size: clamp(38px, 6vw, 76px);
line-height: 0.95;
}

h2 {
margin-top: 8px;
font-size: 24px;
}

.grid {
display: grid;
grid-template-columns: 1.05fr 0.95fr;
gap: 16px;
}

.panel {
min-height: 260px;
border: 1px solid var(--line);
background: var(--panel);
padding: 24px;
}

.hero {
grid-row: span 2;
}

.row {
border-top: 1px solid var(--line);
padding-top: 12px;
margin-top: 14px;
}

.row span {
display: block;
color: var(--muted);
}

.row strong {
display: block;
color: var(--green);
overflow-wrap: anywhere;
}

.hero .row strong {
color: var(--blue);
}

@media (max-width: 820px) {
.shell {
padding: 18px;
}

header,
.grid {
display: grid;
grid-template-columns: 1fr;
}
}
Loading