A web app for company handbooks (SOPs) and team training. One frontend, hosted on GitHub Pages, serves every company. Each company runs its own backend on Bunny: one edge script, one Bunny Database and one Storage zone.
This README covers what is built so far (milestone 1: foundations). It will become the full setup guide in milestone 9.
Browser (GitHub Pages, static files in web/)
│ HTTPS + JSON, Authorization: Bearer <session token>
▼
Bunny edge script (one per company, built from edge/src)
├── Bunny Database (one per company)
├── Bunny Storage zone + pull zone (milestone 5)
└── Anthropic Messages API (milestone 8)
People log in with three things: the workspace URL (the address of their company’s edge script, for example https://police.academy.onetake.ai), their email and their password. Admins can share a link that fills in the workspace URL:
https://academy.onetake.ai/?workspace=https://police.academy.onetake.ai
| Path | What it is |
|---|---|
web/ |
The frontend: plain HTML, CSS and JavaScript modules, published as-is. |
edge/src/ |
The backend, written as several modules. edge/src/main.js is the entry point. |
edge/build.mjs |
Joins edge/src into the single file Bunny runs: edge/dist/edge.mjs. |
dev/ |
Local development server and the SQLite adapter used by the tests. |
tests/ |
Automated tests, run with Node’s built-in test runner. |
.github/workflows/ |
Tests on every pull request, frontend publishing, edge script deployment. |
There are no npm dependencies to install. The edge script imports two packages directly from npm at runtime (@bunny.net/edgescript-sdk and @bunny.net/database-client), with exact versions.
You need Node.js 22 or later.
node dev/server.mjs
Then open http://localhost:8080, enter http://localhost:8787 as the workspace URL and dev-setup-code as the setup code. The local server uses a SQLite file, dev/local.db. Stop the server and delete that file to start again from an empty workspace.
To run the tests:
node --test 'tests/*.test.mjs'
To build the edge script:
node edge/build.mjs
Each company does this once, in its own Bunny account.
In the Bunny dashboard, open Edge Platform → Database and create a database. You don’t need to create any tables: the edge script creates them on its first request.
.b-cdn.net. To use your own address, such as police.academy.onetake.ai, add it as a hostname on that pull zone and create the DNS record Bunny shows you.Cache-Control header sent by the script. Every API response is sent with Cache-Control: no-store and must never be cached.Open the database, then Access, click Generate Tokens, then Add Secrets to Edge Script and choose your script. This adds BUNNY_DATABASE_URL and BUNNY_DATABASE_AUTH_TOKEN to the script.
On the script, open Env Configuration → Environment Secrets and add:
| Secret | Value |
|---|---|
ALLOWED_ORIGINS |
The websites allowed to use this workspace, separated by commas. For OneTake AI: https://academy.onetake.ai. Add http://localhost:8080 while testing with the local frontend. |
SETUP_CODE |
A long random code, used once to create the first admin. Keep it private. |
The Storage secrets (STORAGE_ZONE, STORAGE_KEY, STORAGE_REGION_HOST, PUBLIC_FILES_URL) come with milestone 5.
Either way works:
BUNNY_TENANTS repository secret (see below). Every change to edge/ merged into main is deployed to every company.edge-script file from the Tests workflow run of a pull request (or run node edge/build.mjs and take edge/dist/edge.mjs), paste its content into the script editor in the Bunny dashboard, then Save and Publish.Open the frontend, enter the workspace URL, and fill in the “Create the first admin” form with the setup code. This only works while the workspace has no users.
The Deploy edge script workflow reads one repository secret, BUNNY_TENANTS, a JSON list with one entry per company:
[
{ "script_id": "12345", "deploy_key": "the-deploy-key" }
]
Find the script ID and deploy key in the Bunny dashboard, on the script, under Deployments → Settings. A deploy key can only deploy its own script. Add the secret in GitHub under Settings → Secrets and variables → Actions → New repository secret. Company names and IDs never appear in the repository or in the workflow logs.
A company that uses its own copy of this repository sets BUNNY_TENANTS in its copy with just its own entry.
The Publish frontend workflow publishes web/ to GitHub Pages on every change merged into main. In the repository settings, under Pages, set the source to GitHub Actions, then set the custom domain.
ALLOWED_ORIGINS can call the API from a browser.The iteration count is PBKDF2_ITERATIONS in edge/src/lib/crypto.js, currently 600,000. It is being measured on Bunny with the temporary POST /api/bench endpoint; this section will record the result.
MIT. See LICENSE.