The product surface. The apps a cooperative actually uses: a member dashboard, an admin panel, and the API that will sit between them and the chain.
Part of Lumio — an open-source cooperative finance platform.
| App | Name | Stack | Port | Responsibility |
|---|---|---|---|---|
apps/dashboard |
@lumio/dashboard |
Next.js (App Router) | 3001 | Member experience — contributions, treasury, votes. |
apps/admin |
@lumio/admin |
Next.js (App Router) | 3002 | Operator panel — members, cycles, payouts. |
apps/api |
@lumio/api |
NestJS | 3000 | Backend — talks to contracts via @lumio/sdk. |
⚠️ Scaffold. Every page is a placeholder rendered with the real design system, and the API returnsnot-implementedfor domain routes (onlyGET /healthdoes real work). No auth, no database schema, no live contract calls yet — those are later phases.
- Node.js ≥ 20
- pnpm 9.12 (
corepack enableornpm i -g pnpm@9.12.0) - A sibling
lumio-sdkcheckout, built (see below)
This repo does not vendor @lumio/ui, @lumio/sdk, or @lumio/shared. It consumes them
through pnpm's link: protocol pointing at a sibling lumio-sdk checkout. pnpm workspaces
can't span repository roots, so the one hard prerequisite is:
Check out lumio-sdk next to lumio-app, and build it first.
lumio-network/
├── lumio-sdk/ # ← must exist and be built
└── lumio-app/ # ← this repo
# 1. Build the SDK packages the apps link against
cd ../lumio-sdk
pnpm install
pnpm build
# 2. Then install + run the apps
cd ../lumio-app
pnpm install
pnpm dev # dashboard :3001, admin :3002, api :3000 (turbo runs all)Individual apps:
pnpm --filter @lumio/dashboard dev
pnpm --filter @lumio/admin dev
pnpm --filter @lumio/api devVerify the API:
curl http://localhost:3000/health
# {"status":"ok","service":"lumio-api","time":"...","indicators":{"liveness":{"status":"up","details":"uptime: 123s"}}}CORS_ORIGINS— Comma-separated list of allowed CORS origins for the API. Defaults tohttp://localhost:3001,http://localhost:3002(dashboard and admin dev ports).PORT— API server port. Defaults to3000.
pnpm build # turbo: next build ×2 + tsc (api)
pnpm typecheck # tsc --noEmit across apps
pnpm lint # eslint .
pnpm format # prettier --write .The apps import the finalized brand foundation from @lumio/ui:
- Tokens —
app/layout.tsximports@lumio/ui/tokens/design-tokens.css(the raw CSS variables) and wires thenext/fontfamilies (Fraunces / IBM Plex Sans / IBM Plex Mono) into them. - Tailwind preset —
tailwind.config.tsextends@lumio/ui/tailwind-preset, so utilities likebg-ink-950,text-lumen, andfont-displayresolve to brand values. - Logo & favicon — the real SVGs from the foundation kit are copied verbatim into each app's
public/brand/; the nav renderslumio-lockup-horizontal-on-dark.svgand the tab usesfavicon.svg. They are never redrawn.
docker-compose.yml defines Postgres (works today: docker compose up db) and the API. The API
image build depends on @lumio/sdk being published to a registry (a later phase) because the
Docker build context can't reach the sibling lumio-sdk checkout — until then, run the API on the
host with pnpm --filter @lumio/api dev.
Today the apps link to a sibling lumio-sdk checkout via the link: protocol. Once the SDK
packages are published to npm, switch each app to versioned dependencies so a fresh clone (Vercel,
Docker, CI) installs them straight from the registry — no sibling checkout required.
In apps/dashboard/package.json, apps/admin/package.json, and apps/api/package.json, replace:
with the published versions (match whatever lumio-sdk released, e.g. ^0.1.0):
"@lumio/sdk": "^0.1.0",
"@lumio/shared": "^0.1.0",
"@lumio/ui": "^0.1.0",(apps/api does not depend on @lumio/ui; only swap the two it uses.) Then run pnpm install to
refresh the lockfile. After this, the sibling-checkout + build-SDK-first prerequisite above no
longer applies, and the API Docker image can build. See lumio-sdk/PUBLISHING.md for the release
side of this.