diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..a4ca4107 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,80 @@ +version: 2 + +updates: + # Rust dependencies (Soroban contracts) + - package-ecosystem: "cargo" + directory: "/smart-contract" + schedule: + interval: "weekly" + day: "monday" + time: "09:00" + + open-pull-requests-limit: 10 + + reviewers: + - "Lynndabel" + + assignees: + - "Lynndabel" + + commit-message: + prefix: "deps" + include: "scope" + + versioning-strategy: increase + + labels: + - "dependencies" + - "rust" + + groups: + rust-dependencies: + patterns: + - "*" + + # Frontend dependencies (Next.js / TypeScript) + - package-ecosystem: "npm" + directory: "/frontend" + schedule: + interval: "weekly" + day: "monday" + time: "09:00" + + open-pull-requests-limit: 10 + + reviewers: + - "Lynndabel" + + assignees: + - "Lynndabel" + + commit-message: + prefix: "deps" + include: "scope" + + versioning-strategy: increase + + labels: + - "dependencies" + - "javascript" + + groups: + frontend-dependencies: + patterns: + - "*" + + ignore: + # Ignore risky React major updates + - dependency-name: "react" + update-types: + - "version-update:semver-major" + + - dependency-name: "react-dom" + update-types: + - "version-update:semver-major" + + # Ignore Soroban SDK updates requiring manual testing + - dependency-name: "@stellar/*" + update-types: + - "version-update:semver-major" + - "version-update:semver-minor" diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..181dda36 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,109 @@ +## Description + + +## Type of Change + +- [ ] ๐Ÿ› Bug fix (non-breaking change that fixes an issue) +- [ ] โœจ New feature (non-breaking change that adds functionality) +- [ ] ๐Ÿ’ฅ Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] ๐Ÿ”ง Code refactor (no functional changes) +- [ ] ๐Ÿ“š Documentation update +- [ ] ๐Ÿงช Tests (adding or updating tests) +- [ ] ๐Ÿ”’ Security (security-related changes) +- [ ] ๐Ÿš€ Performance (performance-related changes) +- [ ] ๐ŸŽจ UI/UX (user interface changes) +- [ ] ๐Ÿ› ๏ธ DevOps (deployment, CI/CD, infrastructure changes) + +## Changes Made + + +### Code Changes + + +### Documentation Updates + + +### Database/Schema Changes + + +## Testing + + +### Manual Testing + + +### Automated Tests + + +- [ ] Unit tests pass +- [ ] Integration tests pass +- [ ] E2E tests pass (if applicable) +- [ ] Performance tests pass (if applicable) + +### Test Coverage + + +## Screenshots/Videos (UI Changes) + + + +| Before | After | +|--------|-------| +| | | + +## Breaking Changes + + + +## Checklist + + +### Code Quality +- [ ] Code follows project style guidelines +- [ ] Code is self-documenting or properly commented +- [ ] No console.log statements or debugger breakpoints left +- [ ] No unused imports or variables +- [ ] Code passes linting checks + +### Testing +- [ ] Unit tests added/updated for new functionality +- [ ] Integration tests added/updated if needed +- [ ] Manual testing completed +- [ ] Edge cases considered and tested +- [ ] Tests pass locally + +### Documentation +- [ ] README updated if needed +- [ ] API documentation updated if needed +- [ ] Inline code documentation added/updated +- [ ] Comments added for complex logic + +### Security +- [ ] Security implications reviewed +- [ ] No sensitive data exposed +- [ ] Input validation added where needed +- [ ] Authentication/authorization considered + +### Performance +- [ ] Performance impact assessed +- [ ] No performance regressions introduced +- [ ] Bundle size checked (frontend) +- [ ] Database queries optimized (backend) + +### Deployment +- [ ] Environment variables documented +- [ ] Database migrations included +- [ ] Backward compatibility maintained +- [ ] Rollback plan considered + +### Legal/Compliance +- [ ] DCO (Developer Certificate of Origin) signed +- [ ] License headers added to new files +- [ ] Third-party dependencies reviewed +- [ ] GDPR/privacy implications considered + +## Related Issues + + +## Additional Context + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..4081a7d8 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,225 @@ +name: CI +on: + push: + branches: [ main, develop ] + pull_request: + branches: [ main, develop ] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + rust-tests: + name: Rust Tests & Quality + runs-on: ubuntu-latest + env: + STELLAR_CLI_VERSION: 23.4.0 + defaults: + run: + working-directory: ./smart-contract + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + with: + targets: wasm32-unknown-unknown, wasm32v1-none + + - name: Ensure wasm32v1-none target is available + run: rustup target add wasm32v1-none + + # Use the official Stellar CLI GitHub Action (v23.4.0) + # Replaces the old manual soroban-cli curl install + - name: Install Stellar CLI + shell: bash + run: | + set -euo pipefail + + mkdir -p "$HOME/.local/bin" + + arch="$(uname -m)" + case "$arch" in + x86_64) asset_arch="x86_64" ;; + aarch64|arm64) asset_arch="aarch64" ;; + *) echo "Unsupported architecture: $arch"; exit 1 ;; + esac + + version="${STELLAR_CLI_VERSION}" + base_url="https://github.com/stellar/stellar-cli/releases/download/v${version}" + + urls=( + "${base_url}/stellar-cli-${version}-${asset_arch}-unknown-linux-gnu.tar.gz" + "${base_url}/stellar-cli-${version}-${asset_arch}-unknown-linux-musl.tar.gz" + ) + + success="false" + for url in "${urls[@]}"; do + echo "Attempting download: ${url}" + if curl -fL --retry 6 --retry-all-errors --retry-delay 5 -o stellar-cli.tar.gz "${url}"; then + success="true" + break + fi + done + + if [ "$success" != "true" ]; then + echo "Failed to download stellar-cli v${version} from GitHub releases." + exit 1 + fi + + tmpdir="$(mktemp -d)" + tar -xzf stellar-cli.tar.gz -C "$tmpdir" + stellar_path="$(find "$tmpdir" -type f -name stellar | head -n 1)" + if [ -z "$stellar_path" ]; then + echo "Could not find 'stellar' binary in downloaded archive." + exit 1 + fi + mv "$stellar_path" "$HOME/.local/bin/stellar" + chmod +x "$HOME/.local/bin/stellar" + + echo "$HOME/.local/bin" >> "$GITHUB_PATH" + stellar --version + + - name: Cache Cargo registry + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo-registry- + + - name: Cache Cargo build + uses: actions/cache@v4 + with: + # Fixed: scoped to actual target dir relative to repo root, + # not the working-directory (which would resolve incorrectly) + path: smart-contract/target + key: ${{ runner.os }}-cargo-build-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo-build- + + - name: Check formatting + run: cargo fmt --all -- --check + + - name: Run clippy + run: cargo clippy --all-targets --all-features -- -D warnings + + - name: Run tests + run: cargo test --release --all-features + + # Use stellar contract build instead of raw cargo build --target wasm32 + # This ensures proper metadata, optimizer flags, and correct wasm output paths + - name: Build WASM contracts + run: stellar contract build + + - name: Upload WASM artifacts + uses: actions/upload-artifact@v4 + with: + name: wasm-artifacts + path: smart-contract/target/wasm32-unknown-unknown/release/*.wasm + retention-days: 7 + + frontend-tests: + name: Frontend Tests & Quality + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./frontend + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: frontend/package-lock.json + + - name: Install dependencies + run: | + npm ci + npm install @rollup/rollup-linux-x64-gnu --save-optional + npm install lightningcss-linux-x64-gnu --save-optional + + - name: Run npm audit + run: npm audit --audit-level=moderate + + # Fixed: was running `npm run build` here (type check) AND again below (build verification) + # Use tsc --noEmit for type checking, keep the real build separate + - name: Type checking + run: npx tsc --noEmit + + - name: Lint code + run: npm run lint --if-present + + - name: Run tests + run: npm test --if-present + + - name: Build + run: npm run build + + - name: Upload frontend artifacts + uses: actions/upload-artifact@v4 + with: + name: frontend-artifacts + # Fixed: artifacts are uploaded from the job that produces them, + # not from a downstream job that can't access other jobs' filesystems + path: frontend/.next/ + retention-days: 7 + + frontend-e2e: + name: Frontend E2E (Playwright) + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./frontend + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: frontend/package-lock.json + + - name: Install dependencies + run: | + npm ci + npm install @rollup/rollup-linux-x64-gnu --save-optional + npm install lightningcss-linux-x64-gnu --save-optional + + - name: Install Playwright browsers + run: npx playwright install --with-deps + + - name: Run Playwright tests + run: npm run e2e + + - name: Upload Playwright report + if: always() + uses: actions/upload-artifact@v4 + with: + name: playwright-report + path: frontend/playwright-report/ + retention-days: 7 + + - name: Upload Playwright test results + if: failure() + uses: actions/upload-artifact@v4 + with: + name: playwright-test-results + path: frontend/test-results/ + retention-days: 7 + + build-verification: + name: Build Verification + runs-on: ubuntu-latest + needs: [ rust-tests, frontend-tests, frontend-e2e ] + steps: + - name: All builds passed + run: echo "All upstream jobs completed successfully" diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 00000000..335cd412 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,250 @@ +name: Deploy + +on: + push: + branches: [ main ] + workflow_dispatch: + inputs: + environment: + description: 'Deployment environment' + required: true + default: 'staging' + type: choice + options: + - staging + - production + +# Prevent concurrent deploys to the same environment +concurrency: + group: deploy-${{ github.event.inputs.environment || 'staging' }} + cancel-in-progress: false + +jobs: + deploy-contracts: + name: Deploy Smart Contracts + runs-on: ubuntu-latest + environment: ${{ github.event.inputs.environment || 'staging' }} + env: + STELLAR_CLI_VERSION: 23.4.0 + outputs: + # Expose contract IDs to downstream jobs if needed + deployed: ${{ steps.deploy.outputs.deployed }} + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + with: + targets: wasm32-unknown-unknown + + # Fixed: use the official Stellar CLI GitHub Action (replaces broken soroban curl install) + - name: Install Stellar CLI + shell: bash + run: | + set -euo pipefail + + mkdir -p "$HOME/.local/bin" + + arch="$(uname -m)" + case "$arch" in + x86_64) asset_arch="x86_64" ;; + aarch64|arm64) asset_arch="aarch64" ;; + *) echo "Unsupported architecture: $arch"; exit 1 ;; + esac + + version="${STELLAR_CLI_VERSION}" + base_url="https://github.com/stellar/stellar-cli/releases/download/v${version}" + + urls=( + "${base_url}/stellar-cli-${version}-${asset_arch}-unknown-linux-gnu.tar.gz" + "${base_url}/stellar-cli-${version}-${asset_arch}-unknown-linux-musl.tar.gz" + ) + + success="false" + for url in "${urls[@]}"; do + echo "Attempting download: ${url}" + if curl -fL --retry 6 --retry-all-errors --retry-delay 5 -o stellar-cli.tar.gz "${url}"; then + success="true" + break + fi + done + + if [ "$success" != "true" ]; then + echo "Failed to download stellar-cli v${version} from GitHub releases." + exit 1 + fi + + tmpdir="$(mktemp -d)" + tar -xzf stellar-cli.tar.gz -C "$tmpdir" + stellar_path="$(find "$tmpdir" -type f -name stellar | head -n 1)" + if [ -z "$stellar_path" ]; then + echo "Could not find 'stellar' binary in downloaded archive." + exit 1 + fi + mv "$stellar_path" "$HOME/.local/bin/stellar" + chmod +x "$HOME/.local/bin/stellar" + + echo "$HOME/.local/bin" >> "$GITHUB_PATH" + stellar --version + + # Fixed: register the deployer key into the CLI key store. + # --secret-key flag was removed from deploy/invoke commands in modern stellar CLI. + # The correct approach is to add the key once via `stellar keys add` and then + # reference it by name with --source-account in subsequent commands. + - name: Register deployer identity + env: + STELLAR_SECRET_KEY: ${{ secrets.STELLAR_SECRET_KEY }} + run: | + echo "$STELLAR_SECRET_KEY" | stellar keys add deployer --secret-key + + # Fixed: use stellar contract build instead of cargo build --target wasm32-unknown-unknown. + # This ensures correct metadata, optimizer flags, and proper wasm output paths. + - name: Build contracts + working-directory: ./smart-contract + run: stellar contract build + + - name: Configure network + run: | + NETWORK=${{ github.event.inputs.environment || 'staging' }} + if [ "$NETWORK" = "production" ]; then + echo "STELLAR_NETWORK=mainnet" >> $GITHUB_ENV + echo "STELLAR_RPC_URL=https://soroban-rpc.mainnet.stellar.org" >> $GITHUB_ENV + echo "STELLAR_NETWORK_PASSPHRASE=Public Global Stellar Network ; September 2015" >> $GITHUB_ENV + else + echo "STELLAR_NETWORK=testnet" >> $GITHUB_ENV + echo "STELLAR_RPC_URL=https://soroban-testnet.stellar.org" >> $GITHUB_ENV + echo "STELLAR_NETWORK_PASSPHRASE=Test SDF Network ; September 2015" >> $GITHUB_ENV + fi + + # Fixed: replaced --secret-key (removed flag) with --source-account referencing the + # registered identity. Also uses --alias per current CLI docs so contracts can be + # referenced by name in subsequent steps instead of tracking raw IDs in a text file. + - name: Deploy contracts + id: deploy + run: | + for wasm_file in smart-contract/target/wasm32-unknown-unknown/release/*.wasm; do + CONTRACT_NAME=$(basename "$wasm_file" .wasm) + echo "Deploying $CONTRACT_NAME..." + stellar contract deploy \ + --wasm "$wasm_file" \ + --source-account deployer \ + --network "$STELLAR_NETWORK" \ + --rpc-url "$STELLAR_RPC_URL" \ + --network-passphrase "$STELLAR_NETWORK_PASSPHRASE" \ + --alias "$CONTRACT_NAME" \ + --ignore-checks + echo "Deployed $CONTRACT_NAME" + done + echo "deployed=true" >> $GITHUB_OUTPUT + + - name: Initialize contracts + run: | + # Add per-contract initialization calls here, e.g.: + # stellar contract invoke \ + # --id \ + # --source-account deployer \ + # --network "$STELLAR_NETWORK" \ + # -- initialize --admin deployer + echo "Add initialization logic here" + + - name: Health check + run: | + # Add contract health check invocations here, e.g.: + # stellar contract invoke --id --network "$STELLAR_NETWORK" -- get_status + echo "Add health check logic here" + + deploy-frontend: + name: Deploy Frontend + runs-on: ubuntu-latest + environment: ${{ github.event.inputs.environment || 'staging' }} + needs: deploy-contracts + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: frontend/package-lock.json + + - name: Install dependencies + working-directory: ./frontend + run: npm ci + + - name: Write environment config + working-directory: ./frontend + run: | + NETWORK=${{ github.event.inputs.environment || 'staging' }} + if [ "$NETWORK" = "production" ]; then + echo "NEXT_PUBLIC_CONTRACT_ID=${{ secrets.PRODUCTION_CONTRACT_ID }}" >> .env.local + echo "NEXT_PUBLIC_STELLAR_NETWORK=mainnet" >> .env.local + echo "NEXT_PUBLIC_RPC_URL=https://soroban-rpc.mainnet.stellar.org" >> .env.local + else + echo "NEXT_PUBLIC_CONTRACT_ID=${{ secrets.STAGING_CONTRACT_ID }}" >> .env.local + echo "NEXT_PUBLIC_STELLAR_NETWORK=testnet" >> .env.local + echo "NEXT_PUBLIC_RPC_URL=https://soroban-testnet.stellar.org" >> .env.local + fi + + - name: Build frontend + working-directory: ./frontend + run: npm run build + + # Fixed: `if: env.VERCEL_TOKEN != ''` silently never evaluates true in GitHub Actions + # because env context is not available in `if:` conditions. + # Use vars (non-secret config) to gate the Vercel deploy instead. + - name: Deploy to Vercel + if: vars.USE_VERCEL == 'true' + working-directory: ./frontend + run: | + npm install -g vercel + vercel --prod --yes --token ${{ secrets.VERCEL_TOKEN }} + + # Fixed: upgraded from stale peaceiris/actions-gh-pages@v3 to @v4 + - name: Deploy to GitHub Pages (fallback) + if: vars.USE_VERCEL != 'true' + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./frontend/.next + cname: ${{ (github.event.inputs.environment == 'production') && 'chainlogistics.app' || 'staging.chainlogistics.app' }} + + notify: + name: Notify Deployment Status + runs-on: ubuntu-latest + needs: [ deploy-contracts, deploy-frontend ] + if: always() + + steps: + - name: Notify success + if: needs.deploy-contracts.result == 'success' && needs.deploy-frontend.result == 'success' + run: | + echo "Deployment successful!" + # Add Slack/email notification here + + - name: Notify failure + if: needs.deploy-contracts.result == 'failure' || needs.deploy-frontend.result == 'failure' + run: | + echo "Deployment failed!" + # Add Slack/email notification here + + # NOTE: True contract rollback on Stellar/Soroban is not possible by reverting a deploy โ€” + # deployed contracts are immutable on-chain. A real rollback strategy requires either: + # 1. Redeploying the previous WASM and updating any router/proxy contract to point to it, or + # 2. Maintaining a feature-flag or upgrade mechanism inside the contract itself. + # The stub below is preserved as a placeholder for frontend-only rollback (e.g. Vercel promote). + rollback: + name: Rollback Frontend on Failure + runs-on: ubuntu-latest + needs: [ deploy-contracts, deploy-frontend ] + if: failure() && github.event_name == 'push' && vars.USE_VERCEL == 'true' + + steps: + - name: Rollback Vercel deployment + run: | + echo "Promote the previous Vercel deployment via the Vercel API or CLI here." + # vercel rollback --token ${{ secrets.VERCEL_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..9291d2ca --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,152 @@ +name: Release + +on: + push: + tags: + - "v*.*.*" + +jobs: + release: + name: Create Release + runs-on: ubuntu-latest + + steps: + # Checkout repository + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + # Setup Node + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + + # Install Rust + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + + # Add WASM target + - name: Add wasm target + run: rustup target add wasm32-unknown-unknown + + # Install Soroban CLI + - name: Install Soroban CLI + run: cargo install soroban-cli --locked + + # Extract version from tag + - name: Get version from tag + id: get_version + run: echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT + + # Generate changelog + - name: Generate changelog + id: changelog + run: | + PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD~1 2>/dev/null || echo "") + if [ -z "$PREVIOUS_TAG" ]; then + PREVIOUS_TAG=$(git rev-list --max-parents=0 HEAD) + fi + + echo "## What's Changed" > changelog.md + echo "" >> changelog.md + git log --pretty=format:"* %s (%h)" --no-merges ${PREVIOUS_TAG}..HEAD >> changelog.md + echo "" >> changelog.md + echo "**Full Changelog**: https://github.com/${{ github.repository }}/compare/${PREVIOUS_TAG}...${{ github.ref }}" >> changelog.md + + { + echo 'changelog<> $GITHUB_OUTPUT + + # Build Soroban contracts + - name: Build Rust contracts + working-directory: ./smart-contract + run: cargo build --release --target wasm32-unknown-unknown + + # Install frontend dependencies + - name: Install frontend dependencies + working-directory: ./frontend + run: npm ci + + # Build frontend + - name: Build frontend + working-directory: ./frontend + run: npm run build + + # Package frontend build + - name: Package frontend build + run: | + tar -czf frontend-build.tar.gz -C frontend .next + + # Prepare release artifacts + - name: Prepare release artifacts + run: | + mkdir release-artifacts + cp smart-contract/target/wasm32-unknown-unknown/release/*.wasm release-artifacts/ + cp frontend-build.tar.gz release-artifacts/ + + # Zip artifacts + - name: Zip release artifacts + run: | + cd release-artifacts + zip -r ../chainlogistics-${{ steps.get_version.outputs.version }}.zip . + + # Create GitHub Release + - name: Create GitHub Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: Release ${{ steps.get_version.outputs.version }} + body: ${{ steps.changelog.outputs.changelog }} + draft: false + prerelease: false + + # Upload release asset + - name: Upload release assets + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./chainlogistics-${{ steps.get_version.outputs.version }}.zip + asset_name: chainlogistics-${{ steps.get_version.outputs.version }}.zip + asset_content_type: application/zip + + + publish-frontend: + name: Publish Frontend + runs-on: ubuntu-latest + needs: release + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "npm" + cache-dependency-path: frontend/package-lock.json + + - name: Install dependencies + working-directory: ./frontend + run: npm ci + + - name: Build frontend + working-directory: ./frontend + run: npm run build + + # Deploy to Vercel + - name: Deploy to Vercel + if: secrets.VERCEL_TOKEN != '' + run: | + npm install -g vercel + cd frontend + vercel --prod --yes --token ${{ secrets.VERCEL_TOKEN }} diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml new file mode 100644 index 00000000..ab0eb099 --- /dev/null +++ b/.github/workflows/security.yml @@ -0,0 +1,104 @@ +name: Security Scan + +on: + schedule: + # Run weekly on Mondays at 9 AM UTC + - cron: '0 9 * * 1' + workflow_dispatch: + push: + branches: [ main ] + +jobs: + # Replaces the separate rust-security and npm-security jobs. + # + # WHY: cargo audit is effectively unmaintained (primary maintainer stepped back March 2025). + # Its --format json --output flags don't exist (correct flag is --json to stdout), and its + # JSON schema doesn't have a flat "severity": "critical" field, so the grep checks were + # silently never matching anything. OSV-Scanner covers Cargo, npm, and 11+ other ecosystems, + # outputs SARIF to GitHub's Security tab natively, and is actively maintained by Google. + osv-scan: + name: OSV Dependency Scan + uses: google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@v2.3.3 + permissions: + actions: read + contents: read + security-events: write + with: + # Recursively scans the repo, picking up both Cargo.lock and frontend/package-lock.json + scan-args: |- + --recursive + ./ + + codeql-analysis: + name: CodeQL Analysis + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + strategy: + fail-fast: false + matrix: + # Fixed: 'rust' is not a supported CodeQL language. + # CodeQL does not support Rust โ€” remove it to prevent the job from failing silently + # or erroring. If you want static analysis for Rust, use cargo clippy (in CI) or + # a dedicated tool like semgrep with Rust rules. + language: [ 'javascript-typescript' ] + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + queries: security-and-quality + + - name: Autobuild + uses: github/codeql-action/autobuild@v3 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{ matrix.language }}" + + license-check: + name: License Compliance + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: frontend/package-lock.json + + - name: Install frontend dependencies + working-directory: ./frontend + run: npm ci + + - name: Install license-checker + run: npm install -g license-checker + + - name: Check frontend licenses + working-directory: ./frontend + run: | + license-checker --json --out licenses.json + # Warn on any GPL variant (GPL-2.0, GPL-3.0, LGPL, AGPL, etc.) + if grep -qE '"licenses":\s*"(A|L)?GPL' licenses.json; then + echo "โš  GPL-family licensed dependencies found โ€” review for compatibility:" + grep -E '"licenses":\s*"(A|L)?GPL' licenses.json + # This is a warning, not a hard failure โ€” adjust to 'exit 1' if you want to enforce + else + echo "โœ“ No GPL-family licenses found." + fi + + - name: Upload license report + uses: actions/upload-artifact@v4 + with: + name: license-report + path: frontend/licenses.json + retention-days: 30 diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..7c8d4bdc --- /dev/null +++ b/.gitignore @@ -0,0 +1,57 @@ +# Rust build artifacts +target/ +**/target/ +backend/target/ +sdk/rust/target/ +smart-contract/target/ +smart-contract/contracts/target/ +**/*.rs.bk +*.pdb + +# Node.js +node_modules/ +frontend/node_modules/ +frontend/.next/ +frontend/out/ +frontend/.cache/ + +# Environment files +.env +.env.local +.env.*.local +backend/.env +frontend/.env.local + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS +.DS_Store +Thumbs.db + +# Logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Test coverage +coverage/ +*.lcov + +# Temporary files +smart-contract/contracts/src/simple_test.rs +smart-contract/contracts/test_snapshots/ +issue.md +checks.md +task.md +GITHUB_ISSUES.md +pr.md + +# Frontend Testing +playwright-report/ +test-results/ \ No newline at end of file diff --git a/CODE_REVIEW.md b/CODE_REVIEW.md new file mode 100644 index 00000000..7bcdadcd --- /dev/null +++ b/CODE_REVIEW.md @@ -0,0 +1,594 @@ +# Code Review Process + +This document establishes the formal code review process for ChainLogistics. Code reviews are essential for maintaining code quality, sharing knowledge, and ensuring the stability of the codebase. + +## Table of Contents + +- [Overview](#overview) +- [Review Workflow](#review-workflow) +- [Review Roles](#review-roles) +- [Review Requirements](#review-requirements) +- [Code Review Checklists](#code-review-checklists) +- [Review Standards](#review-standards) +- [Review Guidelines](#review-guidelines) +- [Review Metrics](#review-metrics) + +--- + +## Overview + +### Purpose + +Code reviews serve multiple purposes: +- **Quality Assurance**: Catch bugs, security issues, and performance problems before production +- **Knowledge Sharing**: Help team members understand different parts of the codebase +- **Consistency**: Ensure code follows project standards and best practices +- **Maintainability**: Improve long-term maintainability of the codebase +- **Onboarding**: Help new contributors understand the codebase + +### Scope + +All code changes must go through review, including: +- New features +- Bug fixes +- Refactoring +- Documentation changes +- Configuration changes +- Test updates + +### Review Categories + +1. **Feature Review** - New functionality +2. **Bug Fix Review** - Bug corrections +3. **Security Review** - Security-related changes +4. **Performance Review** - Performance optimizations +5. **Refactoring Review** - Code restructuring +6. **Documentation Review** - Documentation updates + +--- + +## Review Workflow + +### 1. Self-Review (Before Submitting) + +Before requesting a code review, the author must: + +- [ ] Complete all acceptance criteria +- [ ] Run all tests locally +- [ ] Check for compiler/linter warnings +- [ ] Review own changes for obvious issues +- [ ] Update relevant documentation +- [ ] Add/update tests if applicable +- [ ] Ensure commit messages follow conventions +- [ ] Verify the PR description is complete + +### 2. Submit Pull Request + +- Create a descriptive PR title +- Fill out the PR template completely +- Link to related issues +- Add appropriate labels +- Assign reviewers based on the area of change +- Request review from at least one team member + +### 3. Initial Review + +The reviewer should: +- Read the PR description to understand context +- Review the changes in a logical order +- Start with high-level design, then implementation details +- Focus on correctness, security, and maintainability +- Provide constructive, specific feedback + +### 4. Discussion and Revision + +- Author responds to all review comments +- Author makes requested changes or provides justification +- Author pushes updates to the same branch +- Author requests re-review when changes are complete + +### 5. Approval and Merge + +- At least one approval from a maintainer required +- All CI checks must pass +- No outstanding blocking comments +- PR must be up-to-date with main branch +- Squash and merge (or merge commit if history needed) + +### 6. Post-Merge + +- Reviewer monitors for any issues +- Author closes related issues +- Team updates documentation if needed + +--- + +## Review Roles + +### Author + +**Responsibilities:** +- Write clean, documented code +- Write tests for new functionality +- Update documentation +- Respond to review comments promptly +- Make requested changes or provide justification +- Follow project conventions + +### Reviewer + +**Responsibilities:** +- Review code thoroughly and promptly +- Provide constructive, specific feedback +- Ask questions if something is unclear +- Suggest improvements and alternatives +- Ensure code follows project standards +- Verify tests are adequate + +### Maintainer + +**Responsibilities:** +- Approve or reject pull requests +- Ensure review process is followed +- Resolve conflicts in review feedback +- Make final merge decisions +- Enforce code quality standards + +### Domain Expert + +**Responsibilities:** +- Review changes in their area of expertise +- Provide deep technical feedback +- Ensure domain-specific correctness +- Suggest architectural improvements + +--- + +## Review Requirements + +### Minimum Review Requirements + +**All PRs must have:** +- At least one reviewer approval +- All automated checks passing (tests, lint, build) +- No unresolved blocking comments +- Updated documentation (if applicable) +- Tests for new functionality +- Descriptive commit messages + +**Additional requirements by PR type:** + +#### Feature PRs +- [ ] At least one maintainer approval +- [ ] Design document (for large features) +- [ ] Tests with >80% coverage for new code +- [ ] Updated API documentation +- [ ] Performance impact assessment + +#### Bug Fix PRs +- [ ] Test case reproducing the bug +- [ ] Verification that fix resolves the issue +- [ ] Regression tests +- [ ] Root cause analysis in PR description + +#### Security PRs +- [ ] Security expert review +- [ ] Security impact assessment +- [ ] Vulnerability disclosure (if applicable) +- [ ] Security testing +- [ ] Maintainer approval + +#### Performance PRs +- [ ] Performance benchmarks +- [ ] Before/after metrics +- [ ] Profiling data +- [ ] Performance expert review + +#### Refactoring PRs +- [ ] No behavior changes +- [ ] All existing tests pass +- [ ] Refactoring justification +- [ ] Migration guide (if breaking) + +### Review Timeline + +- **Small PRs (<100 lines)**: Review within 24 hours +- **Medium PRs (100-500 lines)**: Review within 48 hours +- **Large PRs (500+ lines)**: Review within 72 hours +- **Complex PRs**: Break down into smaller PRs if possible + +### Review Priority + +| Priority | PR Type | SLA | +|----------|---------|-----| +| Critical | Security fixes, production bugs | 4 hours | +| High | Important features, performance | 24 hours | +| Medium | Regular features, improvements | 48 hours | +| Low | Documentation, minor fixes | 1 week | + +--- + +## Code Review Checklists + +### General Checklist + +**Code Quality** +- [ ] Code follows project style guidelines +- [ ] No compiler warnings +- [ ] No linting errors +- [ ] Code is properly formatted +- [ ] Complex logic has comments +- [ ] Magic numbers replaced with constants +- [ ] No dead code or commented-out code +- [ ] No debugging code left in + +**Functionality** +- [ ] Implementation matches requirements +- [ ] Edge cases are handled +- [ ] Error handling is comprehensive +- [ ] Input validation is present +- [ ] Security best practices followed +- [ ] Performance is acceptable +- [ ] Memory usage is reasonable + +**Testing** +- [ ] Unit tests added/updated +- [ ] Integration tests added (if applicable) +- [ ] E2E tests added (for UI changes) +- [ ] Tests cover happy path +- [ ] Tests cover error cases +- [ ] Test coverage is sufficient (>80% for new code) +- [ ] All tests pass locally + +**Documentation** +- [ ] Public APIs documented +- [ ] Complex algorithms explained +- [ ] README updated (if needed) +- [ ] API documentation updated (if endpoints changed) +- [ ] Changelog updated (if breaking change) +- [ ] Comments are accurate and up-to-date + +**Security** +- [ ] No secrets or keys committed +- [ ] User inputs are validated +- [ ] SQL injection prevention in place +- [ ] XSS prevention in place (frontend) +- [ ] Authentication/authorization correct +- [ ] Rate limiting applied (if public API) +- [ ] Dependencies are up-to-date + +### Smart Contract Checklist + +**Additional for Soroban Contracts:** +- [ ] Storage keys are unique and well-named +- [ ] State changes are atomic +- [ ] Access control is properly implemented +- [ ] Error messages are descriptive +- [ ] Gas optimization considered +- [ ] Events emitted for state changes +- [ ] Input validation at contract entry +- [ ] Reentrancy protection (if applicable) +- [ ] Integer overflow/underflow prevention +- [ ] Cross-contract calls handled safely +- [ ] WASM size is reasonable +- [ ] Test coverage >90% + +### Backend Checklist + +**Additional for Rust/Axum:** +- [ ] Handler functions are async where appropriate +- [ ] Database queries use parameterized statements +- [ ] Connection pooling configured +- [ ] Error types are comprehensive +- [ ] utoipa annotations added for new endpoints +- [ ] ToSchema derived for request/response structs +- [ ] Rate limiting applied to public endpoints +- [ ] CORS configured correctly +- [ ] Logging is appropriate (not too verbose) +- [ ] Environment variables used for configuration +- [ ] Database migrations included +- [ ] SQL injection prevention verified + +### Frontend Checklist + +**Additional for Next.js/TypeScript:** +- [ ] Components are reusable and modular +- [ ] TypeScript types defined (no `any`) +- [ ] Props interface documented +- [ ] State management is appropriate +- [ ] Error boundaries implemented +- [ ] Loading states handled +- [ ] Responsive design verified +- [ ] Accessibility (a11y) considered +- [ ] Performance optimized (lazy loading, memoization) +- [ ] SEO metadata updated (if applicable) +- [ ] API error handling is user-friendly +- [ ] Form validation is comprehensive + +### Database Checklist + +**Additional for SQL Changes:** +- [ ] Migration is reversible +- [ ] Migration doesn't destroy data +- [ ] Indexes added for query optimization +- [ ] Foreign key constraints defined +- [ ] Unique constraints where appropriate +- [ ] Default values specified +- [ ] Data types are appropriate +- [ ] Migration tested on sample data +- [ ] Rollback plan documented + +--- + +## Review Standards + +### Code Quality Standards + +**Readability** +- Code should be self-documenting where possible +- Function names should describe what they do +- Variable names should be descriptive +- Complex logic should have explanatory comments +- File structure should be logical + +**Maintainability** +- Code should be modular and loosely coupled +- Functions should be small and focused (single responsibility) +- DRY principle followed (Don't Repeat Yourself) +- Dependencies should be minimal +- Configuration should be externalized + +**Performance** +- Algorithms should be efficient +- Database queries should be optimized +- Caching used where appropriate +- Memory usage should be reasonable +- No unnecessary computations + +**Security** +- Input validation on all user inputs +- Output encoding to prevent XSS +- SQL injection prevention +- Authentication and authorization +- Secrets never committed +- Dependencies regularly updated + +### Documentation Standards + +**Code Comments** +- Public APIs must have documentation +- Complex algorithms must be explained +- Non-obvious decisions need comments +- TODO comments should have context and issue numbers +- Comments should explain "why", not "what" + +**API Documentation** +- All endpoints documented with utoipa +- Request/response schemas defined +- Error responses documented +- Examples provided +- Authentication requirements specified + +**README/Docs** +- Setup instructions updated +- Configuration documented +- Breaking changes noted +- Migration guides provided + +### Testing Standards + +**Coverage Requirements** +- New code: >80% coverage +- Critical paths: >90% coverage +- Utility functions: 100% coverage + +**Test Quality** +- Tests should be independent +- Tests should be fast +- Tests should be deterministic +- Tests should have clear names +- Tests should test behavior, not implementation + +--- + +## Review Guidelines + +### For Reviewers + +**Be Constructive** +- Focus on the code, not the person +- Explain the "why" behind suggestions +- Provide code examples for improvements +- Acknowledge good work + +**Be Specific** +- Point to specific lines of code +- Suggest concrete improvements +- Explain the impact of changes +- Link to relevant documentation + +**Be Thorough** +- Review the entire change, not just the diff +- Consider edge cases +- Think about long-term implications +- Check for security issues + +**Be Timely** +- Respond to review requests promptly +- If you can't review, reassign or comment +- Aim to complete reviews within SLA + +### For Authors + +**Be Receptive** +- Accept feedback gracefully +- Ask clarifying questions +- Explain your reasoning if you disagree +- Learn from the review process + +**Be Responsive** +- Respond to comments promptly +- Make requested changes quickly +- Request re-review when ready +- Don't leave PRs hanging + +**Be Professional** +- Don't take feedback personally +- Focus on improving the code +- Thank reviewers for their time +- Help reviewers understand the context + +--- + +## Review Metrics + +### Key Metrics to Track + +- **Review Time**: Average time from PR request to approval +- **Review Count**: Number of reviewers per PR +- **Comment Count**: Number of review comments per PR +- **Cycle Time**: Time from PR creation to merge +- **Rejection Rate**: Percentage of PRs rejected +- **Revision Count**: Number of revisions per PR +- **Test Coverage**: Coverage percentage before and after + +### Quality Metrics + +- **Bug Rate**: Number of bugs found in production per PR +- **Defect Density**: Bugs per thousand lines of code +- **Review Effectiveness**: Bugs caught during review vs. production +- **Code Churn**: Percentage of code changed within 3 months + +### Process Metrics + +- **PR Backlog**: Number of PRs awaiting review +- **Reviewer Availability**: Average reviewer capacity +- **Merge Frequency**: Number of merges per day/week +- **Review Participation**: Percentage of team members reviewing + +### Goals + +- Average review time: <48 hours +- Reviewer participation: >80% +- Test coverage: >80% +- Production bugs from reviewed code: <5% + +--- + +## Review Templates + +### PR Review Comment Template + +```markdown +## Feedback + +### Overall +[Brief summary of overall impression] + +### Issues +- [ ] **Issue 1**: Description with line reference + - Severity: [Critical/High/Medium/Low] + - Suggestion: What to fix + +### Suggestions +- [ ] **Suggestion 1**: Improvement opportunity + - Benefit: Why this helps + +### Questions +- [ ] **Question 1**: Something unclear + - Context: Why this matters + +### Positive Feedback +- Good job on [specific aspect] +- Nice implementation of [specific feature] +``` + +### Review Summary Template + +```markdown +## Review Summary + +**PR**: #123 +**Reviewer**: @username +**Status**: [Approved/Changes Requested] + +### Summary +[Brief overview of the review] + +### Key Findings +- [ ] Critical issues: 0 +- [ ] High priority: 2 +- [ ] Medium priority: 3 +- [ ] Low priority: 1 + +### Recommendation +[Approve with minor changes / Request changes / Reject] + +### Next Steps +[List of actions needed before merge] +``` + +--- + +## Escalation Process + +### When to Escalate + +- Review not completed within SLA +- Disagreement on technical approach +- Blocking review comments that seem unreasonable +- Security concerns not addressed +- Process violations + +### Escalation Steps + +1. **Discuss directly**: First try to resolve with the reviewer +2. **Tag maintainer**: If unresolved, tag a maintainer for input +3. **Team discussion**: If still unresolved, bring to team meeting +4. **Final decision**: Maintainer makes final call + +--- + +## Continuous Improvement + +### Review Process Reviews + +Quarterly review of the code review process: +- Collect feedback from team +- Analyze metrics +- Identify bottlenecks +- Implement improvements + +### Training + +Regular training sessions on: +- Code review best practices +- Security review techniques +- Performance optimization +- Testing strategies + +### Tool Improvements + +Regular evaluation of tools: +- Automated review tools (linters, static analysis) +- Code coverage tools +- Security scanners +- CI/CD integration + +--- + +## Resources + +- [Contributing Guidelines](./Contributing.md) +- [Code Style Guidelines](./Contributing.md#code-style-guidelines) +- [Testing Requirements](./Contributing.md#testing-requirements) +- [GitHub Review Features](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests) + +--- + +## Contact + +For questions about the code review process: +- **Lead Maintainer**: maintainer@chainlogistics.io +- **Team Discord**: https://discord.gg/chainlogistics +- **GitHub Discussions**: https://github.com/ChainLojistics/ChainLogistics/discussions diff --git a/Contributing.md b/Contributing.md index 77708557..94b581a1 100644 --- a/Contributing.md +++ b/Contributing.md @@ -2,7 +2,7 @@ Thank you for your interest in contributing to ChainLojistic! This comprehensive guide will help you contribute effectively to our open-source supply chain tracking platform. -## ๐Ÿ“š Table of Contents +## ๐Ÿ“š Table of Contentss - [Quick Start](#quick-start) - [Development Setup](#development-setup) - [Project Structure](#project-structure) @@ -25,7 +25,7 @@ ChainLojistic is a decentralized supply chain tracker built on Stellar's Soroban 1. **Smart Contracts** (Rust/Soroban) - On-chain logic 2. **Frontend** (Next.js 15/React 19/TypeScript) - Web UI -3. **Backend** (Node.js/Express/TypeScript) - API (optional) +3. **Backend** (Rust/Axum/SQLx) - High-Performance API Server **New contributors**: Look for issues labeled `good first issue`! @@ -48,7 +48,10 @@ rustup target add wasm32-unknown-unknown ``` #### Frontend & Backend: -- Node.js 18+ +- Node.js 18+ (for frontend) +- Rust 1.70+ (for backend) +- PostgreSQL 14+ (for backend database) +- Redis 6+ (for backend caching) - npm or yarn - Git @@ -74,46 +77,174 @@ cd ../frontend npm install npm run dev # http://localhost:3000 -# 6. Backend (optional) +# 6. Backend (Rust/Axum) cd ../backend -npm install +cargo build +cargo test cp .env.example .env -npm run dev # http://localhost:3001 +cargo run # http://localhost:3001 ``` --- ## ๐Ÿ“ Project Structure - ``` ChainLojistic/ -โ”œโ”€โ”€ contracts/ # Soroban Smart Contracts -โ”‚ โ”œโ”€โ”€ src/lib.rs # Main contract (Product, Events) +โ”œโ”€โ”€ contracts/ # Soroban Smart Contracts +โ”‚ โ”œโ”€โ”€ src/ +โ”‚ โ”‚ โ”œโ”€โ”€ lib.rs # Contract entry point & exports +โ”‚ โ”‚ โ”œโ”€โ”€ contract.rs # Main contract implementation +โ”‚ โ”‚ โ”œโ”€โ”€ types.rs # Data structures (Product, Event) +โ”‚ โ”‚ โ”œโ”€โ”€ storage.rs # Storage keys & helpers +โ”‚ โ”‚ โ”œโ”€โ”€ error.rs # Custom error types +โ”‚ โ”‚ โ”œโ”€โ”€ events.rs # Event emission +โ”‚ โ”‚ โ”œโ”€โ”€ validation.rs # Input validation logic +โ”‚ โ”‚ โ””โ”€โ”€ test/ +โ”‚ โ”‚ โ”œโ”€โ”€ mod.rs # Test module exports +โ”‚ โ”‚ โ”œโ”€โ”€ setup.rs # Test utilities & fixtures +โ”‚ โ”‚ โ”œโ”€โ”€ product_tests.rs # Product function tests +โ”‚ โ”‚ โ”œโ”€โ”€ event_tests.rs # Event tracking tests +โ”‚ โ”‚ โ”œโ”€โ”€ access_tests.rs # Authorization tests +โ”‚ โ”‚ โ””โ”€โ”€ integration_tests.rs # Full workflow tests โ”‚ โ”œโ”€โ”€ Cargo.toml โ”‚ โ””โ”€โ”€ README.md โ”‚ -โ”œโ”€โ”€ frontend/ # Next.js App +โ”œโ”€โ”€ frontend/ # Next.js Application โ”‚ โ”œโ”€โ”€ app/ -โ”‚ โ”‚ โ”œโ”€โ”€ page.tsx # Homepage -โ”‚ โ”‚ โ”œโ”€โ”€ register/ # Product registration -โ”‚ โ”‚ โ”œโ”€โ”€ track/ # Tracking pages -โ”‚ โ”‚ โ””โ”€โ”€ verify/ # Verification +โ”‚ โ”‚ โ”œโ”€โ”€ layout.tsx # Root layout +โ”‚ โ”‚ โ”œโ”€โ”€ page.tsx # Homepage (EXISTS) +โ”‚ โ”‚ โ”œโ”€โ”€ globals.css # Global styles +โ”‚ โ”‚ โ”œโ”€โ”€ register/ +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ page.tsx # Product registration +โ”‚ โ”‚ โ”œโ”€โ”€ products/ +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ page.tsx # Products list +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ [id]/ +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ page.tsx # Product detail +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ add-event/ +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ page.tsx # Add tracking event +โ”‚ โ”‚ โ”œโ”€โ”€ verify/ +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ [id]/ +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ page.tsx # QR verification page +โ”‚ โ”‚ โ””โ”€โ”€ analytics/ +โ”‚ โ”‚ โ””โ”€โ”€ page.tsx # Analytics dashboard โ”‚ โ”œโ”€โ”€ components/ -โ”‚ โ”‚ โ”œโ”€โ”€ wallet/ # Wallet connection -โ”‚ โ”‚ โ”œโ”€โ”€ tracking/ # Timeline, events -โ”‚ โ”‚ โ””โ”€โ”€ ui/ # Reusable components +โ”‚ โ”‚ โ”œโ”€โ”€ wallet/ +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ WalletConnect.tsx # Wallet connection button +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ WalletStatus.tsx # Wallet status indicator +โ”‚ โ”‚ โ”œโ”€โ”€ forms/ +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ ProductForm.tsx # Product registration form +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ EventForm.tsx # Event tracking form +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ FormInput.tsx # Reusable form input +โ”‚ โ”‚ โ”œโ”€โ”€ tracking/ +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ Timeline.tsx # Event timeline +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ EventCard.tsx # Single event display +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ EventFilters.tsx # Filter events +โ”‚ โ”‚ โ”œโ”€โ”€ products/ +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ ProductCard.tsx # Product card +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ ProductList.tsx # Products grid +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ ProductDetails.tsx # Product info display +โ”‚ โ”‚ โ”œโ”€โ”€ qr/ +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ QRGenerator.tsx # Generate QR codes +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ QRScanner.tsx # Scan QR codes +โ”‚ โ”‚ โ”œโ”€โ”€ charts/ +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ EventsChart.tsx # Events visualization +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ OriginChart.tsx # Origin distribution +โ”‚ โ”‚ โ””โ”€โ”€ ui/ +โ”‚ โ”‚ โ”œโ”€โ”€ Button.tsx # Reusable button +โ”‚ โ”‚ โ”œโ”€โ”€ Card.tsx # Reusable card +โ”‚ โ”‚ โ”œโ”€โ”€ Input.tsx # Reusable input +โ”‚ โ”‚ โ”œโ”€โ”€ Modal.tsx # Modal component +โ”‚ โ”‚ โ””โ”€โ”€ LoadingSpinner.tsx # Loading state โ”‚ โ”œโ”€โ”€ lib/ -โ”‚ โ”‚ โ”œโ”€โ”€ stellar.ts # Soroban interaction -โ”‚ โ”‚ โ””โ”€โ”€ types.ts # TypeScript types -โ”‚ โ””โ”€โ”€ package.json +โ”‚ โ”‚ โ”œโ”€โ”€ stellar/ +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ client.ts # Stellar RPC client +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ contract.ts # Contract interaction +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ wallet.ts # Wallet utilities +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ types.ts # Stellar types +โ”‚ โ”‚ โ”œโ”€โ”€ utils/ +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ format.ts # Formatting helpers +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ validation.ts # Client-side validation +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ constants.ts # Constants +โ”‚ โ”‚ โ””โ”€โ”€ hooks/ +โ”‚ โ”‚ โ”œโ”€โ”€ useContract.ts # Contract interaction hook +โ”‚ โ”‚ โ”œโ”€โ”€ useProducts.ts # Product data hook +โ”‚ โ”‚ โ”œโ”€โ”€ useEvents.ts # Events data hook +โ”‚ โ”‚ โ””โ”€โ”€ useWallet.ts # Wallet hook +โ”‚ โ”œโ”€โ”€ contexts/ +โ”‚ โ”‚ โ”œโ”€โ”€ WalletContext.tsx # Wallet state +โ”‚ โ”‚ โ””โ”€โ”€ ContractContext.tsx # Contract state +โ”‚ โ”œโ”€โ”€ types/ +โ”‚ โ”‚ โ”œโ”€โ”€ product.ts # Product types +โ”‚ โ”‚ โ”œโ”€โ”€ event.ts # Event types +โ”‚ โ”‚ โ””โ”€โ”€ api.ts # API types +โ”‚ โ”œโ”€โ”€ public/ +โ”‚ โ”‚ โ”œโ”€โ”€ images/ +โ”‚ โ”‚ โ””โ”€โ”€ icons/ +โ”‚ โ”œโ”€โ”€ tests/ +โ”‚ โ”‚ โ”œโ”€โ”€ unit/ # Unit tests +โ”‚ โ”‚ โ””โ”€โ”€ e2e/ # E2E tests +โ”‚ โ”œโ”€โ”€ package.json +โ”‚ โ”œโ”€โ”€ tsconfig.json +โ”‚ โ”œโ”€โ”€ tailwind.config.ts +โ”‚ โ””โ”€โ”€ next.config.ts โ”‚ -โ””โ”€โ”€ backend/ # API Server - โ”œโ”€โ”€ src/ - โ”‚ โ”œโ”€โ”€ index.ts # Express app - โ”‚ โ”œโ”€โ”€ routes/ # API routes - โ”‚ โ””โ”€โ”€ services/ # Business logic - โ””โ”€โ”€ package.json -``` +โ”œโ”€โ”€ backend/ # Rust API Server (Axum) +โ”‚ โ”œโ”€โ”€ src/ +โ”‚ โ”‚ โ”œโ”€โ”€ main.rs # Server entry point +โ”‚ โ”‚ โ”œโ”€โ”€ lib.rs # Library exports +โ”‚ โ”‚ โ”œโ”€โ”€ routes/ +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ mod.rs # Route module +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ products.rs # Product routes +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ events.rs # Event routes +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ analytics.rs # Analytics routes +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ webhooks.rs # Webhook routes +โ”‚ โ”‚ โ”œโ”€โ”€ services/ +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ soroban_service.rs # Contract interactions +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ cache_service.rs # Redis caching +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ webhook_service.rs # Webhook handling +โ”‚ โ”‚ โ”œโ”€โ”€ middleware/ +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ mod.rs # Middleware module +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ auth.rs # Authentication +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ rate_limit.rs # Rate limiting +โ”‚ โ”‚ โ”œโ”€โ”€ models/ +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ mod.rs # Model exports +โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ product.rs # Product structs +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ event.rs # Event structs +โ”‚ โ”‚ โ”œโ”€โ”€ config/ +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ mod.rs # Configuration +โ”‚ โ”‚ โ”œโ”€โ”€ database/ +โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ mod.rs # Database layer +โ”‚ โ”‚ โ””โ”€โ”€ utils/ +โ”‚ โ”‚ โ””โ”€โ”€ mod.rs # Utilities +โ”‚ โ”œโ”€โ”€ migrations/ # SQLx migrations +โ”‚ โ”œโ”€โ”€ tests/ +โ”‚ โ”‚ โ”œโ”€โ”€ unit/ +โ”‚ โ”‚ โ””โ”€โ”€ integration/ +โ”‚ โ”œโ”€โ”€ Cargo.toml # Rust dependencies +โ”‚ โ””โ”€โ”€ .env.example # Environment variables +โ”‚ +โ”œโ”€โ”€ docs/ # Documentation +โ”‚ โ”œโ”€โ”€ ARCHITECTURE.md +โ”‚ โ”œโ”€โ”€ API.md +โ”‚ โ”œโ”€โ”€ DEPLOYMENT.md +โ”‚ โ””โ”€โ”€ images/ +โ”‚ +โ”œโ”€โ”€ .github/ # GitHub configs +โ”‚ โ”œโ”€โ”€ workflows/ +โ”‚ โ”‚ โ”œโ”€โ”€ contracts-ci.yml # Contract CI/CD +โ”‚ โ”‚ โ”œโ”€โ”€ frontend-ci.yml # Frontend CI/CD +โ”‚ โ”‚ โ””โ”€โ”€ backend-ci.yml # Backend CI/CD +โ”‚ โ”œโ”€โ”€ ISSUE_TEMPLATE/ +โ”‚ โ”‚ โ”œโ”€โ”€ bug_report.md +โ”‚ โ”‚ โ”œโ”€โ”€ feature_request.md +โ”‚ โ”‚ โ””โ”€โ”€ good_first_issue.md +โ”‚ โ””โ”€โ”€ pull_request_template.md +โ”‚ +โ”œโ”€โ”€ .gitignore +โ”œโ”€โ”€ README.md +โ”œโ”€โ”€ CONTRIBUTING.md +โ”œโ”€โ”€ LICENSE +โ””โ”€โ”€ package.json # Root workspace config --- @@ -152,7 +283,7 @@ ChainLojistic/ cd frontend && npm run build # Backend - cd backend && npm test + cd backend && cargo test ``` 6. **Commit & Push** @@ -187,7 +318,7 @@ ChainLojistic/ | `documentation` | Docs work | โญ Easy | | `smart-contract` | Soroban/Rust | โญโญโญ Hard | | `frontend` | Next.js/React | โญโญ Medium | -| `backend` | Node.js/API | โญโญ Medium | +| `backend` | Rust/Axum/API | โญโญ Medium | | `testing` | Test coverage | โญโญ Medium | | `design` | UI/UX work | โญโญ Medium | | `priority: high` | Urgent | - | @@ -730,10 +861,10 @@ npm install -D @types/qrcode Build RESTful API endpoints for product CRUD operations. #### What You'll Learn -- REST API design -- Express.js routing -- Soroban integration -- Error handling +- REST API design with Rust/Axum +- Async Rust programming +- Soroban integration from Rust +- Error handling with thiserror #### Endpoints to Create ``` @@ -745,46 +876,54 @@ POST /api/products/:id/events - Add event ``` #### Implementation -```typescript -// src/routes/products.ts -import { Router } from 'express'; -import { Contract } from '@stellar/stellar-sdk'; - -const router = Router(); - -router.get('/products/:id', async (req, res) => { - try { - const { id } = req.params; - const contract = new Contract(process.env.CONTRACT_ID); - const product = await contract.get_product({ id }); - res.json(product); - } catch (error) { - res.status(500).json({ error: error.message }); - } -}); +```rust +// src/routes/products.rs +use axum::{extract::Path, response::Json, routing::get, Router}; +use soroban_sdk::{Address, Env}; + +pub fn product_routes() -> Router { + Router::new() + .route("/products", get(list_products).post(create_product)) + .route("/products/:id", get(get_product)) + .route("/products/:id/events", get(get_product_events)) +} -export default router; +async fn get_product( + Path(id): Path, + State(app_state): State, +) -> Result, AppError> { + let product = app_state.soroban_service.get_product(&id).await?; + Ok(Json(product)) +} ``` #### Validation -```typescript -// src/middleware/validation.ts -import { body, param, validationResult } from 'express-validator'; - -export const validateProduct = [ - body('id').isString().trim().notEmpty(), - body('name').isString().trim().isLength({ min: 3 }), - body('origin').isString().trim().notEmpty(), - (req, res, next) => { - const errors = validationResult(req); - if (!errors.isEmpty()) { - return res.status(400).json({ errors: errors.array() }); - } - next(); - } -]; -``` +```rust +// src/middleware/validation.rs +use axum::{extract::Request, middleware::Next, response::Response}; +use serde::{Deserialize, Serialize}; +use validator::Validate; + +#[derive(Deserialize, Validate)] +pub struct CreateProductRequest { + #[validate(length(min = 3, message = "Name must be at least 3 characters"))] + pub name: String, + + #[validate(length(min = 1, message = "Origin is required"))] + pub origin: String, + + #[validate(custom = "validate_stellar_address")] + pub owner: String, +} +pub async fn validate_product( + req: Request, + next: Next, +) -> Result { + // Validation logic here + Ok(next.run(req).await) +} +``` #### Error Responses ```json { @@ -795,20 +934,25 @@ export const validateProduct = [ ``` #### Acceptance Criteria -- [ ] All endpoints work -- [ ] Proper validation -- [ ] Error handling -- [ ] Correct HTTP status codes -- [ ] API documented +- [ ] All endpoints functional with proper validation +- [ ] Error handling works correctly +- [ ] Contract integration tested +- [ ] API responses follow consistent format +- [ ] Rate limiting applied #### Files to Create -- `backend/src/routes/products.ts` -- `backend/src/services/productService.ts` -- `backend/src/middleware/validation.ts` +- `backend/src/routes/products.rs` +- `backend/src/services/soroban_service.rs` +- `backend/src/middleware/validation.rs` #### Dependencies -```bash -npm install express-validator +```toml +axum = "0.7" +tokio = { version = "1.0", features = ["full"] } +serde = { version = "1.0", features = ["derive"] } +validator = "0.16" +thiserror = "1.0" +soroban-sdk = "21.0" ``` #### Estimated Time @@ -1063,18 +1207,30 @@ Create a beginner-friendly guide for new users. 1. **Run Tests** ```bash # Contracts - cargo test && cargo clippy - + cd contracts + cargo test + cargo clippy -- -D warnings + cargo build --target wasm32-unknown-unknown --release + # Frontend - npm run build && npm run lint - - # Backend + cd frontend + npm run build + npm run lint + npm run type-check npm test + + # Backend + cd backend + cargo test + cargo clippy -- -D warnings + cargo fmt --check ``` 2. **Update Docs** - Add/update README if needed - Document new features + - Update API documentation if endpoints changed + - Add utoipa annotations for new endpoints 3. **Commit Convention** ``` @@ -1085,93 +1241,881 @@ Create a beginner-friendly guide for new users. refactor: code restructure test: add tests chore: maintenance + ci: CI/CD changes ``` -### PR Template +### Branch Naming + +Use descriptive branch names following this pattern: +- `feature/issue-23-wallet-connection` +- `bugfix/issue-45-auth-token-expiry` +- `hotfix/issue-67-security-patch` +- `docs/update-api-documentation` +- `refactor/optimize-database-queries` + +### PR Description Template ```markdown ## Description -[What does this PR do?] +[Provide a clear and concise description of what this PR does] + +## Type of Change +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] Documentation update +- [ ] Performance improvement +- [ ] Code refactoring ## Related Issue Closes #[issue number] +Related to #[issue number] -## Type -- [ ] Bug fix -- [ ] New feature -- [ ] Breaking change -- [ ] Documentation +## Changes Made +- [ ] Added tests for new functionality +- [ ] Updated documentation +- [ ] Updated API documentation (if applicable) +- [ ] Added/updated utoipa annotations (if applicable) ## Testing -- [ ] Tests pass -- [ ] Manual testing done +### Manual Testing Steps +1. +2. +3. -## Screenshots -[If applicable] +### Automated Tests +- [ ] All existing tests pass +- [ ] New tests added and passing +- [ ] Test coverage maintained or improved + +## Screenshots (if applicable) +[Add screenshots for UI changes] ## Checklist -- [ ] Code follows style guide -- [ ] Self-reviewed -- [ ] Commented complex code -- [ ] Docs updated -- [ ] Tests added +- [ ] My code follows the style guidelines of this project +- [ ] I have performed a self-review of my code +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation +- [ ] My changes generate no new warnings +- [ ] I have added tests that prove my fix is effective or that my feature works +- [ ] New and existing unit tests pass locally with my changes +- [ ] Any dependent changes have been merged and published +``` + +### PR Review Process + +1. **Self-Review** + - Review your own changes before submitting + - Ensure all tests pass + - Check documentation is complete + - Verify no sensitive data is committed + +2. **Request Review** + - Assign at least one reviewer from the team + - Tag relevant team members based on the area of change + - Provide context on what needs focus + +3. **Address Feedback** + - Respond to all review comments + - Make requested changes or provide justification + - Push updates to the same branch + - Request re-review when changes are complete + +4. **Merge Requirements** + - At least one approval from a maintainer + - All CI checks must pass + - No merge conflicts + - PR must be up-to-date with main branch + +--- + +## ๐Ÿงช Testing Requirements + +### Smart Contracts (Rust/Soroban) + +#### Unit Tests +```rust +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_product_creation() { + let env = Env::default(); + let product_id = String::from_str("PROD001").unwrap(); + + let product = register_product(env.clone(), product_id.clone(), "Coffee", "Ethiopia"); + + assert_eq!(product.id, product_id); + assert_eq!(product.name, "Coffee"); + } +} +``` + +#### Integration Tests +```rust +#[test] +fn test_full_product_lifecycle() { + let env = Env::default(); + + // Register product + let product = register_product(env.clone(), "PROD001", "Coffee", "Ethiopia"); + + // Add tracking event + let event = add_tracking_event(env.clone(), "PROD001", "Harvest", "Farm"); + + // Retrieve product + let retrieved = get_product(env, "PROD001"); + + assert_eq!(retrieved.id, product.id); +} +``` + +#### Coverage Requirements +- Minimum 80% code coverage for critical paths +- All public functions must have tests +- Error cases must be tested +- Edge cases must be covered + +#### Test Commands +```bash +# Run all tests +cargo test + +# Run specific test +cargo test test_product_creation + +# Run with output +cargo test -- --nocapture + +# Run tests in release mode +cargo test --release ``` --- +### Frontend (Next.js/TypeScript) + +#### Unit Tests +```typescript +// components/__tests__/ProductCard.test.tsx +import { render, screen } from '@testing-library/react'; +import { ProductCard } from '../ProductCard'; + +describe('ProductCard', () => { + it('renders product name', () => { + const product = { id: '1', name: 'Coffee' }; + render(); + expect(screen.getByText('Coffee')).toBeInTheDocument(); + }); +}); +``` + +#### Integration Tests (Playwright) +```typescript +// tests/e2e/product-registration.spec.ts +import { test, expect } from '@playwright/test'; + +test('user can register a product', async ({ page }) => { + await page.goto('/register'); + await page.fill('[name="productId"]', 'PROD001'); + await page.fill('[name="name"]', 'Organic Coffee'); + await page.click('button[type="submit"]'); + + await expect(page).toHaveURL(/\/products\/PROD001/); +}); +``` + +#### Coverage Requirements +- Minimum 70% code coverage for components +- Critical user flows must have E2E tests +- All hooks must have unit tests +- Utility functions must have 100% coverage + +#### Test Commands +```bash +# Run unit tests +npm test + +# Run with coverage +npm run test:coverage + +# Run E2E tests +npx playwright test + +# Run specific test file +npm test ProductCard.test.tsx +``` + +--- + +### Backend (Rust/Axum) + +#### Unit Tests +```rust +#[cfg(test)] +mod tests { + use super::*; + + #[tokio::test] + async fn test_get_product() { + let pool = create_test_pool().await; + let product = create_test_product(&pool).await; + + let result = get_product(&pool, &product.id).await; + + assert!(result.is_ok()); + assert_eq!(result.unwrap().id, product.id); + } +} +``` + +#### Integration Tests +```rust +#[tokio::test] +async fn test_product_api_endpoint() { + let app = create_test_app().await; + + let response = app + .oneshot(Request::builder() + .uri("/api/v1/products/PROD001") + .body(Body::empty()) + .unwrap()) + .await + .unwrap(); + + assert_eq!(response.status(), StatusCode::OK); +} +``` + +#### Coverage Requirements +- Minimum 80% code coverage for handlers +- All service functions must have tests +- Database operations must be tested +- Error paths must be covered + +#### Test Commands +```bash +# Run all tests +cargo test + +# Run with output +cargo test -- --nocapture + +# Run specific test +cargo test test_get_product + +# Run tests in release mode +cargo test --release + +# Run with coverage (requires tarpaulin) +cargo tarpaulin --out Html +``` + +--- + +### General Testing Guidelines + +#### Test Organization +``` +contracts/src/test/ +โ”œโ”€โ”€ mod.rs # Test module exports +โ”œโ”€โ”€ setup.rs # Test fixtures and utilities +โ”œโ”€โ”€ product_tests.rs # Product-related tests +โ”œโ”€โ”€ event_tests.rs # Event-related tests +โ””โ”€โ”€ integration_tests.rs # Full workflow tests + +frontend/tests/ +โ”œโ”€โ”€ unit/ # Unit tests +โ”‚ โ””โ”€โ”€ components/ +โ”œโ”€โ”€ integration/ # Integration tests +โ””โ”€โ”€ e2e/ # End-to-end tests + +backend/tests/ +โ”œโ”€โ”€ unit/ # Unit tests +โ””โ”€โ”€ integration/ # Integration tests +``` + +#### Test Naming +```rust +// Good: Descriptive and specific +#[test] +fn test_product_registration_with_valid_data() {} + +// Bad: Vague +#[test] +fn test_product() {} +``` + +#### Test Data Management +- Use fixtures for common test data +- Clean up test data after each test +- Use transactions for database tests +- Mock external dependencies + +#### CI/CD Testing +All tests must pass in CI before merging: +- GitHub Actions runs tests on every PR +- Tests run on multiple OS versions +- Database tests use test containers +- E2E tests run on staging environment + +--- + +## โœ… Code Review Checklist + +### Before Submitting for Review + +**Code Quality** +- [ ] Code follows project style guidelines +- [ ] No compiler warnings +- [ ] No clippy warnings (Rust) +- [ ] No ESLint warnings (TypeScript) +- [ ] Code is properly formatted +- [ ] Complex logic has comments +- [ ] Magic numbers are replaced with constants + +**Functionality** +- [ ] Feature works as specified +- [ ] Edge cases are handled +- [ ] Error handling is comprehensive +- [ ] Input validation is present +- [ ] Security best practices followed +- [ ] Performance considerations addressed + +**Testing** +- [ ] Unit tests added +- [ ] Integration tests added (if applicable) +- [ ] E2E tests added (for UI changes) +- [ ] Tests cover happy path +- [ ] Tests cover error cases +- [ ] Test coverage is sufficient +- [ ] All tests pass locally + +**Documentation** +- [ ] Public APIs documented +- [ ] Complex algorithms explained +- [ ] README updated (if needed) +- [ ] API documentation updated (if endpoints changed) +- [ ] Changelog updated (if breaking change) +- [ ] Comments are accurate and up-to-date + +**Security** +- [ ] No secrets or keys committed +- [ ] User inputs are validated +- [ ] SQL injection prevention in place +- [ ] XSS prevention in place (frontend) +- [ ] Authentication/authorization correct +- [ ] Rate limiting applied (if public API) + +**Performance** +- [ ] No obvious performance issues +- [ ] Database queries optimized +- [ ] Caching used where appropriate +- [ ] Large data sets handled efficiently +- [ ] Memory leaks checked + +### During Review + +**Review Focus Areas** +- [ ] Code is readable and maintainable +- [ ] Logic is correct and efficient +- [ ] Error handling is appropriate +- [ ] Security vulnerabilities identified +- [ ] Performance bottlenecks identified +- [ ] Test coverage is adequate +- [ ] Documentation is clear + +**Review Comments Guidelines** +- Be constructive and specific +- Explain the "why" behind suggestions +- Provide code examples for improvements +- Ask questions if something is unclear +- Acknowledge good work + +### Before Merging + +**Final Checks** +- [ ] All review comments addressed +- [ ] CI checks passing +- [ ] No merge conflicts +- [ ] Up-to-date with main branch +- [ ] At least one approval from maintainer +- [ ] Breaking changes documented +- [ ] Migration guide provided (if needed) + +### Post-Merge + +**Follow-up Tasks** +- [ ] Monitor production for issues +- [ ] Update issue tracker +- [ ] Close related issues +- [ ] Notify team of deployment +- [ ] Update documentation website (if applicable) +- [ ] Create release notes (if needed) + +--- + ## ๐ŸŽจ Code Style Guidelines -### Smart Contracts (Rust) +### Smart Contracts (Rust/Soroban) + +#### Naming Conventions ```rust -// Good naming +// Functions: snake_case pub fn register_product() {} โœ… pub fn reg_prod() {} โŒ -// Document public APIs -/// Registers a new product. -pub fn register_product() {} +// Structs: PascalCase +pub struct Product {} โœ… +pub struct product {} โŒ + +// Constants: SCREAMING_SNAKE_CASE +pub const MAX_PRODUCTS: u32 = 1000; โœ… +pub const max_products: u32 = 1000; โŒ + +// Storage keys: SymbolShort +let key = symbol_short!("PRODUCT"); โœ… +let key = symbol_short!("product"); โŒ +``` + +#### Documentation +```rust +/// Registers a new product on the blockchain. +/// +/// # Arguments +/// +/// * `product_id` - Unique identifier for the product +/// * `name` - Human-readable product name +/// * `origin` - Geographic origin location +/// +/// # Returns +/// +/// Returns the newly created Product struct. +/// +/// # Errors +/// +/// Returns `Error::AlreadyExists` if product_id is already registered. +/// +/// # Example +/// +/// ``` +/// let product = register_product(env, "PROD001", "Coffee", "Ethiopia"); +/// ``` +pub fn register_product( + env: Env, + product_id: String, + name: String, + origin: String, +) -> Product { + // implementation +} +``` + +#### Error Handling +```rust +// Use custom error types +#[derive(Error, Debug)] +pub enum Error { + #[error("Product already exists")] + AlreadyExists, + #[error("Unauthorized access")] + Unauthorized, +} + +// Panic with errors for contract failures +if product_exists { + panic_with_error!(&env, Error::AlreadyExists); +} +``` + +#### Code Organization +```rust +// File structure +src/ +โ”œโ”€โ”€ lib.rs # Contract entry point +โ”œโ”€โ”€ contract.rs # Main contract logic +โ”œโ”€โ”€ types.rs # Data structures +โ”œโ”€โ”€ storage.rs # Storage helpers +โ”œโ”€โ”€ error.rs # Error types +โ”œโ”€โ”€ events.rs # Event emission +โ””โ”€โ”€ validation.rs # Input validation + +// Use modules for organization +pub mod types; +pub mod storage; +pub mod error; + +use crate::types::{Product, Event}; +use crate::storage::{get_product, set_product}; +``` -// Format & lint +#### Format & Lint +```bash +# Format code cargo fmt -cargo clippy + +# Check for issues +cargo clippy -- -D warnings + +# Run tests +cargo test + +# Build for WASM +cargo build --target wasm32-unknown-unknown --release ``` -### Frontend (TypeScript) +--- + +### Frontend (Next.js/TypeScript) + +#### Naming Conventions ```typescript -// Strict TypeScript +// Components: PascalCase +export function ProductCard() {} โœ… +export function productCard() {} โŒ + +// Functions: camelCase +function getUserData() {} โœ… +function get_user_data() {} โŒ + +// Constants: UPPER_SNAKE_CASE +const MAX_RETRIES = 3; โœ… +const maxRetries = 3; โŒ + +// Types/Interfaces: PascalCase +interface UserProfile {} โœ… +interface userProfile {} โŒ +``` + +#### Component Structure +```typescript +// Use functional components with hooks +export function ProductCard({ product }: ProductCardProps) { + const [loading, setLoading] = useState(false); + + useEffect(() => { + // effect logic + }, [product.id]); + + if (loading) return ; + + return
{product.name}
; +} + +// Define props interface +interface ProductCardProps { + product: Product; + onEdit?: () => void; +} +``` + +#### TypeScript Best Practices +```typescript +// Always define types interface Product { id: string; name: string; + origin: string; } -// Functional components -export function ProductCard({ product }: { product: Product }) { - return
{product.name}
; -} +// Avoid `any` +function processData(data: any) {} โŒ +function processData(data: Product) {} โœ… + +// Use union types for variants +type EventStatus = 'pending' | 'confirmed' | 'failed'; -// Organize imports -import { useState } from 'react'; // React -import { Contract } from '@stellar/sdk'; // Packages -import { format } from '@/lib/utils'; // Local +// Use generics for reusable types +interface ApiResponse { + data: T; + error: string | null; +} ``` -### Backend (TypeScript) +#### Import Organization ```typescript -// Async/await -async function getProduct(id: string) { - return await contract.get_product({ id }); +// 1. React and hooks +import { useState, useEffect } from 'react'; + +// 2. Third-party libraries +import { Contract } from '@stellar/stellar-sdk'; +import { useRouter } from 'next/navigation'; + +// 3. Internal modules +import { Product } from '@/types/product'; +import { useWallet } from '@/hooks/useWallet'; +import { formatAddress } from '@/lib/utils'; +``` + +#### File Organization +``` +app/ +โ”œโ”€โ”€ layout.tsx # Root layout +โ”œโ”€โ”€ page.tsx # Homepage +โ””โ”€โ”€ products/ + โ”œโ”€โ”€ page.tsx # Products list + โ””โ”€โ”€ [id]/ + โ””โ”€โ”€ page.tsx # Product detail + +components/ +โ”œโ”€โ”€ ui/ # Reusable UI components +โ”œโ”€โ”€ forms/ # Form components +โ”œโ”€โ”€ wallet/ # Wallet-related +โ””โ”€โ”€ tracking/ # Tracking components + +lib/ +โ”œโ”€โ”€ stellar/ # Stellar SDK utilities +โ”œโ”€โ”€ utils/ # Helper functions +โ””โ”€โ”€ hooks/ # Custom hooks +``` + +#### Linting & Formatting +```bash +# Format code +npm run format + +# Lint code +npm run lint + +# Type check +npm run type-check + +# Run tests +npm test + +# Build for production +npm run build +``` + +--- + +### Backend (Rust/Axum) + +#### Naming Conventions +```rust +// Structs: PascalCase +pub struct AppState {} โœ… +pub struct app_state {} โŒ + +// Functions: snake_case +pub async fn get_product() {} โœ… +pub async fn getProduct() {} โŒ + +// Constants: SCREAMING_SNAKE_CASE +pub const API_VERSION: &str = "v1"; โœ… +pub const api_version: &str = "v1"; โŒ +``` + +#### Handler Structure +```rust +// Use proper error handling +pub async fn get_product( + State(state): State, + Path(id): Path, +) -> Result, AppError> { + let product = state.product_service + .get_product(&id) + .await + .map_err(|_| AppError::NotFound("Product not found".to_string()))?; + + Ok(Json(product.into())) } +``` -// Error handling -try { - const product = await getProduct(id); - res.json(product); -} catch (error) { - logger.error('Error fetching product', { id, error }); - res.status(500).json({ error: 'Internal error' }); +#### Database Queries +```rust +// Use SQLx for type-safe queries +pub async fn get_product( + pool: &PgPool, + id: &str, +) -> Result { + sqlx::query_as!( + Product, + r#" + SELECT id, name, description, origin_location, category, tags, + certifications, media_hashes, custom_fields, owner_address, + is_active, created_at, updated_at, created_by, updated_by + FROM products + WHERE id = $1 + "#, + id + ) + .fetch_one(pool) + .await +} +``` + +#### Error Handling +```rust +// Define custom error types +#[derive(Debug)] +pub enum AppError { + NotFound(String), + Unauthorized(String), + ValidationError(String), + DatabaseError(String), + InternalError(String), +} + +impl IntoResponse for AppError { + fn into_response(self) -> Response { + let (status, message) = match self { + AppError::NotFound(msg) => (StatusCode::NOT_FOUND, msg), + AppError::Unauthorized(msg) => (StatusCode::UNAUTHORIZED, msg), + AppError::ValidationError(msg) => (StatusCode::BAD_REQUEST, msg), + AppError::DatabaseError(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg), + AppError::InternalError(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg), + }; + + (status, Json(json!({ "error": message }))).into_response() + } +} +``` + +#### Validation +```rust +// Validate inputs before processing +use crate::validation::{validate_string, validate_stellar_address}; + +pub async fn create_product( + State(state): State, + Json(req): Json, +) -> Result, AppError> { + // Validate inputs + validate_string("name", &req.name, 100)?; + validate_stellar_address(&req.owner_address)?; + validate_string("origin", &req.origin, 200)?; + + // Process request + let product = state.product_service.create_product(req).await?; + + Ok(Json(product)) +} +``` + +#### OpenAPI Documentation +```rust +// Add utoipa annotations for all public endpoints +#[utoipa::path( + get, + path = "/api/v1/products/{id}", + tag = "products", + params( + ("id" = String, Path, description = "Product ID") + ), + responses( + (status = 200, description = "Product retrieved successfully", body = ProductResponse), + (status = 404, description = "Product not found"), + (status = 401, description = "Unauthorized"), + (status = 429, description = "Rate limit exceeded") + ), + security( + ("api_key" = []) + ) +)] +pub async fn get_product( + State(state): State, + Path(id): Path, +) -> Result, AppError> { + // implementation } ``` +#### Format & Lint +```bash +# Format code +cargo fmt + +# Check for issues +cargo clippy -- -D warnings + +# Run tests +cargo test + +# Run with database +cargo run + +# Build for release +cargo build --release +``` + +--- + +### General Guidelines + +#### Git Commit Messages +``` +(): + + + +