Keysat 5de974edaf ESLint, server-action tests, export-my-data, enriched healthcheck, CHANGELOG
ESLint
- Pinned eslint@^8 + eslint-config-next@^14 to match Next 14's `next lint`.
  ESLint 9's flat-config breaks `next lint` for legacy projects.
- .eslintrc.json extends next/core-web-vitals; ignores tests/, scripts/,
  prisma/data/, .next/, node_modules.
- 7 pre-existing warnings surfaced (exhaustive-deps + alt-text + img tag
  in user-written components). Left as warnings — pre-existing, not
  breaking. CI runs lint; warnings don't fail the job.

Server action tests (tests/actions-admin.test.ts, tests/actions-auth.test.ts)
- Vitest setup file (tests/helpers/setup-actions.ts) sets DATABASE_URL
  to a per-process temp SQLite DB and runs `prisma db push` BEFORE
  lib/prisma instantiates its global PrismaClient. Tests then call the
  real server actions against an isolated DB.
- vi.mock + vi.hoisted to mock @/lib/auth.getCurrentUser, next/headers
  cookies+headers, next/navigation redirect, next/cache revalidatePath.
- Coverage:
  - admin: setUserAdmin (Forbidden, promote, last-admin demote refused,
    demote-with-other-admin allowed), deleteUser (last-admin guard,
    self-delete refused, cascading delete to exercises + workouts),
    adminResetPassword (hash-and-revoke, short-password rejected).
  - auth flows: signupAction (closed by default, opens-and-creates,
    mismatched confirm rejected, short pwd rejected, malformed email
    rejected, no email-enumeration leak), changePasswordAction
    (rotate-and-revoke-others, wrong current pwd rejected, no-op pwd
    rejected), deleteMyAccountAction (phrase required, password required,
    last-admin refused, success cascades + clears cookie + redirects).
- Total suite: 34 tests, ~2s.

Export my data (/api/me/export + Settings -> Export my data)
- Downloads a JSON dump of every workout/set/exercise/program tied to
  the user. Excludes password hash and sessions. Filename includes
  email + date. content-disposition: attachment, no-store cache.
- Exported shape matches the underlying tables 1:1 so a future "import
  my data" flow can round-trip without ambiguity.

Enriched /api/health
- Now reports: database.connected, database.journalMode (and walEnabled
  shortcut), users count, instanceSettings.signupsOpen, library.available
  + sizeBytes. Surfaces a `warnings` array if journal_mode != 'wal' but
  doesn't fail the check (app still works without WAL — just unsafe for
  online backups). Returns 503 only on hard DB failure.

CHANGELOG.md
- Single Unreleased section documenting everything that will ship as
  v1.0.0:1 once the maintainer drops a fresh /data snapshot. Added /
  Changed / Removed / Compat-notes sections.
2026-05-09 10:41:13 -05:00

Proof of Work

Self-hosted multi-user workout planner and logger. Plan training cycles, log daily workouts, search your history, and curate a shared exercise library across everyone on the instance. Distributed as a StartOS 0.4 sideload package.

Repo layout

proof-of-work/    Next.js app (TypeScript, Prisma + SQLite, Tailwind, PWA)
start9/0.4/       StartOS 0.4 package wrapper (manifest, Dockerfile,
                  entrypoint, version graph, change-credentials action)

Everything else is generated at build time.

Local development

cd proof-of-work
npm install
npx prisma generate       # important after schema changes
npx prisma db push        # create the dev DB at prisma/data/app.db
npm run db:seed           # admin@local / workout123 + curated library + admin flag
npm run dev               # http://localhost:3000

Multi-user

Every install starts with one admin user (admin@local) and sign-ups closed. To open the instance to additional users:

  • In-app: log in as admin -> Settings -> Instance Settings -> Allow new sign-ups.
  • StartOS: Services -> Proof of Work -> Actions -> Set new signups.

Both write to the same InstanceSettings row; either path works.

When sign-ups are open, anyone reaching the URL can create an account at /auth/signup. New users start with no admin privileges and are automatically seeded the full curated exercise library.

Building the StartOS package

See start9/0.4/DEPLOY_040.md for the full deployment / cutover guide. Short version:

cd start9/0.4
npm ci
make clean
make x86                  # produces proof-of-work_x86_64.s9pk
make install              # sideload to the host in ~/.startos/config.yaml

Curated exercise library

proof-of-work/prisma/exercises.seed.json is the canonical library shipped to every install. It seeds fresh installs (via prisma/seed.ts) and is re-applied on every boot to existing installs (via docker_entrypoint.sh + ensureExerciseLibrary.cjs) so updates flow to all users on package upgrade.

Refresh the JSON from the maintainer's live host:

./start9/0.4/refresh_seed.sh <ssh-target>     # pull a fresh /data snapshot
cd proof-of-work && npm run sync-library      # extract Exercise table -> JSON
git diff prisma/exercises.seed.json

The system is additive only — removing an exercise from the JSON does not delete it from existing installs (users may have logged sets against it). Users' own custom exercises (isCustom = true) are never touched.

Privacy

start9/0.4/seed/data/app.db is your live /data snapshot. It contains real workout history and a bcrypt'd password hash. The top-level .gitignore keeps it out of git; do NOT commit it to any public repo.

S
Description
No description provided
Readme 110 MiB
Languages
TypeScript 93.8%
Shell 2.6%
JavaScript 2.4%
Makefile 0.7%
Dockerfile 0.4%