Conversation
Tests cover table existence after schema init, system_state seed rows, orders CRUD and PRIMARY KEY uniqueness, api_keys UNIQUE key_hash constraint, idempotency_keys composite PK behaviour, and WAL/foreign-key pragma enforcement.
…ask-48 test(db): add unit tests for db.js schema and queries
…role storage Closes Stellarkard#65 Closes Stellarkard#66 Closes Stellarkard#67 Closes Stellarkard#68 - Fail-safe (Stellarkard#65): new pause()/unpause()/is_paused() circuit breaker. pay_usdc/pay_xlm reject new payments with Error::ContractPaused while paused, checked before any balance/auth work runs. - RBAC (Stellarkard#67): wires the existing (previously unused) Role system into actual access control — pause() requires at least the Operator role via has_role(), while unpause() deliberately requires the stricter DataKey::Admin address directly, matching init/upgrade's authority level. - Storage optimization (Stellarkard#68): migrates role storage from a single growing Roles: Map<Address, Role> instance-storage entry to per-address DataKey::UserRole(Address) persistent entries. A Map entry re-serializes and rent-extends the *entire* map on every single grant/revoke; per-address keys mean each grant/revoke touches only its own entry. - Tests (Stellarkard#66): 12 new tests covering pause/unpause authorization (Operator can pause, Viewer/no-role cannot, only the stored admin can unpause), paused-payment rejection for both pay_usdc and pay_xlm (including that balances are untouched), per-address role storage independence and overwrite behavior. All 43 pre-existing tests still pass unmodified.
Reconciles this branch's per-address role storage and RBAC-gated pause with PR Stellarkard#233's independently-developed pause/RBAC/docs changes that landed on main in the meantime. Standardizes on a single RBAC-gated pause(env, caller) requiring at least the Operator role, removes the resulting duplicate pause/unpause/is_paused definitions, and fixes init() to grant the Admin role via per-address persistent storage. Also fixes two test-only compile breaks surfaced by the merge: stale is_paused() client calls (renamed to is_paused_view()) and a bare vec! macro in a #![no_std] crate. test_upgrade_works now uploads the contract's own compiled WASM so the upgrade success path is exercised against a hash that actually exists in the test ledger, instead of an arbitrary all-1s hash.
…rbac-storage-tests feat(contract): pause circuit breaker, RBAC-gated pause, per-address role storage
…e keys, and modern deploy script
…275-276-277-281 chore: add CONTRIBUTING guide, commitlint/Husky, CI cache keys, and modern Node deploy script
…trancy guard Closes Stellarkard#57 Closes Stellarkard#58 Closes Stellarkard#59 Closes Stellarkard#60 - Fail-safe (Stellarkard#60): new rescue_tokens() recovers tokens sent to the contract by mistake (a direct transfer bypassing pay_usdc/pay_xlm, which forward straight to the treasury). Works for any SAC-compatible token, not just the configured USDC/XLM contracts. - RBAC (Stellarkard#57): rescue_tokens() requires Admin authority — either the stored DataKey::Admin address or the Admin role via grant_role. Also adds transfer_admin(), a two-step admin handover requiring auth from BOTH the current admin and the proposed new admin, so a typo'd address can never silently become admin. - Storage optimization (Stellarkard#58): moves the reentrancy guard from instance to temporary storage. The guard only needs to exist for the span of a single call (set on entry, cleared before return) — it has no reason to count toward the instance storage footprint that every pay_usdc/pay_xlm call already reads and rent-extends. - Documentation (Stellarkard#59): adds module-level //! documentation describing the contract's overall architecture, plus full rustdoc for every new function (Arguments/Returns/Errors/Authorization/Panics sections, matching the existing functions' style). Also fixes a real gap found while testing rescue_tokens: the deploying DataKey::Admin address is never auto-granted the Admin *role* (grant_role/ has_role are a separate system) — a role-only authorization check would have locked a fresh deployment out of its own rescue function until someone remembered to self-grant the role. rescue_tokens now accepts either form of admin authority, documented and tested both ways. Tests: 9 new tests (52 total, up from 43), all pre-existing tests still passing against the new storage layout.
…ct-rescue-admin-transfer-storage feat(contract): token rescue, two-step admin transfer, temporary reentrancy guard
…roles-ttl-tests feat(contract): batch role granting, TTL threshold optimization, doc audit
Add lint-staged pre-commit hook for incremental linting and pre-push hook to run tests before pushing. Include tests validating commitlint config and husky hook presence.
Create composite action for consistent Node.js setup with npm cache across all workflows. Update test.yml to use the shared action.
Add a11y.yml workflow that runs Playwright tests and Storybook accessibility checks on push, PR, and weekly schedule. Include tests validating workflow configuration.
Add CI/CD badges to README, document project structure, and expand getting started section. Update CONTRIBUTING.md with git hooks documentation and CI/CD pipeline overview.
- Stellarkard#267: Add pre-commit hook with lint-staged. Install lint-staged and prettier in SDK devDeps. Pre-commit runs eslint --fix and prettier --write. - Stellarkard#268: Add axe-core a11y audit CI workflow and e2e/a11y-audit.spec.ts. Tests wcag2a/2aa/21a/21aa rules against all dashboard routes. - Stellarkard#269: Add .prettierrc.json and .prettierignore. Install eslint-config-prettier in frontend to disable rules that conflict with Prettier. - Stellarkard#270: Enhance Playwright config with CI-aware timeouts, screenshot/video on failure, HTML+GitHub reporter. Add sharded e2e CI workflow with artifact upload.
…ovements feat: implement tooling, CI caching, a11y audits, and documentation updates
…-e2e-all feat: consolidate tooling, add a11y CI, and improve e2e stability
…g, and dependabot config
docs: review and update READMEs, docker-compose, cross-browser testin…
…d dependabot coverage Closes Stellarkard#259 Closes Stellarkard#260 Closes Stellarkard#262
…0-261-262 chore: consolidate lint/format configs, stabilize e2e pipeline, extend dependabot coverage
- e2e.yml: run Mobile Chrome/Mobile Safari projects in CI (previously configured in playwright.config.ts but never exercised by the matrix), resolving each to its underlying chromium/webkit engine for install and cache-key purposes. Microsoft Edge stays local-only since ubuntu-latest has no system Edge browser. - security.yml: add npm cache to the audit job (was uncached, causing a full npm ci --package-lock-only on every run). - a11y.yml: cache Playwright browser binaries the same way e2e.yml does, instead of reinstalling Chromium on every run. - docker-compose.yml: wire backend service to stellar_card-backend/.env.example via env_file so `docker compose up` gets Stellar/VCC config instead of only the four hardcoded vars. - CICD.md: document the caching strategy across workflows and the E2E CI matrix's engine-resolution behavior. - cross-browser.test.mjs: assert the e2e.yml matrix includes the mobile projects.
…-docs-ci-task-1 ci: extend cross-browser matrix, fix caching gaps, wire compose env (Part 1)
Sentry Setup
Doc payment handler
Error handling
app.js still carried the pre-extraction copy of every handler alongside
the registerRoutes() call that replaced them: /status, /v1/policy/check,
/v1/agent/status and /v1/usage were mounted twice, and a duplicated
`const { registerRoutes } = require('./routes')` made the module a
SyntaxError, so requiring the app failed outright.
Remove the ~470 lines of dead inline handlers and their limiters — every
one already lives in its own module under src/api/ and is mounted by
src/routes/index.js. app.js now owns application middleware, the mount
call, and the terminal error chain, which is what docs/ROUTING.md has
described all along.
Also drop the inline CORS-denial middleware: src/middleware/errorHandler.js
formats that same 403, so the two were competing to answer one error and
disagreed on whether it carried a req_id. The surviving one includes it,
matching every other error response.
errorHandler.js had the same duplicate-declaration problem (`const payload`
twice), which made the whole suite unrunnable. Removed the second one.
Closes Stellarkard#16
… the rest of /v1 Two validation modules had grown in parallel: src/lib/validate.js (body + query + params, path-to-error-code mapping, non-coercing primitives) and src/middleware/validate.js (body only, its own error-code options). They disagreed on whether a 400 carries req_id, and /auth/login used the narrower one while docs/REQUEST_VALIDATION.md documented the other. /auth/login was also unrunnable — a bad merge had left two interleaved copies of its handler body and a reference to an unimported `z`. - Delete src/middleware/validate.js; /auth/login and /auth/verify now use validate() with the error codes their clients already match on. - Add schemas for POST /v1/agent/claim, POST /v1/agent/status and GET /v1/policy/check, the last three routes on the agent surface still validating by hand. - Repoint test/unit/validate.test.js at src/lib/validate.js and cover every primitive, the error-code fallback, first-issue-wins ordering, and the non-transformation guarantee. Behaviour this tightens, all previously reachable: - GET /v1/policy/check accepted "10abc" as 10 and "10.12345" as a valid amount, because the guard was isNaN(parseFloat(x)). It now shares the decimal shape POST /v1/orders enforces, so a preview cannot succeed for an amount the order endpoint would reject. - POST /v1/agent/claim and POST /auth/verify accepted a whitespace-only code. Both handlers .trim() before hashing, so every such request hashed to the same empty-string digest. POST /v1/agent/status keeps the absent-vs-null distinction its partial UPDATE depends on, and its "provide at least one field" rule moves to an object-level refinement mapped through defaultErrorCode. Closes Stellarkard#17
The existing suite pinned schema, constraints and the orders aggregates. The tables whose queries decide whether work actually happens were only covered by a table-exists assertion, and every one of them fails quietly: a retry scan that picks up too few rows drops customer webhooks, and one that picks up too many re-fires deliveries that already succeeded. Adds 30 tests across six suites: - webhook_queue — the retry-scan predicate (undelivered, under the attempt cap, due), inclusive next_attempt, the abandoned-delivery counter /status reports, and an EXPLAIN QUERY PLAN check that the scan still resolves through idx_webhook_queue_next. - credential expiry — the single predicate shared by login codes, agent claim codes and MPP challenges. datetime() yields NULL for an unparseable timestamp and NULL comparisons are NULL, so a malformed expires_at fails closed; rewriting it as a bare lexical comparison would fail open instead. Both halves are pinned. - system_state — cursor advance-in-place, the missing-key case sysStateInt's optional-chained read depends on, and the TEXT-affinity coercion that turns a bound 42 into '42.0'. - stellar_dead_letter — the tx_hash primary key that keeps a ledger replay from inflating the /status counter into a phantom incident. - unmatched_payments — the un-refunded backlog query and its partial index. - policy_decisions — per-key scoping, the composite index plan, and the nullable order_id a blocked-before-creation decision needs. docs/DATABASE_TESTING.md gains a section on the three SQLite behaviours behind these, and drops a stale reference to claim redemption living in app.js. Closes Stellarkard#18
The backend had no machine-readable contract. What documentation existed was a hand-written endpoint list in README.md that had drifted completely — it advertised GET /health, POST /api/v1/orders and POST /api/v1/auth/otp, none of which this server has ever routed. That is the failure mode worth designing against. Documentation being absent is obvious to a reader; documentation being present and wrong is not, and a client trusts it anyway. - GET /api/openapi.json — OpenAPI 3.0.3 for the public and agent-facing surface. - GET /api/docs — Swagger UI over it. Both unauthenticated (an integrator has to read the API before they have a key) and rate limited to 60/min per IP like the other public metadata routes. The document is built by src/api/openapi.js rather than checked in as YAML, so the values that can drift are imported from the modules that enforce them: ORDER_STATUSES, the amount pattern, the min/max order bounds, the metadata byte budget and the webhook URL cap all come from api/orders.js, and info.version from the same frozen payload GET /api/version returns. Changing a bound changes the published schema in the same commit, or it does not change at all. What that cannot catch is covered behaviourally in test/integration/openapi.test.js: every documented path must reach a real handler, every operation marked `security: []` must be reachable without a credential and every one that is not must return 401, and every route the app actually mounts must be either documented or listed in UNDOCUMENTED_PREFIXES with a reason. That last check walks Express's real layer stack, so a new public endpoint cannot ship undocumented. The operator surface, the HMAC callback and the feature-flagged MPP routes are deliberately excluded — no third-party clients, and publishing them to anonymous readers only helps someone map the deployment. Swagger UI needs inline script and style, which the app-wide helmet policy blocks. CSP is re-applied for the /api/docs subtree only, with no external host permitted, and the test asserts both that the docs page gets the relaxation and that /api/version does not. Adds one dependency, swagger-ui-express. It bundles its own assets, so the page has no CDN dependency and works offline; npm audit reports the same 17 pre-existing advisories before and after. Also adds the regression tests that keep Stellarkard#16 from recurring: app.js declares no route handlers, and no path is mounted twice. Closes Stellarkard#15
…sks-15-18 Feature/backend tasks 15 18
- Verified comprehensive documentation in PAYMENT_HANDLER.md - Complete flow coverage including all phases and helper functions - Security properties and audit findings (F0-F3) documented - Operator runbooks and integration points included - Test coverage documentation verified
docs: document payment-handler.js flow
…-task-4 fix(backend): standardize error middleware logging
Resolve conflicts across six files: - src/app.js: keep this branch's route stack and OpenAPI annotations, append main's 404 catch-all and Sentry error chain before errorHandler. Restore the rateLimit/ipKeyGenerator imports, the router requires, and the adminLimiter definition that main's slimmed header dropped. - src/api/auth.js: take main's validateLogin/validateVerify handler signatures (they supersede the inline body-shape guards) and keep the @openapi doc blocks from this branch. - src/api/orders.js: same resolution for validateCreateOrder and validateListOrders. - package.json: keep swagger-jsdoc alongside main's swagger-ui-express. - package-lock.json: regenerated from main's lock plus swagger-jsdoc. - README.md: keep main's endpoint table; the block on this branch listed routes (/api/v1/orders, /api/v1/auth/otp, /api/v1/webhooks/vcc) that do not exist in the codebase.
…ing-a11y-278-279 feat(tooling,a11y): partial implementation for ESLint consolidation and CI a11y audit (Stellarkard#278, Stellarkard#279)
[backend] Add Swagger/OpenAPI documentation
✅ Deploy Preview for stellarcard ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
@Menjay7 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! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR completes the third phase of the unified local development environment by expanding the Docker Compose configuration. It streamlines project setup, ensures consistent development environments, and improves onboarding by orchestrating all required services through a single command.
Scope
Extended the Docker Compose configuration to support additional application services.
Improved service orchestration, networking, and dependency management.
Enhanced environment configuration for local development.
Optimized developer experience with faster startup and simplified workflows.
Changes
Added and configured missing services required for local development.
Improved service dependency ordering using health checks and startup conditions.
Added persistent Docker volumes for databases and other stateful services.
Configured shared Docker networks for secure inter-service communication.
Introduced environment variable templates and sensible defaults.
Added optional development profiles for running subsets of services.
Improved container naming and logging configuration.
Updated documentation with setup, startup, and troubleshooting instructions.
Benefits
Provides a consistent development environment across all machines.
Reduces onboarding time for new contributors.
Eliminates manual setup of supporting infrastructure.
Improves service reliability during local development.
Simplifies running the entire application stack with a single command.
Creates a stronger foundation for future development and testing workflows.
Testing
Verified all services start successfully using Docker Compose.
Confirmed service discovery and network connectivity between containers.
Validated persistent volumes retain data across container restarts.
Tested environment variable loading and configuration overrides.
Confirmed application functionality with the complete local stack running.
Breaking Changes
None. This PR enhances the local development environment without affecting existing production deployments or application behavior.
Closed #264