# HELIX > **EVOLV and every R&D strand, one helix.** > > The R&D showcase platform of Waterschap Brabantse Delta. EVOLV at its core, > every innovation along the strands. HELIX collects projects, innovations, and updates from across the R&D team in one place — with deep links to repos, dashboards, and demos. Sign-in is gated to the `RnD` Gitea organisation; viewing is open. ## Stack - **SvelteKit 2** + **Svelte 5** + TypeScript - **Tailwind v4** (CSS-first design tokens) - **SQLite** (single file) + **Drizzle ORM** - **Gitea OAuth2** for authoring (no passwords stored) - Pure **SVG + CSS** helix animation — no WebGL ## Local development ```bash nvm use # picks up .nvmrc → Node 20 cp .env.example .env # Fill in GITEA_CLIENT_ID and GITEA_CLIENT_SECRET (see "Gitea OAuth setup" below) npm install npm run db:generate # produces drizzle/0000_*.sql from the schema npm run db:migrate # applies migrations to ./helix.db npm run db:seed # adds example projects + posts so the landing page isn't empty npm run dev # http://localhost:3000 ``` ## Gitea OAuth setup HELIX uses your existing Gitea identity. Create an OAuth2 application once: 1. Open 2. Click **Create new OAuth2 application** 3. Application name: `HELIX (local)` (or `HELIX (production)`) 4. Redirect URI: - local: `http://localhost:3000/auth/gitea/callback` - prod: `https:///auth/gitea/callback` 5. Click **Create application** 6. Copy the **Client ID** and **Client Secret** into your `.env`: ``` GITEA_CLIENT_ID=... GITEA_CLIENT_SECRET=... ``` `GITEA_ALLOWED_ORG=RnD` restricts authoring (sign-in) to members of the `RnD` organisation. Leave it empty to allow any authenticated Gitea user. ## Adding a dashboard embed allowlist host `src/lib/config.ts` → `DASHBOARD_ALLOWED_HOSTS` controls which Grafana / dashboard origins can be embedded inline on a project page. Add a hostname (no scheme, no path) and redeploy. Hosts not on the list render as a "Open in new tab" card instead — never blindly iframed. ## Production deploy (Docker) ```bash cp .env.example .env # fill in Gitea OAuth + ORIGIN docker compose up -d --build ``` The SQLite database lives in the `helix-data` named volume at `/data/helix.db`. Back it up with `docker compose exec helix sqlite3 /data/helix.db .dump`. ## Project layout ``` helix/ ├── src/ │ ├── lib/ │ │ ├── components/ # Helix.svelte, ProjectCard, PostCard, Nav, Footer, DashboardEmbed │ │ ├── server/ │ │ │ ├── db/ # Drizzle schema + client (better-sqlite3) │ │ │ ├── auth.ts # session token + cookie helpers │ │ │ └── gitea.ts # OAuth2 dance + user fetch │ │ ├── config.ts # site name, tagline, dashboard allowlist │ │ └── markdown.ts # marked wrapper + slug/id helpers │ ├── routes/ │ │ ├── +page.svelte # landing (helix hero + recent projects/posts) │ │ ├── projects/ # /projects, /[slug], /new │ │ ├── posts/ # /posts, /[slug], /new │ │ ├── login/ # sign-in page (kicks off Gitea OAuth) │ │ ├── logout/+server.ts # POST → invalidates session │ │ └── auth/gitea/ # OAuth start + callback │ ├── app.html │ ├── app.css # Tailwind v4 entry + design tokens │ ├── app.d.ts # Locals types │ └── hooks.server.ts # session hydration ├── drizzle/ # generated migrations ├── scripts/ │ ├── migrate.js # run pending migrations │ └── seed.js # idempotent example data ├── static/favicon.svg ├── Dockerfile ├── docker-compose.yml ├── drizzle.config.ts ├── svelte.config.js ├── vite.config.ts ├── tailwind.config.ts (none — Tailwind v4 uses @theme in app.css) ├── tsconfig.json └── package.json ``` ## How to post After signing in (top-right → Sign in → Gitea), use: - **+ New** in the nav (or `/projects/new`) — a project: title, summary, markdown body, links - **`/posts/new`** — a shorter update / write-up Both are auth-gated. Anyone in `RnD` on Gitea can post. ## Contributing This is internal R&D — open a PR against `main` on [`gitea.wbd-rd.nl/RnD/helix`](https://gitea.wbd-rd.nl/RnD/helix). ## License Internal — Waterschap Brabantse Delta R&D.