Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat: complete platform features with local Supabase setup (security …#24

Open
saurabharch wants to merge 1 commit into
mainfrom
prod
Open

feat: complete platform features with local Supabase setup (security …#24
saurabharch wants to merge 1 commit into
mainfrom
prod

Conversation

@saurabharch
Copy link
Copy Markdown
Owner

…scrubbed and history cleaned)

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 18, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
bright-website Error Error Apr 18, 2026 9:19am
bright-website-yq2t Error Error Apr 18, 2026 9:19am

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request establishes a robust local development and deployment framework using Docker Compose, integrating a self-hosted Supabase stack with Infisical for secrets management and a monitoring suite (Grafana, Loki, Prometheus). It adds numerous database migrations, utility scripts, and extensive documentation regarding environment setup and data migration. Critical feedback identifies several issues: a hardcoded project URL in a SQL trigger, a security risk from a hardcoded JWT in the development environment file, and a configuration error in the functions service pointing to a non-existent directory. Furthermore, the deployment script contains redundant, buggy code, and the sprite analysis utility is duplicated across two files while referencing missing SVG assets.


-- User must ensure the pg_net extension is enabled and the URL is correct for their project.
select
net.http_post(
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The Supabase project URL is hardcoded in this trigger function. This prevents the migration from working correctly on other projects or local environments. It is better to use a relative path if supported by the environment or to store the base URL in a configuration table that can be updated per environment.

Comment thread .env.development
# Use the HS256 ANON_KEY JWT — this is what Kong/PostgREST validates against JWT_SECRET
VITE_SUPABASE_PUBLISHABLE_KEY=your_jwt_here
VITE_SUPABASE_ANON_KEY=your_jwt_here
ANON_KEY_ASYMMETRIC=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImQxNTY1OWI5LTczNDEtNDQzMy05YzUwLTA3YWNmNDY2YjM5NiJ9.eyJyb2xlIjoiYW5vbiIsImlzcyI6InN1cGFiYXNlIiwiaWF0IjoxNzczNzU5NDA2LCJleHAiOjE5MzE0Mzk0MDZ9.Auf7cXNmliguyY4tQUZoFNkdy0Q0qfP0-iTN-FisgfmZR1Q9nJ_Rkv-iH0_B9oq4d8X64BzxZWDQbEpBNV2d3A
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-high high

Committing a hardcoded JWT (ANON_KEY_ASYMMETRIC) to the repository is a security risk. Secrets should be managed via environment variables that are not tracked in version control. Use a placeholder value here and provide instructions for local setup in a .env.example file.

Comment thread docker-compose.yml
- start
- --main-service
- /home/deno/functions/main
healthcheck:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The functions service points to /home/deno/functions/main, but no main function directory is provided in supabase/functions. This will likely cause the service to fail on startup. Verify if a main entry point is missing or if the path should point to one of the existing functions.

Comment thread deploy.sh
Comment on lines +131 to +166
apply_migrations() {
step "Applying DB migrations"
MIGRATIONS_DIR="${REPO_ROOT}/supabase/migrations"
[[ -d "$MIGRATIONS_DIR" ]] || { warn "No migrations dir — skipping"; return; }

# Create tracking table
docker exec "$DB_CONTAINER" psql -U postgres -d postgres -c "
CREATE TABLE IF NOT EXISTS _migration_log (
filename TEXT PRIMARY KEY,
applied_at TIMESTAMPTZ DEFAULT now()
);" >/dev/null 2>&1 || true

for f in "$MIGRATIONS_DIR"/*.sql; do
[[ -f "$f" ]] || continue
fname="$(basename "$f")"

already=$(docker exec "$DB_CONTAINER" psql -U postgres -d postgres -tAc \
"SELECT 1 FROM _migration_log WHERE filename = '$fname';" 2>/dev/null || echo "")

if [[ "$already" == "1" ]]; then
ok "Already applied: $fname"
continue
fi

echo -e " Applying: $fname"
if Get-Content "$f" | docker exec -i "$DB_CONTAINER" psql -U postgres -d postgres 2>&1; then
docker exec "$DB_CONTAINER" psql -U postgres -d postgres -c \
"INSERT INTO _migration_log(filename) VALUES ('$fname') ON CONFLICT DO NOTHING;" >/dev/null 2>&1 || true
ok "Applied: $fname"
else
warn "Migration $fname had errors (may be safe to ignore)"
fi
done
}

# Bash version of apply_migrations (uses cat instead of Get-Content)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The apply_migrations function is defined twice. The first definition (lines 131-164) is redundant and contains a bug: it uses the PowerShell command Get-Content on line 156, which is not valid in a Bash script. Since a correct implementation using cat is provided starting on line 167, the first definition and the preceding comment should be removed to avoid confusion and potential execution errors.

Comment thread analyze-sprites.cjs
Comment on lines +1 to +53
const fs = require('fs');

function analyzeSprite(filePath, name) {
const txt = fs.readFileSync(filePath, 'utf8');
console.log('\n========== ' + name + ' ==========');

// Extract SVG root dimensions
const rootM = txt.match(/<svg[^>]*width="([^"]+)"[^>]*height="([^"]+)"/);
if (rootM) console.log('Size: ' + rootM[1] + ' x ' + rootM[2]);

// Extract all clipPath rects / paths
const clipRects = [...txt.matchAll(/<clipPath[^>]*id="([^"]+)"[^>]*>[\s\S]*?<(?:rect|path)[^>]*(?:x="([^"]*)"[^>]*y="([^"]*)"[^>]*width="([^"]*)"[^>]*height="([^"]*)"[^>]*|d="M([0-9.]+)\s+([0-9.]+)h([0-9.]+)v([0-9.]+)[^"]*")[^>]*\/?>[\s\S]*?<\/clipPath>/g)];
if (clipRects.length) {
console.log('ClipPath rects (' + clipRects.length + '):');
clipRects.forEach(m => {
if (m[2]) console.log(' id=' + m[1] + ' x=' + m[2] + ' y=' + m[3] + ' w=' + m[4] + ' h=' + m[5]);
else if (m[6]) console.log(' id=' + m[1] + ' M=' + m[6] + ',' + m[7] + ' w=' + m[8] + ' h=' + m[9]);
});
}

// Extract all mask rects
const maskRects = [...txt.matchAll(/<mask[^>]*id="([^"]+)"[^>]*>[\s\S]*?<(?:rect|path)[^>]*(?:x="([^"]*)"[^>]*y="([^"]*)"[^>]*width="([^"]*)"[^>]*height="([^"]*)"[^>]*|d="M([0-9.-]+)\s+([0-9.-]+)[^"]*w\s*=\s*"([^"]*)"[^>]*h\s*=\s*"([^"]*)"[^"]*")[^>]*\/?>[\s\S]*?<\/mask>/g)];
if (maskRects.length) {
console.log('Mask rects (' + maskRects.length + '):');
maskRects.forEach(m => {
if (m[2]) console.log(' id=' + m[1] + ' x=' + m[2] + ' y=' + m[3] + ' w=' + m[4] + ' h=' + m[5]);
});
}

// Simpler: just find all rect elements in defs with x,y,width,height
const allRects = [...txt.matchAll(/<rect[^>]*x="([0-9.-]+)"[^>]*y="([0-9.-]+)"[^>]*width="([0-9.-]+)"[^>]*height="([0-9.-]+)"/g)];
console.log('All rects with x,y,w,h (' + allRects.length + '):');
allRects.forEach(m => console.log(' x=' + m[1] + ' y=' + m[2] + ' w=' + m[3] + ' h=' + m[4]));

// Find all absolute M commands in path data (indicator of icon corners)
const Ms = [...txt.matchAll(/(?:^|[\s,])M\s*([0-9.]+)\s+([0-9.]+)/g)];
const unique = {};
Ms.forEach(m => {
const x = Math.floor(parseFloat(m[1]));
const y = Math.floor(parseFloat(m[2]));
const key = x + '_' + y;
if (!unique[key]) unique[key] = {x, y, count: 0};
unique[key].count++;
});
const sorted = Object.values(unique).sort((a,b) => a.y-b.y || a.x-b.x);
// Only show coords with large round values (likely icon grid corners)
const corners = sorted.filter(p => p.count >= 2 && p.x % 1 === 0 && p.y % 1 === 0 && (p.x === 0 || p.x > 20));
console.log('Likely icon corners (M cmds, count>=2): ' + corners.length);
corners.slice(0, 30).forEach(p => console.log(' x=' + p.x + ' y=' + p.y + ' count=' + p.count));
}

analyzeSprite('src/assets/some-silo-sprite.svg', 'some-silo-sprite.svg');
analyzeSprite('src/assets/common-header-sprite.svg', 'common-header-sprite.svg');
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

This file is identical to analyze-sprites.js. Duplicate files for the same logic increase maintenance burden and can lead to inconsistencies if one is updated while the other is not. Please remove one of them.

Comment thread analyze-sprites.js
Comment on lines +52 to +53
analyzeSprite('src/assets/some-silo-sprite.svg', 'some-silo-sprite.svg');
analyzeSprite('src/assets/common-header-sprite.svg', 'common-header-sprite.svg');
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The script attempts to analyze some-silo-sprite.svg and common-header-sprite.svg, but these files are not included in the repository changes. This will cause the script to crash when run. Ensure the target files exist or update the script to accept file paths as arguments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant