Skip to content

Commit e3d3dd5

Browse files
authored
Merge branch 'main' into feat/issue-152-matching-engine
2 parents 461f4d7 + 15b70b7 commit e3d3dd5

104 files changed

Lines changed: 9285 additions & 653 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/backend.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ on:
55
branches: [main, develop]
66
paths: [backend/**]
77
pull_request:
8-
branches: [main]
98
paths: [backend/**]
109
workflow_dispatch:
1110

.github/workflows/ci.yml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ on:
44
push:
55
branches: [main, develop]
66
pull_request:
7-
branches: [main]
87

98
jobs:
109
frontend:
@@ -99,6 +98,24 @@ jobs:
9998
- name: Secret scanning
10099
run: gitleaks detect --config .gitleaks.toml --source . --no-git --exit-code 1
101100

101+
openapi-lint:
102+
name: OpenAPI Spec Validation (Spectral)
103+
runs-on: ubuntu-latest
104+
steps:
105+
- uses: actions/checkout@v4
106+
- uses: actions/setup-node@v4
107+
with:
108+
node-version: "20"
109+
110+
- name: Validate OpenAPI spec with Spectral (built-in OAS rules)
111+
run: npx @stoplight/spectral-cli@6.14.3 lint docs/api/openapi.yaml --ruleset .spectral.yaml
112+
113+
- name: Install dependencies for custom validation
114+
run: npm ci
115+
116+
- name: Validate project-specific conventions (429, descriptions, summaries)
117+
run: node scripts/validate-openapi.js
118+
102119
zap_scan:
103120
name: DAST Security Scan (OWASP ZAP)
104121
runs-on: ubuntu-latest

.github/workflows/contracts.yml

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@ on:
55
branches: [main, develop]
66
paths: [contracts/**]
77
pull_request:
8-
branches: [main]
98
paths: [contracts/**]
109
workflow_dispatch:
1110
schedule:
12-
# Nightly deep fuzz run 1 000 000 iterations every day at 03:00 UTC
11+
# Nightly deep fuzz run -- 1 000 000 iterations every day at 03:00 UTC
1312
- cron: "0 3 * * *"
1413

1514
jobs:
@@ -40,15 +39,16 @@ jobs:
4039
- name: Run Clippy
4140
run: cargo clippy --workspace -- -D warnings
4241

43-
- name: Run tests (skip duplicate fuzz run handled by dedicated fuzz job)
44-
run: cargo test --workspace -- --skip fuzz::
42+
- name: Run tests (skip duplicate fuzz run -- handled by dedicated fuzz job)
43+
run: "cargo test --features testutils --workspace -- --skip fuzz::"
4544

4645
- name: Build WASM
4746
run: cargo build --workspace --target wasm32v1-none --release
4847

4948
fuzz:
50-
name: Fuzz Tests (100k iterations)
49+
name: Fuzz Tests (10k iterations)
5150
runs-on: ubuntu-latest
51+
timeout-minutes: 20
5252
defaults:
5353
run:
5454
working-directory: contracts
@@ -67,15 +67,16 @@ jobs:
6767
with:
6868
workspaces: contracts
6969

70-
- name: Run fuzz tests (100k iterations)
71-
run: FUZZ_ITERATIONS=100000 cargo test --features testutils -- fuzz
70+
- name: Run fuzz tests (10k iterations)
71+
run: cargo test --features testutils -- fuzz
7272
env:
73-
FUZZ_ITERATIONS: 100000
73+
FUZZ_ITERATIONS: 10000
7474

7575
deep-fuzz:
76-
name: Deep Fuzz (1M iterations nightly)
76+
name: Deep Fuzz (1M iterations -- nightly)
7777
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
7878
runs-on: ubuntu-latest
79+
timeout-minutes: 120
7980
defaults:
8081
run:
8182
working-directory: contracts
@@ -95,7 +96,7 @@ jobs:
9596
workspaces: contracts
9697

9798
- name: Run deep fuzz tests (1M iterations)
98-
run: FUZZ_ITERATIONS=1000000 cargo test --features testutils -- fuzz
99+
run: cargo test --features testutils -- fuzz
99100
env:
100101
FUZZ_ITERATIONS: 1000000
101102

.github/workflows/extension.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ on:
1010
pull_request:
1111
paths:
1212
- "extension/**"
13-
branches: [main]
1413

1514
jobs:
1615
build:

.github/workflows/frontend.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ on:
44
push:
55
branches: [main, develop]
66
pull_request:
7-
branches: [main]
87

98
jobs:
109
frontend-build:

.github/workflows/image-scan.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ on:
1111
push:
1212
branches: [main]
1313
pull_request:
14-
branches: [main]
1514
workflow_dispatch:
1615

1716
jobs:

.github/workflows/sbom.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ on:
1111
push:
1212
branches: [main]
1313
pull_request:
14-
branches: [main]
1514
workflow_dispatch:
1615

1716
jobs:

.github/workflows/secret-scanning.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ on:
44
push:
55
branches: [main, develop]
66
pull_request:
7-
branches: [main]
87
workflow_dispatch:
98

109
permissions:

.spectral.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Spectral API linting ruleset for Stellar-IndigoPay
2+
#
3+
# Extends the built-in `spectral:oas` ruleset which validates OpenAPI 3.x
4+
# structure (media examples, schema types, server URLs, path parameters,
5+
# trailing slashes, operation tags, typed enums, etc.).
6+
#
7+
# Custom-project-specific validations (e.g., 429 on mutation endpoints,
8+
# inline response descriptions) are handled by a separate Node.js script
9+
# in scripts/validate-openapi.js — Spectral's built-in functions cannot
10+
# assert on specific response status code keys, and Spectral 6.x YAML
11+
# rulesets do not support custom JavaScript functions out-of-the-box.
12+
#
13+
extends: "spectral:oas"
14+
15+
rules:
16+
# ── Severity overrides for intentional omissions ────────────────
17+
# operationId is recommended but not required — simple or internal
18+
# endpoints may omit it without reducing documentation quality.
19+
operation-operationId: warn
20+
21+
# operation-description is recommended — if the summary is
22+
# sufficiently descriptive, a separate description may be omitted.
23+
operation-description: warn
24+
25+
# Unused components are a minor housekeeping concern, not a spec
26+
# validity issue. Downgraded to info to avoid CI noise.
27+
oas3-unused-component: info

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

33
### Features
44

5+
* **backend,frontend:** add Idempotency-Key support for donation recording (closes #148)
6+
- Accept `Idempotency-Key` header (UUID v4) on `POST /api/donations`; store response and replay within 24 hours
7+
- New `idempotency_keys` table via migration 016 with index on `created_at`
8+
- Hourly pg-boss cleanup cron (`idempotencyCleanup`) purges expired keys (configurable via `IDEMPOTENCY_CLEANUP_CRON`)
9+
- Frontend: `DonateForm` and `bridge` generate `crypto.randomUUID()` per donation attempt
10+
- Documented in OpenAPI spec with 200 replay response
11+
- 11 new tests: 5 unit (donations), 8 unit (cleanup), 3 integration (testcontainers)
12+
513
* **docs:** add CONTRIBUTORS.md to credit community work (GF-015, closes #64)
614

715
* **backend:** implement Soroban RPC retry with exponential backoff and circuit breaker (GF-043, closes #100)

0 commit comments

Comments
 (0)