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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
100 changes: 86 additions & 14 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,16 @@ jobs:
NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}
SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.SUPABASE_SERVICE_ROLE_KEY }}
REDIS_URL: ${{ secrets.REDIS_URL }}

- name: Analyze bundle size
run: npm run build:analyze
env:
NODE_ENV: production
NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}
SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.SUPABASE_SERVICE_ROLE_KEY }}
REDIS_URL: ${{ secrets.REDIS_URL }}

- name: Upload build artifacts
uses: actions/upload-artifact@v4
Expand Down Expand Up @@ -183,6 +190,7 @@ jobs:
NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}
SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.SUPABASE_SERVICE_ROLE_KEY }}
REDIS_URL: ${{ secrets.REDIS_URL }}

- name: Wait for app to be ready
run: |
Expand Down Expand Up @@ -314,6 +322,7 @@ jobs:
NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}
SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.SUPABASE_SERVICE_ROLE_KEY }}
REDIS_URL: ${{ secrets.REDIS_URL }}

- name: Deploy to Vercel (Staging)
id: deploy-staging
Expand Down Expand Up @@ -439,6 +448,7 @@ jobs:
NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}
SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.SUPABASE_SERVICE_ROLE_KEY }}
REDIS_URL: ${{ secrets.REDIS_URL }}

- name: Deploy to Vercel (Production)
id: deploy-production
Expand Down Expand Up @@ -592,16 +602,33 @@ jobs:

- name: Create Lighthouse configuration for deployed site
run: |
cat > lighthouserc-deployed.js << 'EOF'
# Get the deployment URL from the previous step
DEPLOYMENT_URL="${{ needs.deploy-production.outputs.deployment-url }}"

# Validate deployment URL
if [ -z "$DEPLOYMENT_URL" ]; then
echo "❌ Deployment URL is empty, using fallback URL"
DEPLOYMENT_URL="${{ secrets.PRODUCTION_URL }}"
fi

