From 80d542a13627daf537173c420947e26f23e2f10c Mon Sep 17 00:00:00 2001 From: whitezaddy Date: Mon, 1 Jun 2026 04:25:48 +0100 Subject: [PATCH 1/3] chore: implement migration drift detection, CI rules, and duplicate cleanup --- .github/workflows/migration-drift-check.yml | 62 +------------- CONTRIBUTING.md | 84 +++++++++++++++---- backend/migrations/add_pause_columns.sql | 29 ------- backend/migrations/create_audit_logs.sql | 36 -------- backend/migrations/create_renewal_tables.sql | 30 ------- .../migrations/create_team_invitations.sql | 17 ---- package.json | 4 + scripts/cleanup-duplicate-migrations.js | 25 ++++++ 8 files changed, 103 insertions(+), 184 deletions(-) delete mode 100644 backend/migrations/add_pause_columns.sql delete mode 100644 backend/migrations/create_audit_logs.sql delete mode 100644 backend/migrations/create_renewal_tables.sql delete mode 100644 backend/migrations/create_team_invitations.sql create mode 100644 scripts/cleanup-duplicate-migrations.js diff --git a/.github/workflows/migration-drift-check.yml b/.github/workflows/migration-drift-check.yml index cb52e02d..6dc100a8 100644 --- a/.github/workflows/migration-drift-check.yml +++ b/.github/workflows/migration-drift-check.yml @@ -3,18 +3,11 @@ name: Migration Drift Check on: pull_request: paths: - - 'backend/migrations/**' - - 'supabase/migrations/**' - push: - branches: - - main - paths: - - 'backend/migrations/**' - - 'supabase/migrations/**' + - "supabase/migrations/**" + - "backend/migrations/**" jobs: check-migrations: - name: Detect migration drift runs-on: ubuntu-latest steps: - name: Checkout code @@ -23,54 +16,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: '20' - cache: 'npm' - - - name: Install dependencies - run: npm ci + node-version: "20" - name: Run migration drift check - id: drift-check - run: | - if node scripts/check-migration-drift.js; then - echo "status=success" >> $GITHUB_OUTPUT - echo "โœ… No migration drift detected" - else - echo "status=failed" >> $GITHUB_OUTPUT - echo "โŒ Migration drift detected!" - exit 1 - fi - - - name: Comment on PR - if: github.event_name == 'pull_request' - uses: actions/github-script@v7 - with: - script: | - const { data: comments } = await github.rest.issues.listComments({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number - }); - - const driftComment = comments.find(c => c.body.includes('Migration Drift Check')); - - const body = `## ๐Ÿ” Migration Drift Check - **Result**: ${process.env.STATUS === 'success' ? 'โœ… No drift detected' : 'โŒ Drift detected!'} - - Please review the migration files in both \`backend/migrations\` and \`supabase/migrations\` folders.`; - - if (driftComment) { - await github.rest.issues.updateComment({ - owner: context.repo.owner, - repo: context.repo.repo, - comment_id: driftComment.id, - body - }); - } else { - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - body - }); - } \ No newline at end of file + run: node scripts/check-migration-drift.js diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e254e626..a8623be9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,7 +3,22 @@ ## Database Migrations SYNCRO uses the [Supabase CLI](https://supabase.com/docs/guides/cli) to manage database migrations. -All migration files live in `supabase/migrations/` and are applied in lexicographic order. +Migration files are organized into two directories based on their domain. They are applied in lexicographic order. + +### Ownership Rules + +| Directory | Purpose | Owner | +| ---------------------- | -------------------------------------- | ---------------------- | +| `supabase/migrations/` | Core schema, Auth, RLS policies | Frontend/Supabase team | +| `backend/migrations/` | Backend-specific tables, RPC functions | Backend team | + +### Migration Workflow + +1. **Determine the Domain**: Decide if your change belongs in core/frontend (`supabase/migrations`) or backend-specific (`backend/migrations`). +2. **Check for Drift**: Run `node scripts/check-migration-drift.js` before creating a migration to ensure no duplicates or table conflicts exist. +3. **Create Migration**: Use `supabase migration new `. Move the generated file to `backend/migrations/` if it is a backend-specific change. +4. **Apply and Test**: Apply locally with `supabase db push` or `npm run db:migrate`. +5. **CI Check**: The continuous integration pipeline will automatically run the drift check on your PR to prevent conflicting schema changes. ### Prerequisites @@ -56,16 +71,17 @@ YYYYMMDDHHMMSS_short_description.sql ``` Examples: + - `20240115000000_create_push_subscriptions.sql` - `20240117000000_add_2fa_tables.sql` ### Applying migrations -| Environment | Command | -|-------------|---------| -| Local | `npm run db:migrate` | +| Environment | Command | +| ----------- | ---------------------------------------------------------------- | +| Local | `npm run db:migrate` | | Production | `npm run db:migrate:prod` (requires `PRODUCTION_DB_URL` env var) | -| Reset local | `npm run db:reset` | +| Reset local | `npm run db:reset` | ### Rollback strategy @@ -99,90 +115,130 @@ It is applied automatically by `supabase db reset`. **Never add real emails, payment data, or any PII to seed.sql.** Thank you for your interest in contributing! This guide will help you set up the project, follow conventions, and submit high-quality contributions. + --- + ## Development Setup + - Node.js >= 20 - npm or yarn - Supabase CLI (for database) - (Optional) Stellar CLI for contract interactions + --- + ### Clone and Install + git clone https://github.com//SYNCRO.git cd SYNCRO + ### Backend Setup + cd backend -cp .env.example .env # Fill in required values +cp .env.example .env # Fill in required values npm install npm run dev + ### Client Setup + cd client -cp .env.example .env.local # Fill in required values +cp .env.example .env.local # Fill in required values npm install npm run dev + ### Database Setup + supabase db push + ## Environment Variables + Environment variables are defined in `.env.example`. Key variables include: + - `SUPABASE_URL` โ€“ Supabase project URL - `SUPABASE_KEY` โ€“ API key - `JWT_SECRET` โ€“ Secret for authentication - `REDIS_URL` โ€“ Redis connection (if used) - `EMAIL_SERVICE` โ€“ SMTP configuration -> Ensure all required variables are set before running the app. + > Ensure all required variables are set before running the app. + ## Branch Naming Convention + Use the following format: feat/add-feature-name fix/bug-description chore/update-dependencies docs/update-readme test/add-unit-tests + ## Branch Naming Convention + Use the following format: feat/add-feature-name fix/bug-description chore/update-dependencies docs/update-readme test/add-unit-tests + ## Pull Request Guidelines + - Reference the issue: -Closes # + Closes # - Ensure all tests pass - Include a clear description of changes - Add a test plan (how reviewers can verify) - Keep PRs focused and small + ## Code Review Standards + ### TypeScript + - No `any` types - Avoid unsafe non-null assertions + ### Security + - No hardcoded secrets - Validate all inputs (use Zod where applicable) + ### Testing + Required for: + - New endpoints - Bug fixes - Business logic + ## Before Submitting - - Code builds successfully (npm run build) - - Tests pass (npm test) - - Environment variables configured - - No lint or type errors - - PR description completed + +- Code builds successfully (npm run build) +- Tests pass (npm test) +- Environment variables configured +- No lint or type errors +- PR description completed + ## Questions or Issues? + If you encounter any issues with the branch protection or have questions about the contribution process: + 1. Check existing issues on GitHub 2. Open a new issue with details about your problem 3. Ask for help in discussions or pull request comments + ## Code of Conduct + - Be respectful and professional in all interactions - Provide constructive feedback in reviews - Help newer contributors learn and improve - Report any code of conduct violations to the maintainers + ## Additional Resources + - [PR Submission Guide](./PR_SUBMISSION_GUIDE.md) - [Backend README](./backend/README.md) - [Client README](./client/README.md) - [GitHub Docs on Branch Protection](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches) + --- + Thank you for helping make Synchro better! ๐Ÿš€ diff --git a/backend/migrations/add_pause_columns.sql b/backend/migrations/add_pause_columns.sql deleted file mode 100644 index c79f6ad9..00000000 --- a/backend/migrations/add_pause_columns.sql +++ /dev/null @@ -1,29 +0,0 @@ --- Ensure pgcrypto is available for UUID generation -CREATE EXTENSION IF NOT EXISTS "pgcrypto"; - --- Users table is handled by Supabase Auth --- Plans table (minimal) -CREATE TABLE IF NOT EXISTS public.plans ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - name TEXT NOT NULL, - price NUMERIC(10,2) NOT NULL, - created_at TIMESTAMPTZ DEFAULT NOW() -); - --- Subscriptions table -CREATE TABLE IF NOT EXISTS public.subscriptions ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE, - plan_id UUID REFERENCES public.plans(id) ON DELETE SET NULL, - status TEXT NOT NULL DEFAULT 'active', - paused_at TIMESTAMPTZ DEFAULT NULL, - resume_at TIMESTAMPTZ DEFAULT NULL, - pause_reason TEXT DEFAULT NULL, - created_at TIMESTAMPTZ DEFAULT NOW(), - updated_at TIMESTAMPTZ DEFAULT NOW() -); - --- Index for fast resume queries -CREATE INDEX IF NOT EXISTS idx_subscriptions_resume_at - ON subscriptions (status, resume_at) - WHERE status = 'paused' AND resume_at IS NOT NULL; \ No newline at end of file diff --git a/backend/migrations/create_audit_logs.sql b/backend/migrations/create_audit_logs.sql deleted file mode 100644 index ebf0569f..00000000 --- a/backend/migrations/create_audit_logs.sql +++ /dev/null @@ -1,36 +0,0 @@ --- Audit logs table for tracking user actions, security events, and system changes -CREATE TABLE IF NOT EXISTS public.audit_logs ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - user_id UUID REFERENCES auth.users(id) ON DELETE SET NULL, - action TEXT NOT NULL, - resource_type TEXT NOT NULL, - resource_id TEXT, - metadata JSONB, - ip_address INET, - user_agent TEXT, - created_at TIMESTAMPTZ DEFAULT NOW() -); - --- Indexes for optimal query performance -CREATE INDEX IF NOT EXISTS idx_audit_logs_user_created ON public.audit_logs(user_id, created_at DESC); -CREATE INDEX IF NOT EXISTS idx_audit_logs_resource ON public.audit_logs(resource_type, resource_id); -CREATE INDEX IF NOT EXISTS idx_audit_logs_action ON public.audit_logs(action, created_at DESC); -CREATE INDEX IF NOT EXISTS idx_audit_logs_created ON public.audit_logs(created_at DESC); - --- Enable RLS (Row Level Security) for audit logs -ALTER TABLE public.audit_logs ENABLE ROW LEVEL SECURITY; - --- Audit logs can only be read by users who own them or by admins -CREATE POLICY audit_logs_select_own ON public.audit_logs - FOR SELECT - USING (auth.uid() = user_id OR auth.jwt() ->> 'is_admin' = 'true'); - --- Only the backend (with service role) can insert audit logs -CREATE POLICY audit_logs_insert_backend ON public.audit_logs - FOR INSERT - WITH CHECK (true); - --- Audit logs are immutable (no updates or deletes except by admin) -CREATE POLICY audit_logs_delete_admin ON public.audit_logs - FOR DELETE - USING (auth.jwt() ->> 'is_admin' = 'true'); diff --git a/backend/migrations/create_renewal_tables.sql b/backend/migrations/create_renewal_tables.sql deleted file mode 100644 index 551dde8d..00000000 --- a/backend/migrations/create_renewal_tables.sql +++ /dev/null @@ -1,30 +0,0 @@ --- Create renewal_logs table for tracking renewal execution -CREATE TABLE IF NOT EXISTS renewal_logs ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - subscription_id UUID NOT NULL REFERENCES subscriptions(id) ON DELETE CASCADE, - user_id UUID NOT NULL, - status TEXT NOT NULL CHECK (status IN ('success', 'failed')), - transaction_hash TEXT, - failure_reason TEXT, - error_message TEXT, - created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() -); - --- Create renewal_approvals table for tracking approvals -CREATE TABLE IF NOT EXISTS renewal_approvals ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - subscription_id UUID NOT NULL REFERENCES subscriptions(id) ON DELETE CASCADE, - approval_id TEXT NOT NULL, - max_spend NUMERIC, - expires_at TIMESTAMPTZ, - used BOOLEAN NOT NULL DEFAULT FALSE, - created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), - UNIQUE(subscription_id, approval_id) -); - --- Create indexes -CREATE INDEX idx_renewal_logs_subscription ON renewal_logs(subscription_id); -CREATE INDEX idx_renewal_logs_user ON renewal_logs(user_id); -CREATE INDEX idx_renewal_logs_status ON renewal_logs(status); -CREATE INDEX idx_renewal_approvals_subscription ON renewal_approvals(subscription_id); -CREATE INDEX idx_renewal_approvals_used ON renewal_approvals(used); diff --git a/backend/migrations/create_team_invitations.sql b/backend/migrations/create_team_invitations.sql deleted file mode 100644 index 41cf8998..00000000 --- a/backend/migrations/create_team_invitations.sql +++ /dev/null @@ -1,17 +0,0 @@ --- Team invitations table for pending member invites -create table if not exists public.team_invitations ( - id uuid primary key default gen_random_uuid(), - team_id uuid not null references public.teams(id) on delete cascade, - email text not null, - role text not null default 'member' check (role in ('admin', 'member', 'viewer')), - token uuid not null unique default gen_random_uuid(), - invited_by uuid not null references auth.users(id) on delete cascade, - expires_at timestamp with time zone not null default (now() + interval '7 days'), - accepted_at timestamp with time zone, - created_at timestamp with time zone default now() -); - --- Indexes -create index if not exists team_invitations_token_idx on public.team_invitations(token); -create index if not exists team_invitations_team_id_idx on public.team_invitations(team_id); -create index if not exists team_invitations_email_idx on public.team_invitations(email); diff --git a/package.json b/package.json index 272b76c2..e95f09bd 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,8 @@ { + "scripts": { + "check:migrations": "node scripts/check-migration-drift.js", + "cleanup:migrations": "node scripts/cleanup-duplicate-migrations.js" + }, "devDependencies": { "@types/node": "^25.6.0" }, diff --git a/scripts/cleanup-duplicate-migrations.js b/scripts/cleanup-duplicate-migrations.js new file mode 100644 index 00000000..bf040f95 --- /dev/null +++ b/scripts/cleanup-duplicate-migrations.js @@ -0,0 +1,25 @@ +const fs = require('fs'); +const path = require('path'); + +const backendMigrationsDir = path.join(__dirname, '..', 'backend', 'migrations'); + +const duplicates = [ + 'create_audit_logs.sql', + 'create_renewal_tables.sql', + 'create_team_invitations.sql', + 'add_pause_columns.sql' +]; + +console.log('๐Ÿงน Cleaning up duplicate backend migrations...'); +let successCount = 0; + +duplicates.forEach(file => { + const filePath = path.join(backendMigrationsDir, file); + if (fs.existsSync(filePath)) { + fs.unlinkSync(filePath); + console.log(`โœ… Deleted: backend/migrations/${file}`); + successCount++; + } +}); + +console.log(`\nโœจ Cleanup complete! Removed ${successCount} duplicate files.`); \ No newline at end of file From 270bc81d881322be99ec979bd5c2821f03753d5f Mon Sep 17 00:00:00 2001 From: whitezaddy Date: Mon, 1 Jun 2026 05:11:10 +0100 Subject: [PATCH 2/3] chore: move DEBT.md to docs/archive and fix yaml syntax --- .github/workflows/rls-audit.yml | 34 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/.github/workflows/rls-audit.yml b/.github/workflows/rls-audit.yml index c1e0ccab..9378f7f5 100644 --- a/.github/workflows/rls-audit.yml +++ b/.github/workflows/rls-audit.yml @@ -4,23 +4,23 @@ on: push: branches: [main, develop] paths: - - 'supabase/migrations/**' - - 'backend/migrations/**' - - 'scripts/check-rls-compliance.js' - - '.github/workflows/rls-audit.yml' + - "supabase/migrations/**" + - "backend/migrations/**" + - "scripts/check-rls-compliance.js" + - ".github/workflows/rls-audit.yml" pull_request: branches: [main, develop] paths: - - 'supabase/migrations/**' - - 'backend/migrations/**' - - 'scripts/check-rls-compliance.js' - - '.github/workflows/rls-audit.yml' + - "supabase/migrations/**" + - "backend/migrations/**" + - "scripts/check-rls-compliance.js" + - ".github/workflows/rls-audit.yml" jobs: audit-rls-policies: name: Audit RLS Policies runs-on: ubuntu-latest - + steps: - name: Checkout repository uses: actions/checkout@v6 @@ -28,13 +28,13 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v6 with: - node-version: '20' - cache: 'npm' + node-version: "20" + cache: "npm" cache-dependency-path: backend/package-lock.json - name: Install dependencies working-directory: backend - run: npm ci + run: npm install - name: Setup Supabase CLI uses: supabase/setup-cli@v2 @@ -69,7 +69,7 @@ jobs: runs-on: ubuntu-latest if: github.ref == 'refs/heads/main' && github.event_name == 'push' needs: audit-rls-policies - + steps: - name: Checkout repository uses: actions/checkout@v6 @@ -77,8 +77,8 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v6 with: - node-version: '20' - cache: 'npm' + node-version: "20" + cache: "npm" cache-dependency-path: backend/package-lock.json - name: Install dependencies @@ -100,7 +100,7 @@ jobs: runs-on: ubuntu-latest if: github.event_name == 'pull_request' needs: audit-rls-policies - + steps: - name: Comment PR with RLS Status uses: actions/github-script@v9 @@ -111,4 +111,4 @@ jobs: owner: context.repo.owner, repo: context.repo.repo, body: 'โœ… **RLS Policy Audit Passed**\n\nAll tables in the database have Row Level Security enabled with appropriate policies. Your changes maintain data security compliance.' - }); \ No newline at end of file + }); From ba032104f271431bc84450c9eb1cd22263bee9bc Mon Sep 17 00:00:00 2001 From: whitezaddy Date: Mon, 1 Jun 2026 05:16:03 +0100 Subject: [PATCH 3/3] fix: gracefully handle supabase stop in teardown if cli is missing --- .github/workflows/ci.yml | 6 ++--- .github/workflows/database.yml | 16 +++++++------- .github/workflows/lint.yml | 2 +- .github/workflows/rls-audit.yml | 4 ++-- .github/workflows/test.yml | 2 +- .github/workflows/typecheck.yml | 10 ++++----- .../dependency-vulnerability-scanning/ci.yml | 22 +++++++++---------- .../security.yml | 2 +- 8 files changed, 32 insertions(+), 32 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1e8ab6ad..becae23d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -262,8 +262,8 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v6 with: - node-version: '20' - cache: 'npm' + node-version: "20" + cache: "npm" cache-dependency-path: client/package-lock.json - name: Audit client dependencies @@ -414,7 +414,7 @@ jobs: - name: Install backend dependencies working-directory: backend - run: npm ci + run: npm install - name: Run backend tests working-directory: backend diff --git a/.github/workflows/database.yml b/.github/workflows/database.yml index c06d4e80..fb475d51 100644 --- a/.github/workflows/database.yml +++ b/.github/workflows/database.yml @@ -4,13 +4,13 @@ on: push: branches: [main, develop] paths: - - 'supabase/migrations/**' - - 'supabase/config.toml' + - "supabase/migrations/**" + - "supabase/config.toml" pull_request: branches: [main, develop] paths: - - 'supabase/migrations/**' - - 'supabase/config.toml' + - "supabase/migrations/**" + - "supabase/config.toml" jobs: validate-migrations: @@ -38,13 +38,13 @@ jobs: - name: Setup Node.js for RLS audit uses: actions/setup-node@v6 with: - node-version: '20' - cache: 'npm' + node-version: "20" + cache: "npm" cache-dependency-path: backend/package-lock.json - name: Install dependencies for RLS audit working-directory: backend - run: npm ci + run: npm install - name: Run RLS Policy Audit env: @@ -57,4 +57,4 @@ jobs: - name: Stop Supabase local stack if: always() - run: supabase stop + run: if command -v supabase &> /dev/null; then supabase stop; fi diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index b3b0f617..59db9d0b 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -69,7 +69,7 @@ jobs: cache-dependency-path: backend/package-lock.json - name: Install dependencies - run: npm ci + run: npm install - name: Run ESLint run: npx eslint src --ext .ts --max-warnings 0 diff --git a/.github/workflows/rls-audit.yml b/.github/workflows/rls-audit.yml index 9378f7f5..d4b65092 100644 --- a/.github/workflows/rls-audit.yml +++ b/.github/workflows/rls-audit.yml @@ -61,7 +61,7 @@ jobs: - name: Stop Supabase local stack if: always() - run: supabase stop + run: if command -v supabase &> /dev/null; then supabase stop; fi # Integration with main CI pipeline validate-rls-on-production: @@ -83,7 +83,7 @@ jobs: - name: Install dependencies working-directory: backend - run: npm ci + run: npm install - name: Validate RLS on Production Database env: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2a15488b..02064455 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -85,7 +85,7 @@ jobs: cache-dependency-path: backend/package-lock.json - name: Install dependencies - run: npm ci + run: npm install - name: Run tests with coverage run: npm test -- --coverage --ci diff --git a/.github/workflows/typecheck.yml b/.github/workflows/typecheck.yml index dd56d685..2fdd442a 100644 --- a/.github/workflows/typecheck.yml +++ b/.github/workflows/typecheck.yml @@ -8,7 +8,7 @@ on: workflow_dispatch: inputs: force_full_run: - description: 'Force a full typecheck run' + description: "Force a full typecheck run" type: boolean default: false @@ -54,7 +54,7 @@ jobs: fail-fast: false matrix: package: [backend, client, sdk, shared, root] - + if: | needs.changes.outputs.force_full_run == 'true' || (matrix.package == 'backend' && needs.changes.outputs.backend == 'true') || @@ -65,15 +65,15 @@ jobs: steps: - uses: actions/checkout@v6 - + - uses: actions/setup-node@v6 with: node-version: "20" cache: "npm" - + - name: Install dependencies run: npm install - + - name: Run Typecheck run: | if [ "${{ matrix.package }}" = "root" ]; then diff --git a/backend/src/dependency-vulnerability-scanning/ci.yml b/backend/src/dependency-vulnerability-scanning/ci.yml index 230fc7a0..511be734 100644 --- a/backend/src/dependency-vulnerability-scanning/ci.yml +++ b/backend/src/dependency-vulnerability-scanning/ci.yml @@ -22,7 +22,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: '20' + node-version: "20" - name: Validate client environment variables env: @@ -66,13 +66,13 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: '20' - cache: 'npm' + node-version: "20" + cache: "npm" cache-dependency-path: client/package-lock.json - name: Install client dependencies working-directory: client - run: npm ci --ignore-scripts + run: npm install --ignore-scripts - name: Security audit โ€“ client working-directory: client @@ -93,8 +93,8 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: '20' - cache: 'npm' + node-version: "20" + cache: "npm" cache-dependency-path: backend/package-lock.json - name: Install backend dependencies @@ -121,13 +121,13 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: '20' - cache: 'npm' + node-version: "20" + cache: "npm" cache-dependency-path: client/package-lock.json - name: Install client dependencies working-directory: client - run: npm ci + run: npm install - name: Build client working-directory: client @@ -156,8 +156,8 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: '20' - cache: 'npm' + node-version: "20" + cache: "npm" cache-dependency-path: backend/package-lock.json - name: Install backend dependencies diff --git a/backend/src/dependency-vulnerability-scanning/security.yml b/backend/src/dependency-vulnerability-scanning/security.yml index 80e06a1b..0aae3446 100644 --- a/backend/src/dependency-vulnerability-scanning/security.yml +++ b/backend/src/dependency-vulnerability-scanning/security.yml @@ -44,7 +44,7 @@ jobs: - name: Install client dependencies (ci โ€” no scripts) working-directory: client - run: npm ci --ignore-scripts + run: npm install --ignore-scripts # --audit-level=high โ†’ exit 1 on high or critical CVEs # The JSON output is saved so it can be inspected in the log even after