From 4bfb3c2b273c2f6ec80fb6d4efa9a3ebd3e46fbe Mon Sep 17 00:00:00 2001 From: ola196 Date: Wed, 21 Oct 2026 15:25:32 +0000 Subject: [PATCH] fix(scripts): fix broken root scripts and missing contract scaffold - fix(scripts/build-wasm.sh): replace hard-coded non-existent paths (stellar-contract/, packages/contracts/contracts/market/) with a loop over contracts/*/ using the actual Cargo.toml presence as a guard - fix(scripts/publish-registry.sh): replace deprecated 'soroban contract install' with 'stellar contract install'; resolve WASM files from target/wasm32-unknown-unknown/release/ instead of the repo root - feat(backend/seeds): create missing seed entry-point files that seed:basic, seed:performance and seed:cleanup npm scripts resolve to (apps/backend/src/test/seeds/{basic,performance,cleanup}.seed.ts) - fix(contracts/escrow): add missing Cargo.toml so the crate compiles; add contracts/escrow to workspace members in root Cargo.toml - fix(scripts): add execute bit (+x) to 13 scripts that were missing it: audit-eslint-disables.sh, audit-imports.sh, ci-local.sh, consolidate-types.sh, find-duplicate-types.sh, find-unused-exports.sh, fix-imports.sh, generate-contract-errors.js, generate-trend-report.js, migrate-error-enums.sh, remove-unused-exports.sh (build-wasm.sh and publish-registry.sh also fixed above) Closes #1382 --- Cargo.toml | 1 + apps/backend/src/test/seeds/basic.seed.ts | 39 +++++++++++ apps/backend/src/test/seeds/cleanup.seed.ts | 57 ++++++++++++++++ .../src/test/seeds/performance.seed.ts | 39 +++++++++++ contracts/escrow/Cargo.toml | 17 +++++ scripts/audit-eslint-disables.sh | 0 scripts/audit-imports.sh | 0 scripts/build-wasm.sh | 68 ++++++++++++++----- scripts/ci-local.sh | 0 scripts/consolidate-types.sh | 0 scripts/find-duplicate-types.sh | 0 scripts/find-unused-exports.sh | 0 scripts/fix-imports.sh | 0 scripts/generate-contract-errors.js | 0 scripts/generate-trend-report.js | 0 scripts/migrate-error-enums.sh | 0 scripts/publish-registry.sh | 68 ++++++++++++++----- scripts/remove-unused-exports.sh | 0 18 files changed, 255 insertions(+), 34 deletions(-) create mode 100644 apps/backend/src/test/seeds/basic.seed.ts create mode 100644 apps/backend/src/test/seeds/cleanup.seed.ts create mode 100644 apps/backend/src/test/seeds/performance.seed.ts create mode 100644 contracts/escrow/Cargo.toml mode change 100644 => 100755 scripts/audit-eslint-disables.sh mode change 100644 => 100755 scripts/audit-imports.sh mode change 100644 => 100755 scripts/build-wasm.sh mode change 100644 => 100755 scripts/ci-local.sh mode change 100644 => 100755 scripts/consolidate-types.sh mode change 100644 => 100755 scripts/find-duplicate-types.sh mode change 100644 => 100755 scripts/find-unused-exports.sh mode change 100644 => 100755 scripts/fix-imports.sh mode change 100644 => 100755 scripts/generate-contract-errors.js mode change 100644 => 100755 scripts/generate-trend-report.js mode change 100644 => 100755 scripts/migrate-error-enums.sh mode change 100644 => 100755 scripts/publish-registry.sh mode change 100644 => 100755 scripts/remove-unused-exports.sh diff --git a/Cargo.toml b/Cargo.toml index 0b2aaa95..09d0bc9f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ members = [ "contracts/market", "contracts/dispute", "contracts/royalty_distribution", + "contracts/escrow", ] [workspace.dependencies] diff --git a/apps/backend/src/test/seeds/basic.seed.ts b/apps/backend/src/test/seeds/basic.seed.ts new file mode 100644 index 00000000..4520d774 --- /dev/null +++ b/apps/backend/src/test/seeds/basic.seed.ts @@ -0,0 +1,39 @@ +/** + * Basic seed entry point — seeds a small representative data set + * (10 users, 5 courses, enrollments, progress records). + * + * Invoked via: npm run seed:basic --workspace=apps/backend + * Which resolves to: ts-node -r tsconfig-paths/register src/test/seeds/basic.seed.ts + */ +import { NestFactory } from '@nestjs/core'; +import { Logger } from '@nestjs/common'; +import { AppModule } from '../../app.module'; +import { SeedService } from '../../database/seed.service'; +import { env } from '../../config/env'; + +async function bootstrap(): Promise { + const logger = new Logger('BasicSeed'); + + if (env.isProduction) { + logger.error('❌ Refusing to seed in production. Set NODE_ENV to development or staging.'); + process.exit(1); + } + + const app = await NestFactory.createApplicationContext(AppModule, { + logger: ['error', 'warn'], + }); + const seedService = app.get(SeedService); + + try { + logger.log('🌱 Running basic seed (10 users, 5 courses) …'); + await seedService.seed({ count: 10, includeReviews: false, includeTips: false }); + logger.log('✅ Basic seed complete.'); + } catch (err) { + logger.error('❌ Basic seed failed:', err); + process.exit(1); + } finally { + await app.close(); + } +} + +bootstrap(); diff --git a/apps/backend/src/test/seeds/cleanup.seed.ts b/apps/backend/src/test/seeds/cleanup.seed.ts new file mode 100644 index 00000000..e3ba3657 --- /dev/null +++ b/apps/backend/src/test/seeds/cleanup.seed.ts @@ -0,0 +1,57 @@ +/** + * Cleanup seed entry point — removes seeded test data from the database. + * + * Invoked via: npm run seed:cleanup --workspace=apps/backend + * Which resolves to: ts-node -r tsconfig-paths/register src/test/seeds/cleanup.seed.ts + */ +import { NestFactory } from '@nestjs/core'; +import { Logger } from '@nestjs/common'; +import { getDataSourceToken } from '@nestjs/typeorm'; +import { DataSource } from 'typeorm'; +import { AppModule } from '../../app.module'; +import { env } from '../../config/env'; + +async function bootstrap(): Promise { + const logger = new Logger('CleanupSeed'); + + if (env.isProduction) { + logger.error('❌ Refusing to truncate in production. Set NODE_ENV to development or staging.'); + process.exit(1); + } + + const app = await NestFactory.createApplicationContext(AppModule, { + logger: ['error', 'warn'], + }); + + const dataSource = app.get(getDataSourceToken()); + + try { + logger.log('🗑️ Truncating seeded tables …'); + + // Truncate in dependency order (children first, then parents) + const tables = [ + 'progress', + 'enrollment', + 'review', + 'lesson', + 'course_module', + 'notification', + 'course', + 'user', + ]; + + for (const table of tables) { + await dataSource.query(`TRUNCATE TABLE "${table}" CASCADE`); + logger.log(` ✓ ${table} cleared`); + } + + logger.log('✅ Cleanup complete.'); + } catch (err) { + logger.error('❌ Cleanup failed:', err); + process.exit(1); + } finally { + await app.close(); + } +} + +bootstrap(); diff --git a/apps/backend/src/test/seeds/performance.seed.ts b/apps/backend/src/test/seeds/performance.seed.ts new file mode 100644 index 00000000..9795b0c6 --- /dev/null +++ b/apps/backend/src/test/seeds/performance.seed.ts @@ -0,0 +1,39 @@ +/** + * Performance seed entry point — seeds a large data set intended for + * load / performance testing (500 users, 50 courses, full relations). + * + * Invoked via: npm run seed:performance --workspace=apps/backend + * Which resolves to: ts-node -r tsconfig-paths/register src/test/seeds/performance.seed.ts + */ +import { NestFactory } from '@nestjs/core'; +import { Logger } from '@nestjs/common'; +import { AppModule } from '../../app.module'; +import { SeedService } from '../../database/seed.service'; +import { env } from '../../config/env'; + +async function bootstrap(): Promise { + const logger = new Logger('PerformanceSeed'); + + if (env.isProduction) { + logger.error('❌ Refusing to seed in production. Set NODE_ENV to development or staging.'); + process.exit(1); + } + + const app = await NestFactory.createApplicationContext(AppModule, { + logger: ['error', 'warn'], + }); + const seedService = app.get(SeedService); + + try { + logger.log('🌱 Running performance seed (500 users, 50 courses) …'); + await seedService.seed({ count: 500, includeReviews: true, includeTips: true }); + logger.log('✅ Performance seed complete.'); + } catch (err) { + logger.error('❌ Performance seed failed:', err); + process.exit(1); + } finally { + await app.close(); + } +} + +bootstrap(); diff --git a/contracts/escrow/Cargo.toml b/contracts/escrow/Cargo.toml new file mode 100644 index 00000000..adbb8aaa --- /dev/null +++ b/contracts/escrow/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "brain-storm-escrow" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +soroban-sdk = { version = "21.0.0", features = ["alloc"] } +brain-storm-shared = { path = "../shared", default-features = false } + +[dev-dependencies] +soroban-sdk = { version = "21.0.0", features = ["testutils"] } + +[lints] +workspace = true diff --git a/scripts/audit-eslint-disables.sh b/scripts/audit-eslint-disables.sh old mode 100644 new mode 100755 diff --git a/scripts/audit-imports.sh b/scripts/audit-imports.sh old mode 100644 new mode 100755 diff --git a/scripts/build-wasm.sh b/scripts/build-wasm.sh old mode 100644 new mode 100755 index ac77149b..de127a7e --- a/scripts/build-wasm.sh +++ b/scripts/build-wasm.sh @@ -1,38 +1,70 @@ -#!/bin/bash -# Build WASM contracts locally for development/testing +#!/usr/bin/env bash +# Build WASM contracts locally for development/testing. +# Builds every crate under contracts/ that contains a Cargo.toml. -set -e +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" GREEN='\033[0;32m' YELLOW='\033[1;33m' +RED='\033[0;31m' NC='\033[0m' echo -e "${YELLOW}🔨 Building WASM contracts...${NC}" -# Build all contracts -for contract in stellar-contract packages/contracts/contracts/market; do - if [ -d "$contract" ]; then - echo -e "${GREEN}Building $contract...${NC}" - cd "$contract" - cargo build --target wasm32-unknown-unknown --release - cd - > /dev/null +BUILT=0 +FAILED=0 + +for contract_dir in "$ROOT_DIR"/contracts/*/; do + contract_name=$(basename "$contract_dir") + + # Skip entries that are not Rust crates + if [ ! -f "$contract_dir/Cargo.toml" ]; then + continue + fi + + echo -e "${GREEN}Building $contract_name...${NC}" + if cargo build \ + --manifest-path "$contract_dir/Cargo.toml" \ + --target wasm32-unknown-unknown \ + --release; then + BUILT=$((BUILT + 1)) + else + echo -e "${RED}❌ Failed to build $contract_name${NC}" >&2 + FAILED=$((FAILED + 1)) fi done -echo -e "${GREEN}✅ All WASM contracts built!${NC}" +if [ "$BUILT" -eq 0 ] && [ "$FAILED" -eq 0 ]; then + echo -e "${YELLOW}⚠️ No Rust contracts found under contracts/${NC}" + exit 0 +fi + +if [ "$FAILED" -gt 0 ]; then + echo -e "${RED}❌ $FAILED contract(s) failed to build.${NC}" >&2 + exit 1 +fi + +echo -e "${GREEN}✅ All $BUILT WASM contract(s) built!${NC}" -# Compute hashes +# Compute checksums echo -e "${YELLOW}📋 Computing checksums...${NC}" -echo "# WASM Contract Checksums" > CHECKSUMS.md -echo "" >> CHECKSUMS.md -echo "| Contract | Size | SHA256 |" >> CHECKSUMS.md -echo "|----------|------|--------|" >> CHECKSUMS.md +CHECKSUMS_FILE="$ROOT_DIR/CHECKSUMS.md" +{ + echo "# WASM Contract Checksums" + echo "" + echo "| Contract | Size | SHA256 |" + echo "|----------|------|--------|" +} > "$CHECKSUMS_FILE" -find . -name "*.wasm" -type f | while read -r file; do +find "$ROOT_DIR/target/wasm32-unknown-unknown/release" \ + -maxdepth 1 -name "*.wasm" -type f \ + ! -path "*/deps/*" 2>/dev/null | sort | while read -r file; do NAME=$(basename "$file" .wasm) SIZE=$(stat -c%s "$file" 2>/dev/null || stat -f%z "$file" 2>/dev/null) HASH=$(sha256sum "$file" | cut -d' ' -f1) - echo "| $NAME | $SIZE bytes | \`$HASH\` |" >> CHECKSUMS.md + echo "| $NAME | $SIZE bytes | \`$HASH\` |" >> "$CHECKSUMS_FILE" done echo -e "${GREEN}✅ Checksums saved to CHECKSUMS.md${NC}" diff --git a/scripts/ci-local.sh b/scripts/ci-local.sh old mode 100644 new mode 100755 diff --git a/scripts/consolidate-types.sh b/scripts/consolidate-types.sh old mode 100644 new mode 100755 diff --git a/scripts/find-duplicate-types.sh b/scripts/find-duplicate-types.sh old mode 100644 new mode 100755 diff --git a/scripts/find-unused-exports.sh b/scripts/find-unused-exports.sh old mode 100644 new mode 100755 diff --git a/scripts/fix-imports.sh b/scripts/fix-imports.sh old mode 100644 new mode 100755 diff --git a/scripts/generate-contract-errors.js b/scripts/generate-contract-errors.js old mode 100644 new mode 100755 diff --git a/scripts/generate-trend-report.js b/scripts/generate-trend-report.js old mode 100644 new mode 100755 diff --git a/scripts/migrate-error-enums.sh b/scripts/migrate-error-enums.sh old mode 100644 new mode 100755 diff --git a/scripts/publish-registry.sh b/scripts/publish-registry.sh old mode 100644 new mode 100755 index 750e24aa..3471f284 --- a/scripts/publish-registry.sh +++ b/scripts/publish-registry.sh @@ -1,32 +1,68 @@ -#!/bin/bash -# Publish contracts to Soroban registry +#!/usr/bin/env bash +# Publish compiled contracts to the Stellar/Soroban registry. +# Requires: DEPLOYER_SECRET env var, stellar CLI, and wasm files built by build-wasm.sh. -set -e +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +WASM_DIR="$ROOT_DIR/target/wasm32-unknown-unknown/release" +NETWORK="${NETWORK:-testnet}" GREEN='\033[0;32m' YELLOW='\033[1;33m' RED='\033[0;31m' NC='\033[0m' -# Check if deployer secret is set -if [ -z "$DEPLOYER_SECRET" ]; then - echo -e "${RED}❌ DEPLOYER_SECRET environment variable not set${NC}" +# Check required env var +if [ -z "${DEPLOYER_SECRET:-}" ]; then + echo -e "${RED}❌ DEPLOYER_SECRET environment variable not set${NC}" >&2 + exit 1 +fi + +# Check stellar CLI is available +if ! command -v stellar &>/dev/null; then + echo -e "${RED}❌ 'stellar' CLI not found in PATH. Install from https://github.com/stellar/stellar-cli/releases${NC}" >&2 + exit 1 +fi + +# Ensure wasm files are present +if [ ! -d "$WASM_DIR" ]; then + echo -e "${RED}❌ WASM output directory not found: $WASM_DIR${NC}" >&2 + echo -e "${YELLOW} Run ./scripts/build-wasm.sh (or ./scripts/build.sh) first.${NC}" >&2 exit 1 fi -echo -e "${YELLOW}📦 Publishing contracts to Soroban registry...${NC}" +WASM_FILES=() +while IFS= read -r -d '' f; do + WASM_FILES+=("$f") +done < <(find "$WASM_DIR" -maxdepth 1 -name "*.wasm" -type f ! -path "*/deps/*" -print0 2>/dev/null) -# Find all WASM files -find . -name "*.wasm" -type f | while read -r file; do +if [ "${#WASM_FILES[@]}" -eq 0 ]; then + echo -e "${RED}❌ No .wasm files found in $WASM_DIR${NC}" >&2 + echo -e "${YELLOW} Run ./scripts/build-wasm.sh (or ./scripts/build.sh) first.${NC}" >&2 + exit 1 +fi + +echo -e "${YELLOW}📦 Publishing ${#WASM_FILES[@]} contract(s) to Stellar registry (network: $NETWORK)...${NC}" + +PUBLISHED=0 +FAILED=0 + +for file in "${WASM_FILES[@]}"; do NAME=$(basename "$file" .wasm) echo -e "${GREEN}Publishing $NAME...${NC}" - - # Publish to testnet - soroban contract install \ + + if stellar contract install \ --wasm "$file" \ - --network testnet \ - --source-account "$DEPLOYER_SECRET" \ - --output-json || echo -e "${RED}❌ Failed to publish $NAME${NC}" + --network "$NETWORK" \ + --source-account "$DEPLOYER_SECRET"; then + PUBLISHED=$((PUBLISHED + 1)) + else + echo -e "${RED}❌ Failed to publish $NAME${NC}" >&2 + FAILED=$((FAILED + 1)) + fi done -echo -e "${GREEN}✅ All contracts published!${NC}" +echo "" +echo -e "${GREEN}✅ Published: $PUBLISHED | ${RED}Failed: $FAILED${NC}" +[ "$FAILED" -gt 0 ] && exit 1 || exit 0 diff --git a/scripts/remove-unused-exports.sh b/scripts/remove-unused-exports.sh old mode 100644 new mode 100755