Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .coderabbit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

language: "pt-BR"

tone_instructions: "Seja direto em português BR. Foque em bugs reais, segurança e performance. Ignore nitpicks de estilo. Sinalizar como crítico: secrets hardcoded, SQL injection, promises sem await/catch, any sem tratamento, operações destrutivas sem backup."
tone_instructions: "Direto em PT-BR. Foco: bugs, segurança, performance. Ignore nitpicks. Crítico: secrets hardcoded, SQL injection, promises sem await/catch, any sem narrowing, ops destrutivas sem backup."

early_access: false

Expand Down
50 changes: 42 additions & 8 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,59 @@
name: Security & Compliance
...

on:
pull_request:
branches: [main]
push:
branches: [main]
schedule:
# Toda segunda-feira às 06:30 (UTC) — 03:30 BRT
- cron: '30 6 * * 1'
workflow_dispatch:

permissions:
contents: read
pull-requests: read
security-events: write

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add the RLS compliance script before scheduling it

With this workflow restored under jobs:, the rls-audit job now runs on the scheduled/manual Security workflow, but its report step invokes bun scripts/verify_rls_compliance.ts; I checked the repository with git ls-files '*verify*rls*' '*rls*compliance*' 'scripts/*' and that script is not present. As a result, every weekly or manually dispatched security workflow will fail as soon as this job reaches the report step.

Useful? React with 👍 / 👎.

gitleaks:
name: Gitleaks — Secret Scan
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Run Gitleaks
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITLEAKS_ENABLE_SUMMARY: "false"

rls-audit:
name: 🛡️ RLS & Compliance Weekly Report
name: RLS & Compliance Weekly Report
runs-on: ubuntu-latest
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
steps:
- name: 📥 Checkout code
- name: Checkout code
uses: actions/checkout@v4
- name: 📦 Setup Node.js
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: 📚 Install dependencies
- name: Setup Bun
uses: oven-sh/setup-bun@v1
- name: Install dependencies
run: npm install --no-audit --no-fund
- name: 🛡️ Generate RLS Report
- name: Generate RLS Report
run: bun scripts/verify_rls_compliance.ts > rls-compliance-report.md
- name: 📜 Publish Weekly Compliance
- name: Publish Weekly Compliance
Comment on lines +53 to +55
uses: actions/upload-artifact@v4
with:
name: weekly-security-compliance-report
path: rls-compliance-report.md

6 changes: 6 additions & 0 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@
"lovable-tagger": "^1.1.13",
"playwright": "^1.59.1",
"postcss": "^8.5.6",
"prettier": "^3.8.3",
"prettier-plugin-tailwindcss": "^0.8.0",
"prop-types": "^15.8.1",
"storybook": "^10.3.6",
"supabase": "2.9.8",
Expand Down
20 changes: 5 additions & 15 deletions src/lib/retry.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { getLogger, generateCorrelationId } from '@/lib/logger';
import { dbFrom } from '@/integrations/datasource/db';

const log = getLogger('RetryUtil');

Expand All @@ -16,9 +15,9 @@ interface RetryOptions {
* Works with any async operation (Supabase, fetch, etc).
*
* @example
* const data = await withRetry(() => dbFrom('contacts').select('*'), {
* const data = await withRetry(() => fetchSomething(), {
* maxRetries: 3,
* onRetry: (err, attempt) => console.log(`Retry ${attempt}`, err),
* onRetry: (err, attempt) => log.warn('Retry', { attempt, err }),
* });
*/
export async function withRetry<T>(
Expand All @@ -43,18 +42,12 @@ export async function withRetry<T>(
lastError = error;

if (attempt >= maxRetries || !shouldRetry(error, attempt)) {
log.error(
`[${correlationId}] All ${maxRetries} retries exhausted`,
error
);
log.error(`[${correlationId}] All ${maxRetries} retries exhausted`, error);
throw error;
}

// Exponential backoff with jitter
const delay = Math.min(
baseDelayMs * Math.pow(2, attempt) + Math.random() * 500,
maxDelayMs
);
const delay = Math.min(baseDelayMs * Math.pow(2, attempt) + Math.random() * 500, maxDelayMs);

log.warn(
`[${correlationId}] Attempt ${attempt + 1}/${maxRetries} failed, retrying in ${Math.round(delay)}ms`
Expand All @@ -71,10 +64,7 @@ export async function withRetry<T>(
/**
* Convenience: retry only on network-like errors (not 4xx client errors).
*/
export async function withNetworkRetry<T>(
operation: () => Promise<T>,
maxRetries = 3
): Promise<T> {
export async function withNetworkRetry<T>(operation: () => Promise<T>, maxRetries = 3): Promise<T> {
return withRetry(operation, {
maxRetries,
shouldRetry: (error) => {
Expand Down
Loading