* rewards: claim what the chain pays, without recording a score first
The People chain has no pezRewards.recordTrustScore and no userEpochScores since the payroll
started holding the roll still through each claim window: a claim pays the trust score at
claim time times the epoch's rate, plus the seat share for a Parlementer seat taken by the
time of the roll. The app still asked for the recorded score, so the claimable list was
always empty, and three screens offered a Record Trust Score button that signed a call that
does not exist.
The buttons, their handlers and texts, and the messages for an error and a success that can
no longer happen are removed; the claimable amount is worked out as the chain's entitlement
does, and the empty state shows in every epoch status. Past recordTrustScore extrinsics in
the transaction history keep their label.
* backend: body-parser 2.4.0 and ip-address 10.7.5
npm audit on the production dependencies: body-parser 2.0.0-2.3.0 (GHSA-27r3-jxmh-p828,
high, denial of service by trailing bytes after a compressed body) and ip-address <=10.7.3
(GHSA-rxp7-6hxx-x8q5, moderate). Lockfile only; npm audit --omit=dev finds nothing after.
* ops: lower the typecheck baseline to 335
Four TS2339 errors in shared/lib/scores.ts went with the userEpochScores code.
* web: dompurify 3.4.17 and zod 4.6.7
npm audit on the production dependencies: dompurify <=3.4.16 (critical: GHSA-cg2g-xh64-v4q7,
GHSA-mrv2-3pqr-j5jr, GHSA-c6gr-qvv4-5v3f) and zod <4.6.6 (high, GHSA-mrhx-c7xc-m3w5, fixed
only in 4.x). No code imports zod; it is here for abitype, whose peer range is
^3.22.0 || ^4.0.0. Typecheck ratchet, lint and the build are unchanged.
mobile/ was moved out in April (18d41743), but the root package.json still
ran it: `npm run build`, `lint`, `test` and `dev` all called into a missing
directory and failed. The scripts now cover what is here (web, sign,
backend), concurrently is gone with the only command that needed it, and the
root lockfile shrinks to nothing.
The README described the mobile app and not the signing portal; it now lists
the real layout (web, sign, backend, shared, ops).
Node 20 is past its end of life. CI and both images move to Node 24; the
backend's sqlite3 native module builds and its tests pass on 24.
- Move backend and root transitive deps to patched versions
- Upgrade web to react-router 7.18 and patched vitest/dompurify
- Move the sign app to vite 6.4.3
- Depend on the fixed crypto stack in web, sign and backend
- sign: typecheck the shared code it compiles
- ci: run the quality jobs on GitHub-hosted runners, and build sign
- Move to @pezkuwi/api 16.5.39
- ci: run CodeQL for JavaScript/TypeScript on a GitHub-hosted runner
Closes the "backend has zero CI + manual SSH deploy" audit finding for the indexer.
Part B — CI-runnable tests (the integration-tests/*.live.test.js need a live chain and
are excluded, not stubbed): extract injectable cores (indexer.js: DB+HTTP+decode, no
@pezkuwi import; council.js: createApp factory for the council/KYC routes). New node:test
suite (19/19, fully offline) — in-memory sqlite, dependency-injected chain stub, an
in-memory fake-supabase, and REAL @pezkuwi keyring signatures proving 401 bad-sig /
400 msg-mismatch / 200 valid / 409 dup / 403 non-member / threshold auto-execute. Backend
job now runs npm ci + npm test and is in ci-gate (failing tests block merge). Fixed a
latent bug: block indexing now awaits each insert (was fire-and-forget forEach). Added
runtime deps server.js imported but were missing from package.json (@supabase/supabase-js,
pino, pino-http) — server.js could not have `npm ci`-run before.
Part C — Dockerfile (non-root, HEALTHCHECK /health, sqlite state on a /data VOLUME kept
out of the image) + backend deploy pipeline mirroring the web one: build+push to GHCR,
cosign keyless sign + verify, ssh deploy with the DB volume preserved across deploys,
/health poll, auto-rollback to previous SHA, same Telegram CEO approval gate, main/tags
only, never fork PRs. New secrets documented in backend/DEPLOY.md (BACKEND_VPS_HOST/USER/
SSH_KEY). DB_PATH env (default ./transactions.db) lets prod point at the volume.
Note for owner: if server.js (council/KYC bootstrap) is legacy/unused, its newly-added
deps can be dropped instead.
Audit remediation (build/supply-chain/quality):
- Add `@pezkuwi/api-augment` import in main.tsx -> tsc errors 416->328 (Codec-typed
on-chain reads now augmented); add `typecheck` script + a non-blocking Typecheck CI
step (flip to blocking once errors reach 0).
- CI: `npm install` -> `npm ci` (lockfile enforced) in web + security-audit jobs; add a
Backend Indexer job (npm ci + node --check + non-blocking high/critical audit). No
live tests run in CI (they need a live chain) — a mockable CI test subset is a
follow-up.
- Vulns: bump dompurify ^3.4.12 + postcss ^8.5.23 (web prod highs cleared; only the
react-router v7 open-redirect remains, deferred as a breaking major); backend tar
^7.5.22 + ws ^8.21.1 (clears the critical tar advisory). Lockfiles regenerated.
- Prod build now drops console/debugger (vite esbuild.drop); NotificationBell realtime
subscription now returns cleanup + uses a per-user channel (fixes leak); ProfileSettings
language codes aligned to i18n config (ku-kurmanji/ku-sorani).
- Root package.json sdk-ui path env-driven (${SDK_UI_DIR}); generate-docs rustup path
resolved dynamically; Docker image license label MIT (matches LICENSE). Removed scratch
files (mimari.txt, _scratch_credit_serok.mjs).
- Remove pezkuwi-sdk-ui from pwap (now at /home/mamostehp/pezkuwi-sdk-ui)
- Add scripts/fix-pezkuwi-packages.cjs for @pezkuwi package path fixes
- Add postinstall hook to mobile package.json
- Update metro.config.cjs documentation
- Update backend @pezkuwi/api version to 16.5.11
pezkuwi-sdk-ui is now a standalone repo at:
https://github.com/pezkuwichain/pezkuwi-sdk-ui
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fixed TypeScript type assertion issues
- Updated imports from api-augment/substrate to api-augment/bizinikiwi
- Fixed imgConvert.mjs header and imports
- Added @ts-expect-error for runtime-converted types
- Fixed all @polkadot copyright headers to @pezkuwi