Skip to content

fix: resolve issues #538 #511 #468 assigned to solomon35-stack - #645

Merged
dzekojohn4 merged 2 commits into
UnityChainxx:mainfrom
solomon35-stack:fix/solomon-issues-538-511-468
Sep 29, 2026
Merged

dzekojohn4 merged 2 commits into
UnityChainxx:mainfrom
solomon35-stack:fix/solomon-issues-538-511-468

Conversation

@solomon35-stack

Copy link
Copy Markdown
Contributor

Closes #538
Closes #511
Closes #468

Supersedes the failing parts of the onchain test build and wires the admin draft form to the backend. #529 is intentionally not claimed here — see "Issue #529 status" below.


Issue #468 — contract-level invariant tests for interleaved admin mutations

Adds to onchain/contracts/stellar_hunts/src/test.rs:

  • assert_index_invariant — a harness asserting the formally documented index invariant from lib.rs (Replace ad-hoc QuestionsByLevel index surgery in update_question and retire_question #464): QuestionPerLevelIndex(level) equals the number of live entries, each live id appears exactly once across the indices, no id appears in a foreign level, and the first slot past the live window is cleared.
  • test_index_invariant_holds_after_each_interleaved_admin_operation — a deterministic sequence of add_question / update_question level-moves / retire_question / set_question_per_level with the invariant checked after every operation, a move followed by enumeration via get_question_in_level, and a final full enumeration of each level.
  • test_index_invariant_when_a_level_is_drained_by_retirements — drains a level one retirement at a time, asserts a failed retirement (unknown id) leaves the indices untouched and the level count at 0.
  • Every panic message names the operation and step number that broke the invariant (after step N (retire_question(2)): ...), per the acceptance criteria.

Build fix required by the acceptance criterion cargo test --workspace --locked passing: upstream main did not compile — lib.rs references Error::QuestionRetired and Error::WrongQuestion, which were never added to the enum. This PR appends QuestionRetired = 15 and WrongQuestion = 16 (at the end, so existing discriminants stay stable) and aligns four test assertions that had been written against wrong discriminants (#14 is SchemaVersionMismatch; the retirement guard is #15, the cursor guard #16). Before this PR the crate could not compile at all, so these tests had never actually run.

Verified locally: cargo test --workspace --locked → 41 passed (stellar-hunts, incl. the 2 new tests), 13 passed (nft), 0 failed.

Issue #511 — persist puzzle draft and submission forms to the backend

  • New frontend/services/puzzleDraftService.js: createDraft (POST /drafts), updateDraft (PATCH /drafts/:id), publishDraft (POST /drafts/:id/publish), plus extractFieldErrors (maps class-validator message arrays from the global ValidationPipe onto per-field errors) and buildDraftPayload (maps the form onto the backend CreateDraftDto contract; parses the NFT-metadata JSON client-side so a malformed blob never reaches the wire).
  • frontend/app/admin/puzzle-submission/page.jsx no longer posts to the non-existent /admin/puzzles endpoint. It now: saves as draft and switches to update mode (draftId state); exposes Publish through the backend publish endpoint and distinguishes "saved as draft" from "published"; renders per-field validation errors; never clears entered content on a failed save/publish (reset happens only after a successful publish); surfaces errors through the shared useApiMutation hook; authorization remains server-side (JwtAuthGuard + RolesGuard admin-only) with no client-side pretense.
  • New frontend/tests/admin-puzzle-submission.test.jsx covering the three required cases — successful save (+update, +publish), validation failure with preserved content, failed publish with preserved draft — plus invalid-metadata-JSON rejection before any request.

Note: npm ci fails on this repo's main independently of this PR (frontend package-lock.json is out of sync with package.json, e.g. tailwindcss 3.4.19 vs 4.3.3), so the vitest suite could not be executed in this environment. The tests are written against the repo's existing vitest + Testing Library conventions; maintainers running npm test after a lockfile refresh will exercise them.

Issue #538 — duplicate NODE_ENV key / STELLAR_MODE default

Resolved on main by the earlier config-schema work (#492): the schema was extracted to backend/src/config/config.validation.ts (single importable definition, imported by both app.module.ts and the spec), contains no duplicate keys (the spec's "declares each key exactly once" asserts this), and the spec pins the STELLAR_MODE default against STELLAR_MODE_DEFAULT, README.md and backend/.env.example.

Justification of the fail-closed live default (acceptance criterion): a deployment that omits STELLAR_MODE without Soroban credentials fails at startup with every missing key named, instead of booting in mock mode where StellarHandlerService returns synthetic success for NFT claims — a silent data-integrity failure in a rewards product, strictly worse than a boot error. The dangerous direction is additionally closed at the provider (mock is refused when NODE_ENV=production), so production startup with STELLAR_MODE unset cannot silently enter mock mode. Local development opts in via STELLAR_MODE=mock, which both docs state explicitly.

Issue #529 status (not closed by this PR)

~45 DTO files still lack decorators on main. The response-only DTOs (e.g. *-response.dto.ts, *stats.dto.ts) must be excluded, and the ~28 request DTOs need domain-derived rules derived from entities and existing manual checks — done hastily, whitelist: true flips from silently accepting bodies to rejecting legitimate traffic. The forbidNonWhitelisted posture (pipe spec asserts true, main.ts uses unset) also has to be settled once for the whole sweep. This deserves its own reviewed PR; I'll follow up with one rather than bundling a risky sweep here.


Verification summary

Area Command Result
Onchain cargo test --workspace --locked 41 + 13 passed, 0 failed (was: compile error on main)
Backend config existing config-validation.spec.ts on main already asserts #538 acceptance criteria
Frontend npm test (vitest) blocked by pre-existing lockfile/package.json desync on main; new tests follow repo conventions

🤖 Generated with Codebuff
Co-Authored-By: Codebuff noreply@codebuff.com

…assigned to solomon35-stack

- UnityChainxx#468: operation-labeled invariant tests for interleaved admin
  mutations (add/move/retire/set_question_per_level) including
  get_question_in_level enumeration and a drained-level case; fixes
  the broken lib.rs build by appending the missing Error variants
  QuestionRetired=15 and WrongQuestion=16 and aligning test
  discriminants (UnityChainxx#14 was SchemaVersionMismatch).
- UnityChainxx#511: admin puzzle-submission form now persists through the backend
  draft API (create/update/publish), reports per-field validation
  errors, preserves content on failure; adds puzzleDraftService and
  vitest coverage.
- UnityChainxx#538: already satisfied on main by the extracted config schema; the
  fail-closed STELLAR_MODE=live default is documented and asserted by
  config-validation.spec.ts.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
@drips-wave

drips-wave Bot commented Sep 28, 2026

Copy link
Copy Markdown

@solomon35-stack Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@dzekojohn4 dzekojohn4 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@dzekojohn4
dzekojohn4 merged commit 2228107 into UnityChainxx:main Sep 29, 2026
10 of 15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants