Skip to content
RezoanurRahmanPublic

About

Wallwise is a durable exhibition planning desk for independent galleries. It connects artist and artwork records, conflict-aware exhibition hangs, auditable lifecycle workflows, installation tasks, and portfolio-ready analytics in one calm workspace.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Wallwise

Wallwise is a durable exhibition planning desk for independent galleries. It brings artist and artwork records, conflict-aware exhibition scheduling, hang placement, installation tasks, append-only activity, and portfolio analytics into one calm workspace.

The frontend is React 19 + Vite. The API is Elysia 1 with the Node adapter. SQLite is the durable source of truth, and an idempotent demo seed makes the first launch useful. The API contract is shared by browser and server code in TypeScript.

Quick start

Prerequisites:

  • Node.js 20.19 or newer (Node 22.12+ is also supported)
  • npm 10 or newer
  • A typical Linux/macOS build toolchain if a prebuilt better-sqlite3 binary is unavailable for your Node platform

Clone the repository, enter the project root, and run exactly these three commands:

npm install
npm run build
npm start

Open http://127.0.0.1:3000. The production server serves the built client and API. By default it creates the durable database at data/wallwise.sqlite, applies the schema, and inserts the fixed demo seed once. No external services, credentials, or seed command are required.

For a reproducibility-focused install, use npm ci instead of npm install. The committed package-lock.json is generated by npm and is the CI install input.

What you can do

  • Review portfolio totals, status distribution, upcoming exhibitions, readiness, conflicts, overdue work, and recent activity on the dashboard.
  • Create, search, edit, and archive artists while preserving their artwork history.
  • Catalog artworks with dimensions, framing, availability, and an embedded artist summary.
  • Create exhibitions with public and installation date windows, then track explicit lifecycle transitions.
  • Hang artworks by wall and position with date/space and double-booking checks that fail atomically.
  • Track installation tasks by category, assignee, due date, and status.
  • Inspect append-only activity for changes and auditable exhibition status moves.
  • Export the complete exhibition portfolio as a properly quoted CSV file.

All API reads and writes use typed envelopes in src/shared/types.ts. The full behavior contract, acceptance criteria, schema decisions, and test strategy are in SPEC.md.

Local development

cp .env.example .env
npm run dev

The web app is available at http://127.0.0.1:5173 and proxies /api to the Node API at http://127.0.0.1:3000. The .env file is optional; defaults work without it. Node reads it with --env-file-if-exists, and Vite exposes only variables that begin with VITE_.

The development scripts are:

  • npm run dev - run the API and Vite client together with restart on change
  • npm run dev:server - run only the API from src/server/index.ts with Node watch and tsx
  • npm run dev:client - run only Vite

The implementation entry points are src/client (rendered through the root index.html) and src/server/index.ts. Configuration expects npm run build:server to bundle that server entry.

Environment

Variable Default / example Purpose
NODE_ENV Set by scripts Development/test modes are explicit; npm start forces production.
HOST 127.0.0.1 API bind address. Use 0.0.0.0 only when intentionally exposing it.
PORT 3000 Production/API port. E2E uses 4173.
DATABASE_PATH ./data/wallwise.sqlite Durable SQLite file. Parent directories are created by the server.
CORS_ORIGIN http://localhost:5173,http://127.0.0.1:5173 Comma-separated development browser origins.
VITE_DEV_PORT 5173 Strict Vite dev port.
VITE_API_PROXY_TARGET http://127.0.0.1:3000 Vite proxy target for /api.

SQLite and seed data

SQLite is the durable application database, not an in-memory store or a cache. Writes and their audit entries commit together. The demo seed runs once in a transaction and records its marker and version in app_meta. Restarting the server does not replace or reset existing gallery work.

To intentionally rebuild a local demo database, stop the server and remove all three database files:

rm -f data/wallwise.sqlite data/wallwise.sqlite-shm data/wallwise.sqlite-wal

The next start recreates and seeds the database. Tests use disposable files under .tmp/ and never touch the development database.

Build and run

npm run build
npm start