# Ensure URL has protocol
if [[ ! "$DEPLOYMENT_URL" =~ ^https?:// ]]; then
echo "⚠️ Adding https:// protocol to URL: $DEPLOYMENT_URL"
DEPLOYMENT_URL="https://$DEPLOYMENT_URL"
fi

echo "πŸ” Using deployment URL for Lighthouse: $DEPLOYMENT_URL"

cat > lighthouserc-deployed.js << EOF
module.exports = {
ci: {
collect: {
url: [
'${{ needs.deploy-production.outputs.deployment-url }}/',
'${{ needs.deploy-production.outputs.deployment-url }}/about',
'${{ needs.deploy-production.outputs.deployment-url }}/hackathons',
'${{ needs.deploy-production.outputs.deployment-url }}/leaderboard',
'${{ needs.deploy-production.outputs.deployment-url }}/auth/signin'
'${DEPLOYMENT_URL}/',
'${DEPLOYMENT_URL}/about',
'${DEPLOYMENT_URL}/hackathons',
'${DEPLOYMENT_URL}/leaderboard',
'${DEPLOYMENT_URL}/auth/signin'
],
numberOfRuns: 3,
settings: {
Expand Down Expand Up @@ -653,7 +680,21 @@ jobs:
- name: Run Lighthouse CI on deployed site
run: |
echo "πŸš€ Starting Lighthouse CI performance testing..."
echo "Testing URL: ${{ needs.deploy-production.outputs.deployment-url }}"

# Get the deployment URL
DEPLOYMENT_URL="${{ needs.deploy-production.outputs.deployment-url }}"
if [ -z "$DEPLOYMENT_URL" ]; then
DEPLOYMENT_URL="${{ secrets.PRODUCTION_URL }}"
fi

echo "Testing URL: $DEPLOYMENT_URL"

# Validate that we have a URL before running Lighthouse
if [ -z "$DEPLOYMENT_URL" ]; then
echo "❌ No deployment URL available for Lighthouse testing"
echo "Skipping Lighthouse CI test"
exit 0
fi

# Run Lighthouse CI with the deployed configuration
lhci autorun --config=lighthouserc-deployed.js
Expand Down Expand Up @@ -710,16 +751,33 @@ jobs:

- name: Create Lighthouse configuration for staging
run: |
cat > lighthouserc-staging.js << 'EOF'
# Get the deployment URL from the previous step
DEPLOYMENT_URL="${{ needs.deploy-staging.outputs.deployment-url }}"

# Validate deployment URL
if [ -z "$DEPLOYMENT_URL" ]; then
echo "❌ Staging deployment URL is empty, using fallback URL"
DEPLOYMENT_URL="${{ secrets.STAGING_URL }}"
fi

# Ensure URL has protocol
if [[ ! "$DEPLOYMENT_URL" =~ ^https?:// ]]; then
echo "⚠️ Adding https:// protocol to staging URL: $DEPLOYMENT_URL"
DEPLOYMENT_URL="https://$DEPLOYMENT_URL"
fi

echo "πŸ” Using staging deployment URL for Lighthouse: $DEPLOYMENT_URL"

cat > lighthouserc-staging.js << EOF
module.exports = {
ci: {
collect: {
url: [
'${{ needs.deploy-staging.outputs.deployment-url }}/',
'${{ needs.deploy-staging.outputs.deployment-url }}/about',
'${{ needs.deploy-staging.outputs.deployment-url }}/hackathons',
'${{ needs.deploy-staging.outputs.deployment-url }}/leaderboard',
'${{ needs.deploy-staging.outputs.deployment-url }}/auth/signin'
'${DEPLOYMENT_URL}/',
'${DEPLOYMENT_URL}/about',
'${DEPLOYMENT_URL}/hackathons',
'${DEPLOYMENT_URL}/leaderboard',
'${DEPLOYMENT_URL}/auth/signin'
],
numberOfRuns: 2,
settings: {
Expand Down Expand Up @@ -765,7 +823,21 @@ jobs:
- name: Run Lighthouse CI on staging site
run: |
echo "πŸš€ Starting Lighthouse CI performance testing on staging..."
echo "Testing URL: ${{ needs.deploy-staging.outputs.deployment-url }}"

# Get the deployment URL
DEPLOYMENT_URL="${{ needs.deploy-staging.outputs.deployment-url }}"
if [ -z "$DEPLOYMENT_URL" ]; then
DEPLOYMENT_URL="${{ secrets.STAGING_URL }}"
fi

echo "Testing URL: $DEPLOYMENT_URL"

# Validate that we have a URL before running Lighthouse
if [ -z "$DEPLOYMENT_URL" ]; then
echo "❌ No staging deployment URL available for Lighthouse testing"
echo "Skipping Lighthouse CI test"
exit 0
fi

# Run Lighthouse CI with the staging configuration
lhci autorun --config=lighthouserc-staging.js
Expand Down
4 changes: 4 additions & 0 deletions app/api/admin-collaboration/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { NextResponse } from "next/server";
import { createClient } from "@supabase/supabase-js";

// Force Node.js runtime for API routes
export const runtime = 'nodejs';


// Create Supabase client function to avoid build-time initialization
function getSupabaseClient() {
return createClient(
Expand Down
4 changes: 4 additions & 0 deletions app/api/admin-judges/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { NextResponse } from "next/server";
import { createClient } from "@supabase/supabase-js";

// Force Node.js runtime for API routes
export const runtime = 'nodejs';


// Create Supabase client function to avoid build-time initialization
function getSupabaseClient() {
return createClient(
Expand Down
4 changes: 4 additions & 0 deletions app/api/admin-mentors/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { NextResponse } from "next/server";
import { createClient } from "@supabase/supabase-js";

// Force Node.js runtime for API routes
export const runtime = 'nodejs';


// Create Supabase client function to avoid build-time initialization
function getSupabaseClient() {
return createClient(
Expand Down
6 changes: 5 additions & 1 deletion app/api/admin-page-views/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { NextResponse } from 'next/server';
import { createClient } from '@/lib/supabase/server';

// Force Node.js runtime for API routes
export const runtime = 'nodejs';


export async function GET() {
const supabase = await createClient();
const { data, error } = await supabase
Expand All @@ -11,6 +15,6 @@ export async function GET() {
return NextResponse.json({ error: error.message }, { status: 500 });
}

const totalViews = (data || []).reduce((sum, blog) => sum + (blog.views || 0), 0);
const totalViews = (data || []).reduce((sum: number, blog: any) => sum + (blog.views || 0), 0);
return NextResponse.json({ totalViews });
}
4 changes: 4 additions & 0 deletions app/api/admin-sponsorship/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { NextResponse } from "next/server";
import { createClient } from "@supabase/supabase-js";

// Force Node.js runtime for API routes
export const runtime = 'nodejs';


// Create Supabase client function to avoid build-time initialization
function getSupabaseClient() {
return createClient(
Expand Down
4 changes: 4 additions & 0 deletions app/api/admin-users/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { NextResponse } from "next/server";
import { createClient } from "@supabase/supabase-js";

// Force Node.js runtime for API routes
export const runtime = 'nodejs';


// Create Supabase client function to avoid build-time initialization
function getSupabaseClient() {
return createClient(
Expand Down
4 changes: 4 additions & 0 deletions app/api/admin-volunteers/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { NextResponse } from "next/server";
import { createClient } from "@supabase/supabase-js";

// Force Node.js runtime for API routes
export const runtime = 'nodejs';


// Create Supabase client function to avoid build-time initialization
function getSupabaseClient() {
return createClient(
Expand Down
4 changes: 4 additions & 0 deletions app/api/admin/audit-logs/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { NextRequest, NextResponse } from 'next/server';
import { withAdminAuth, AuthenticatedUser } from '@/lib/auth/admin-auth';
import { createAuditLogger, AuditLogFilter, AuditActionType } from '@/lib/services/audit-logger';

// Force Node.js runtime for API routes
export const runtime = 'nodejs';


/**
* GET /api/admin/audit-logs
* Retrieve audit logs with filtering and pagination
Expand Down
4 changes: 4 additions & 0 deletions app/api/admin/audit-logs/stats/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { NextRequest, NextResponse } from 'next/server';
import { withAdminAuth, AuthenticatedUser } from '@/lib/auth/admin-auth';
import { createAuditLogger } from '@/lib/services/audit-logger';

// Force Node.js runtime for API routes
export const runtime = 'nodejs';


/**
* GET /api/admin/audit-logs/stats
* Get audit log statistics
Expand Down
4 changes: 4 additions & 0 deletions app/api/admin/backup/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import { authenticateAdmin } from '@/lib/auth/admin-auth';
import { withRateLimit } from '@/lib/security/rate-limiting';
import { RateLimitConfigs } from '@/lib/security/rate-limiting';

// Force Node.js runtime for API routes
export const runtime = 'nodejs';


export async function GET(request: NextRequest) {
try {
// Authenticate admin user
Expand Down
4 changes: 4 additions & 0 deletions app/api/admin/cache-analytics/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { NextRequest } from 'next/server'
import { UnifiedCache } from '@/lib/unified-cache-system'

// Force Node.js runtime for API routes
export const runtime = 'nodejs';


/**
* API endpoint for cache analytics - Admin only
*
Expand Down
4 changes: 4 additions & 0 deletions app/api/admin/cache-invalidate/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { NextRequest } from 'next/server'
import { cacheAnalytics } from '@/lib/cache-analytics-server'
import { UnifiedCache } from '@/lib/unified-cache-system'

// Force Node.js runtime for API routes
export const runtime = 'nodejs';


/**
* API endpoint to trigger manual cache invalidation - Admin only
*/
Expand Down
4 changes: 4 additions & 0 deletions app/api/admin/cache-management/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import { NextRequest } from 'next/server'
import { handleCachePurgeWebhook, CacheManager } from '@/lib/cloudflare-cache-purge'
import { UnifiedCache } from '@/lib/unified-cache-system'

// Force Node.js runtime for API routes
export const runtime = 'nodejs';


// eslint-disable-next-line @typescript-eslint/no-unused-vars
export async function GET(_request: NextRequest) {
try {
Expand Down
4 changes: 4 additions & 0 deletions app/api/admin/cache-test-data/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { NextRequest } from 'next/server'
import { cacheAnalytics } from '@/lib/cache-analytics-server'
import { UnifiedCache } from '@/lib/unified-cache-system'

// Force Node.js runtime for API routes
export const runtime = 'nodejs';


const routes = [
'/api/hackathons',
'/api/users/profile',
Expand Down
4 changes: 4 additions & 0 deletions app/api/admin/certificates/data/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { NextResponse } from 'next/server';
import { createClient } from '@supabase/supabase-js';

// Force Node.js runtime for API routes
export const runtime = 'nodejs';


// Create Supabase client function to avoid build-time initialization
function getSupabaseClient() {
return createClient(
Expand Down
4 changes: 4 additions & 0 deletions app/api/admin/certificates/participants/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { NextResponse } from 'next/server';
import { createClient } from '@supabase/supabase-js';

// Force Node.js runtime for API routes
export const runtime = 'nodejs';


// Create Supabase client function to avoid build-time initialization
function getSupabaseClient() {
return createClient(
Expand Down
4 changes: 4 additions & 0 deletions app/api/admin/certificates/save/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { NextRequest, NextResponse } from 'next/server';
import { createClient } from '@supabase/supabase-js';

// Force Node.js runtime for API routes
export const runtime = 'nodejs';


// Create Supabase client function to avoid build-time initialization
function getSupabaseClient() {
return createClient(
Expand Down
4 changes: 4 additions & 0 deletions app/api/admin/check-status/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { NextResponse } from 'next/server';
import { createClient } from '@/lib/supabase/server';
import { ErrorSanitizer } from '@/lib/security/error-sanitizer';

// Force Node.js runtime for API routes
export const runtime = 'nodejs';


export async function GET() {
try {
const supabase = await createClient();
Expand Down
4 changes: 4 additions & 0 deletions app/api/admin/events/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { NextRequest, NextResponse } from 'next/server'
import { createClient, createServiceClient } from '@/lib/supabase/server'

// Force Node.js runtime for API routes
export const runtime = 'nodejs';


// GET - Fetch all events (admin only)
export async function GET(request: NextRequest) {
try {
Expand Down
4 changes: 4 additions & 0 deletions app/api/admin/hackathons/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { NextRequest, NextResponse } from 'next/server'
import { hackathonsService } from '@/lib/services/hackathons'
import { createClient } from '@/lib/supabase/server'

// Force Node.js runtime for API routes
export const runtime = 'nodejs';


// GET - Fetch all hackathons (admin only)
export async function GET(request: NextRequest) {
try {
Expand Down
Loading
Loading