KrishnaCosmic commited on
Commit
e9b2cbc
·
1 Parent(s): 78e893f

apply changes

Browse files
src/app/api/auth/github/callback/route.ts CHANGED
@@ -57,6 +57,7 @@ export async function GET(request: NextRequest) {
57
  const githubUser = await userResponse.json();
58
 
59
  // Check if user exists
 
60
  const existingUsers = await db
61
  .select({
62
  id: users.id,
@@ -65,9 +66,6 @@ export async function GET(request: NextRequest) {
65
  avatarUrl: users.avatarUrl,
66
  role: users.role,
67
  githubAccessToken: users.githubAccessToken,
68
- syncStatus: users.syncStatus,
69
- lastSyncAt: users.lastSyncAt,
70
- syncError: users.syncError,
71
  createdAt: users.createdAt,
72
  updatedAt: users.updatedAt,
73
  })
 
57
  const githubUser = await userResponse.json();
58
 
59
  // Check if user exists
60
+ // NOTE: sync_status columns excluded until Turso migration is applied
61
  const existingUsers = await db
62
  .select({
63
  id: users.id,
 
66
  avatarUrl: users.avatarUrl,
67
  role: users.role,
68
  githubAccessToken: users.githubAccessToken,
 
 
 
69
  createdAt: users.createdAt,
70
  updatedAt: users.updatedAt,
71
  })
src/app/api/sync/run/route.ts CHANGED
@@ -7,9 +7,6 @@
7
 
8
  import { NextRequest, NextResponse } from "next/server";
9
  import { getCurrentUser } from "@/lib/auth";
10
- import { db } from "@/db";
11
- import { users } from "@/db/schema";
12
- import { eq } from "drizzle-orm";
13
  import { runMaintainerSync, runContributorSync, syncContributorPRsDirect, reconcileOpenTriageIssue1 } from "@/lib/sync/github-sync";
14
 
15
  const SYNC_INTERVAL_MS = 5 * 60 * 1000; // 5 minutes
@@ -29,7 +26,7 @@ export async function POST(request: NextRequest) {
29
  return NextResponse.json({ error: "GitHub access token not found" }, { status: 400 });
30
  }
31
 
32
- // Layer 2 Defense: In-memory check (FAST - prevents race conditions)
33
  if (activeSyncs.has(user.id)) {
34
  console.log(`[SyncRun] User ${user.id} sync blocked by in-memory guard`);
35
  return NextResponse.json({
@@ -39,56 +36,13 @@ export async function POST(request: NextRequest) {
39
  }, { status: 429 });
40
  }
41
 
42
- // Layer 1 Defense: Database check (PERSISTENT - survives restarts)
43
- const userRecord = await db.select({
44
- id: users.id,
45
- syncStatus: users.syncStatus,
46
- lastSyncAt: users.lastSyncAt,
47
- })
48
- .from(users)
49
- .where(eq(users.id, user.id))
50
- .limit(1);
51
-
52
- if (!userRecord || userRecord.length === 0) {
53
- return NextResponse.json({ error: "User not found" }, { status: 404 });
54
- }
55
-
56
- const currentSyncStatus = userRecord[0].syncStatus;
57
-
58
- // Circuit breaker: Check if sync already in progress
59
- if (currentSyncStatus === 'SYNCING') {
60
- console.log(`[SyncRun] User ${user.id} sync already in progress (DB status)`);
61
- return NextResponse.json({
62
- error: "Sync already in progress",
63
- status: "SYNCING",
64
- message: "Please wait for the current sync to complete"
65
- }, { status: 429 });
66
- }
67
-
68
- if (currentSyncStatus === 'PENDING') {
69
- console.log(`[SyncRun] User ${user.id} sync is pending`);
70
- return NextResponse.json({
71
- error: "Sync is queued",
72
- status: "PENDING",
73
- message: "Sync request is queued and will start shortly"
74
- }, { status: 202 });
75
- }
76
-
77
- // Add to in-memory set FIRST (before DB update)
78
  activeSyncs.add(user.id);
79
  console.log(`[SyncRun] Added user ${user.id} to activeSyncs. Size: ${activeSyncs.size}`);
80
 
81
- // Set database status to SYNCING
82
- await db.update(users)
83
- .set({
84
- syncStatus: 'SYNCING',
85
- syncError: null
86
- })
87
- .where(eq(users.id, user.id));
88
-
89
- console.log(`[SyncRun] Starting sync for user ${user.id}`);
90
-
91
  try {
 
 
92
  // Determine sync type based on user role
93
  const userRole = user.role?.toUpperCase();
94
  let stats;
@@ -109,13 +63,6 @@ export async function POST(request: NextRequest) {
109
  // Always reconcile the critical openTriage#1 issue to ensure immediate state sync
110
  const reconcileResult = await reconcileOpenTriageIssue1(user.githubAccessToken);
111
 
112
- // Mark sync as COMPLETED
113
- await db.update(users).set({
114
- syncStatus: 'COMPLETED',
115
- lastSyncAt: new Date().toISOString(),
116
- syncError: null
117
- }).where(eq(users.id, user.id));
118
-
119
  console.log(`[SyncRun] Sync completed for user ${user.id}`);
120
 
121
  return NextResponse.json({
@@ -133,12 +80,6 @@ export async function POST(request: NextRequest) {
133
  } catch (syncError: any) {
134
  console.error(`[SyncRun] Error syncing for user ${user.id}:`, syncError);
135
 
136
- // Mark sync as FAILED with error message
137
- await db.update(users).set({
138
- syncStatus: 'FAILED',
139
- syncError: syncError.message || 'Unknown error'
140
- }).where(eq(users.id, user.id));
141
-
142
  return NextResponse.json({
143
  error: "Sync failed",
144
  message: syncError.message || "Internal server error"
 
7
 
8
  import { NextRequest, NextResponse } from "next/server";
9
  import { getCurrentUser } from "@/lib/auth";
 
 
 
10
  import { runMaintainerSync, runContributorSync, syncContributorPRsDirect, reconcileOpenTriageIssue1 } from "@/lib/sync/github-sync";
11
 
12
  const SYNC_INTERVAL_MS = 5 * 60 * 1000; // 5 minutes
 
26
  return NextResponse.json({ error: "GitHub access token not found" }, { status: 400 });
27
  }
28
 
29
+ // Circuit Breaker: In-memory check (prevents concurrent syncs per user)
30
  if (activeSyncs.has(user.id)) {
31
  console.log(`[SyncRun] User ${user.id} sync blocked by in-memory guard`);
32
  return NextResponse.json({
 
36
  }, { status: 429 });
37
  }
38
 
39
+ // Add to in-memory set BEFORE starting sync
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  activeSyncs.add(user.id);
41
  console.log(`[SyncRun] Added user ${user.id} to activeSyncs. Size: ${activeSyncs.size}`);
42
 
 
 
 
 
 
 
 
 
 
 
43
  try {
44
+ console.log(`[SyncRun] Starting sync for user ${user.id}`);
45
+
46
  // Determine sync type based on user role
47
  const userRole = user.role?.toUpperCase();
48
  let stats;
 
63
  // Always reconcile the critical openTriage#1 issue to ensure immediate state sync
64
  const reconcileResult = await reconcileOpenTriageIssue1(user.githubAccessToken);
65
 
 
 
 
 
 
 
 
66
  console.log(`[SyncRun] Sync completed for user ${user.id}`);
67
 
68
  return NextResponse.json({
 
80
  } catch (syncError: any) {
81
  console.error(`[SyncRun] Error syncing for user ${user.id}:`, syncError);
82
 
 
 
 
 
 
 
83
  return NextResponse.json({
84
  error: "Sync failed",
85
  message: syncError.message || "Internal server error"
src/app/api/sync/status/route.ts CHANGED
@@ -2,50 +2,22 @@
2
  * Sync Status API Route
3
  *
4
  * GET /api/sync/status - Check current sync status for the authenticated user
5
- * Used by frontend to poll sync progress without triggering new syncs
 
6
  */
7
 
8
- import { NextRequest, NextResponse } from "next/server";
9
- import { getCurrentUser } from "@/lib/auth";
10
- import { db } from "@/db";
11
- import { users } from "@/db/schema";
12
- import { eq } from "drizzle-orm";
13
 
14
- export async function GET(request: NextRequest) {
15
- try {
16
- const user = await getCurrentUser(request);
17
- if (!user) {
18
- return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
19
- }
20
-
21
- // Get user's sync status
22
- const userRecord = await db.select({
23
- syncStatus: users.syncStatus,
24
- lastSyncAt: users.lastSyncAt,
25
- syncError: users.syncError,
26
- })
27
- .from(users)
28
- .where(eq(users.id, user.id))
29
- .limit(1);
30
-
31
- if (!userRecord || userRecord.length === 0) {
32
- return NextResponse.json({ error: "User not found" }, { status: 404 });
33
- }
34
-
35
- const { syncStatus, lastSyncAt, syncError } = userRecord[0];
36
-
37
- return NextResponse.json({
38
- status: syncStatus || 'IDLE',
39
- lastSyncAt: lastSyncAt || null,
40
- error: syncError || null,
41
- isIdle: syncStatus === 'IDLE' || syncStatus === 'COMPLETED',
42
- isSyncing: syncStatus === 'SYNCING',
43
- isPending: syncStatus === 'PENDING',
44
- hasFailed: syncStatus === 'FAILED',
45
- });
46
-
47
- } catch (error) {
48
- console.error("GET /api/sync/status error:", error);
49
- return NextResponse.json({ error: "Internal server error" }, { status: 500 });
50
- }
51
  }
 
2
  * Sync Status API Route
3
  *
4
  * GET /api/sync/status - Check current sync status for the authenticated user
5
+ * DISABLED: sync_status columns not yet migrated in Turso database
6
+ * Re-enable after running: turso db shell <db-name> < src/db/migrations/add_sync_status.sql
7
  */
8
 
9
+ import { NextResponse } from "next/server";
 
 
 
 
10
 
11
+ export async function GET() {
12
+ // Temporarily return IDLE since sync_status columns don't exist in DB yet
13
+ return NextResponse.json({
14
+ status: 'IDLE',
15
+ lastSyncAt: null,
16
+ error: null,
17
+ isIdle: true,
18
+ isSyncing: false,
19
+ isPending: false,
20
+ hasFailed: false,
21
+ message: 'Sync status tracking will be available after database migration'
22
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  }
src/db/schema.ts CHANGED
@@ -39,10 +39,11 @@ export const users = sqliteTable("users", {
39
  role: text("role"), // email: text("email"),
40
  githubAccessToken: text("github_access_token"),
41
 
42
- // Sync status tracking (Phase 2) - Re-enabled after Turso migration
43
- syncStatus: text("sync_status").default("IDLE"), // IDLE | PENDING | SYNCING | COMPLETED | FAILED
44
- lastSyncAt: text("last_sync_at"), // ISO timestamp
45
- syncError: text("sync_error"), // Error message if failed
 
46
 
47
  createdAt: text("created_at").notNull(),
48
  updatedAt: text("updated_at").notNull(),
 
39
  role: text("role"), // email: text("email"),
40
  githubAccessToken: text("github_access_token"),
41
 
42
+ // Sync status tracking (Phase 2) - DISABLED until Turso migration is applied
43
+ // Run: turso db shell <db-name> < src/db/migrations/add_sync_status.sql
44
+ // syncStatus: text("sync_status").default("IDLE"), // IDLE | PENDING | SYNCING | COMPLETED | FAILED
45
+ // lastSyncAt: text("last_sync_at"), // ISO timestamp
46
+ // syncError: text("sync_error"), // Error message if failed
47
 
48
  createdAt: text("created_at").notNull(),
49
  updatedAt: text("updated_at").notNull(),
src/lib/auth.ts CHANGED
@@ -66,6 +66,7 @@ export async function getCurrentUser(request: NextRequest) {
66
  console.log("[getCurrentUser] Token verified, user_id:", payload.user_id);
67
 
68
  // Fetch full user from database
 
69
  const userRecords = await db
70
  .select({
71
  id: users.id,
@@ -74,9 +75,6 @@ export async function getCurrentUser(request: NextRequest) {
74
  avatarUrl: users.avatarUrl,
75
  role: users.role,
76
  githubAccessToken: users.githubAccessToken,
77
- syncStatus: users.syncStatus,
78
- lastSyncAt: users.lastSyncAt,
79
- syncError: users.syncError,
80
  createdAt: users.createdAt,
81
  updatedAt: users.updatedAt,
82
  })
 
66
  console.log("[getCurrentUser] Token verified, user_id:", payload.user_id);
67
 
68
  // Fetch full user from database
69
+ // NOTE: sync_status columns excluded until Turso migration is applied
70
  const userRecords = await db
71
  .select({
72
  id: users.id,
 
75
  avatarUrl: users.avatarUrl,
76
  role: users.role,
77
  githubAccessToken: users.githubAccessToken,
 
 
 
78
  createdAt: users.createdAt,
79
  updatedAt: users.updatedAt,
80
  })