npm run build performs a full TypeScript check, builds the Vite client into dist/, and bundles the Node server to dist/server/index.js. npm start runs that production bundle. The server also serves the built client and SPA fallback for non-API routes.

Build components are available separately with npm run build:client and npm run build:server. The server bundle keeps runtime dependencies external, so deploy dist/, package.json, package-lock.json, and the installed production dependencies together. Use Node 20.19+; Vite 7 and Node ESM are required.

Quality commands

Command What it does
npm run lint ESLint with TypeScript and React rules; warnings fail.
npm run format Write Prettier formatting across the repository.
npm run format:check Verify formatting without writing.
npm run typecheck Strict browser/shared and server TypeScript checks.
npm test Vitest unit and component tests in jsdom.
npm run test:integration Vitest integration tests against real SQLite at .tmp/wallwise-integration.sqlite.
npm start Serve the build; CI smoke-checks GET http://127.0.0.1:3000/api/health.
npm run test:e2e Build, then run Playwright Chromium against .tmp/wallwise-e2e.sqlite.

Unit tests are discovered in src/**/*.test.*, src/**/*.spec.*, tests/unit, and tests/components. Integration tests live in tests/integration or use the *.integration.test.ts suffix. Playwright specs live in tests/e2e/*.spec.ts. If a shared jsdom setup file is added at src/test/setup.ts, src/client/test/setup.ts, or tests/setup.ts, the unit configuration loads it automatically.

Browser tests

Install Playwright's Chromium once after installing npm packages:

npx playwright install chromium

Then run:

npm run test:e2e

This command builds the app first. Playwright owns the production server lifecycle, waits for /api/health, and starts from a deterministic SQLite path. The start:e2e script clears stale database/WAL/SHM files before the server starts. Browser tests fail on missing API readiness and do not mock production data.

API conventions

  • JSON API base: /api; readiness endpoint: /api/health.
  • List envelope: { data, pagination }; detail envelope: { data }; mutation envelope: { data, message, activity? }.
  • Failure envelope: { error: { code, message, field?, details? } }.
  • Dates are YYYY-MM-DD; timestamps are ISO UTC strings. Date ranges are inclusive.
  • IDs are opaque strings. List pagination defaults to 25 and is bounded at 100.
  • Exhibition status can only change through POST /api/exhibitions/:id/transitions using the shared transition map.
  • Portfolio CSV is available from GET /api/export/exhibitions.csv.

UI code should parse unknown failures through normalizeErrorResponse from src/shared/http.ts and use the shared error/status constants instead of duplicating string values.

Architecture

src/
  shared/            Authoritative API types, constants, and HTTP helpers
  client/            React 19 UI
  server/            Elysia app, routes, validation, SQLite repository, and seed
index.html           Vite browser entry document
tests/
  unit/              Vitest unit/component tests
  integration/       Real-SQLite API and storage tests
  e2e/               Playwright user workflows
dist/
  index.html         Vite production client
  assets/            Hashed browser assets
  server/index.js    Bundled Node server

The client never opens SQLite directly. It talks to /api; Vite proxies that path in development and the production server owns it in deployment. The server owns validation, conflict decisions, transitions, audit writes, and computed analytics. Shared modules contain no browser-only globals so both sides can import them.

CI

.github/workflows/ci.yml runs on pushes and pull requests with Node 20. It installs from the lockfile, installs Playwright Chromium, and runs all gates in order: lint, format check, typecheck, unit tests, integration tests, production build, production smoke check, and browser tests. The smoke step starts npm start, polls GET http://127.0.0.1:3000/api/health, prints the server log if readiness fails, and stops the production server before Playwright starts its own. CI uses the same npm scripts as local development and sets deterministic .tmp/ database paths. No repository secrets or external services are needed.

License

Wallwise is released under the MIT License. See LICENSE.

About

Wallwise is a durable exhibition planning desk for independent galleries. It connects artist and artwork records, conflict-aware exhibition hangs, auditable lifecycle workflows, installation tasks, and portfolio-ready analytics in one calm workspace.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages