Skip to content

Repository files navigation

NicoBase Web

Personal health desktop app. The Cloudflare Worker pulls Oura, fuses + scores daily snapshots into D1, and this Vite app reads them. Goals, chapters, and context flags remain writable on the sync API.

NicoBase iOS is paused — do not block web work on phone sync. When mobile resumes, it should consume the same API rather than own ingestion.

Full design: NicoBase-web-spec.md. Cross-repo notes: LINKING.md. Open work: NicoBase-web-todo.md. Web-first proposal: docs/web-first-proposal.html.

Current status

  • Repository is consolidated on a single branch: main.
  • CI is green on main for token drift, server tests, and app/server TypeScript builds.
  • Production Worker, D1, CORS, and Worker secrets are provisioned. CLOUDFLARE_API_TOKEN is set; push-to-main triggers real Pages + Worker deploys.
  • deploy-worker.yml applies pending D1 migrations (wrangler d1 migrations apply nicobase --remote) before each Worker deploy.
  • Active direction (2026-07-26): web-first Oura ownership. Worker cron at 05:00 HKT + sidebar Refresh / Settings sync. Day keys Asia/Hong_Kong. Access-only login on sudx.io. iOS / HealthKit deferred.

Oura range backfill

POST /v1/admin/oura/sync accepts from / to (YYYY-MM-DD, HKT day keys). Default window is the last 30 days. Nightly cron uses a 14-day window.

Workers have CPU time limits — prefer ≤30-day chunks for first-time or catch-up backfills, and wait for each request to finish before starting the next. Re-running an overlapping range is safe (upserts). There is no skip-if-fresh optimization yet; expect full recompute for the requested days.

Layout

├── app/              Vite + React + TypeScript frontend, local port 5173
├── server/           Hono Cloudflare Worker + D1 sync layer, local port 8788
├── shared/           Zod DTO schema + design tokens
├── scripts/          token codegen + dev data seeding
├── artifacts/ios/    Tokens.generated.swift export for nicobase-ios
└── .github/workflows CI + conditional Cloudflare deploy workflows

Local dev quickstart

# 1. Install workspace deps
pnpm install

# 2. Start the local worker. This uses in-memory data, no D1 required.
cd server && bun --hot dev-bun.ts

# 3. In another shell, start the frontend. Vite proxies /v1 to :8788.
cd app && pnpm dev

# 4. From the repo root, seed plausible dev data after the worker is running.
node scripts/seed-dev.mjs 30

Open http://localhost:5173 — no login screen. Vite proxies /v1 to the local worker and injects the dev web key (web.local-dev) on each request.

Dev-only phone seed/write key (curl / scripts, not the browser UI):

phone.local-dev

Local Wrangler path

For local Wrangler/D1 instead of dev-bun.ts:

cp server/.dev.vars.example server/.dev.vars
cd server
npx wrangler d1 migrations apply nicobase --local
pnpm dev

Environment

The app always calls same-origin /v1/*:

  • Local: Vite proxies to http://localhost:8788 and injects web.local-dev (or NICOBASE_WEB_API_KEY if set in the shell).
  • Production: Pages Functions proxy to the Worker and inject the web API key server-side. Do not set VITE_SYNC_URL on production builds.

Production URLs:

Web (canonical): https://nicobase.sudx.io   (Cloudflare Access login)
Worker (direct): https://nicobase-sync.nicolasmonterog.workers.dev

https://nicobase.pages.dev redirects to https://nicobase.sudx.io.

Template: app/.env.example.

Worker secrets are not committed. Production uses Cloudflare secrets on the Worker plus NICOBASE_WEB_API_KEY on the Pages project for the proxy. See SECRETS.md.

Checks

Run the same narrow checks used by CI:

make tokens-check
pnpm --filter nicobase-web-server test
pnpm build

Or run workspace tests only:

pnpm test

There is no ESLint config and no frontend test suite yet.

Design tokens

shared/tokens.json is the source of truth for colors, spacing, and radii. The codegen at scripts/sync-tokens.mjs writes:

  • app/src/tokens.generated.css — imported by app/src/styles.css.
  • artifacts/ios/Tokens.generated.swift — copy into nicobase-ios at NicoBase/Shared/DesignSystem/Tokens.generated.swift.

From the repository root:

make tokens
make tokens-check

Do not hand-edit generated files; CI rejects drift.

Current limitation: Swift codegen emits color tokens only. Spacing/radius are exported to web CSS, but iOS spacing/typography remain hand-written until the follow-up in NicoBase-web-todo.md.

Production deploy

Production resources:

Worker: https://nicobase-sync.nicolasmonterog.workers.dev
Pages:  https://nicobase.sudx.io  (nicobase.pages.dev → redirect)
D1:     nicobase / 3c6969e0-aca1-488c-a05d-6060e9c5788a
CORS:   https://nicobase.sudx.io

Manual Worker deploy:

cd server
npx wrangler d1 migrations apply nicobase --remote
npx wrangler secret list
npx wrangler deploy

Manual Pages deploy:

pnpm --filter nicobase-web-app build
npx wrangler pages deploy app/dist --cwd app --project-name nicobase --branch main

Ensure the Pages project has NICOBASE_WEB_API_KEY set (wrangler pages secret put …). See SECRETS.md.

GitHub Actions:

  • .github/workflows/ci.yml runs on PRs and pushes to main.
  • .github/workflows/deploy-worker.yml runs on main when server/**, shared/**, pnpm-lock.yaml, or the workflow changes.
  • .github/workflows/deploy-pages.yml runs on main when app/**, shared/**, pnpm-lock.yaml, or the workflow changes.

Deploy workflows require these repo secrets:

CLOUDFLARE_ACCOUNT_ID  set
CLOUDFLARE_API_TOKEN   set (token: nicobase-web-deploy, account-locked to Nicolasmonterog)

deploy-worker.yml runs wrangler d1 migrations apply nicobase --remote before wrangler deploy, so adding a migration file to server/migrations/ is enough — the next push to main applies it.

About

NicoBase desktop companion — Vite + React + Cloudflare Worker + D1

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages