@realtimex/folio 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/.env.example +20 -0
  2. package/README.md +63 -0
  3. package/api/server.ts +130 -0
  4. package/api/src/config/index.ts +96 -0
  5. package/api/src/middleware/auth.ts +128 -0
  6. package/api/src/middleware/errorHandler.ts +88 -0
  7. package/api/src/middleware/index.ts +4 -0
  8. package/api/src/middleware/rateLimit.ts +71 -0
  9. package/api/src/middleware/validation.ts +58 -0
  10. package/api/src/routes/accounts.ts +142 -0
  11. package/api/src/routes/baseline-config.ts +124 -0
  12. package/api/src/routes/chat.ts +154 -0
  13. package/api/src/routes/health.ts +61 -0
  14. package/api/src/routes/index.ts +35 -0
  15. package/api/src/routes/ingestions.ts +275 -0
  16. package/api/src/routes/migrate.ts +112 -0
  17. package/api/src/routes/policies.ts +121 -0
  18. package/api/src/routes/processing.ts +90 -0
  19. package/api/src/routes/rules.ts +11 -0
  20. package/api/src/routes/sdk.ts +100 -0
  21. package/api/src/routes/settings.ts +80 -0
  22. package/api/src/routes/setup.ts +389 -0
  23. package/api/src/routes/stats.ts +81 -0
  24. package/api/src/routes/tts.ts +190 -0
  25. package/api/src/services/BaselineConfigService.ts +208 -0
  26. package/api/src/services/ChatService.ts +204 -0
  27. package/api/src/services/GoogleDriveService.ts +331 -0
  28. package/api/src/services/GoogleSheetsService.ts +1107 -0
  29. package/api/src/services/IngestionService.ts +1187 -0
  30. package/api/src/services/ModelCapabilityService.ts +248 -0
  31. package/api/src/services/PolicyEngine.ts +1625 -0
  32. package/api/src/services/PolicyLearningService.ts +527 -0
  33. package/api/src/services/PolicyLoader.ts +249 -0
  34. package/api/src/services/RAGService.ts +391 -0
  35. package/api/src/services/SDKService.ts +249 -0
  36. package/api/src/services/supabase.ts +113 -0
  37. package/api/src/utils/Actuator.ts +284 -0
  38. package/api/src/utils/actions/ActionHandler.ts +34 -0
  39. package/api/src/utils/actions/AppendToGSheetAction.ts +260 -0
  40. package/api/src/utils/actions/AutoRenameAction.ts +58 -0
  41. package/api/src/utils/actions/CopyAction.ts +120 -0
  42. package/api/src/utils/actions/CopyToGDriveAction.ts +64 -0
  43. package/api/src/utils/actions/LogCsvAction.ts +48 -0
  44. package/api/src/utils/actions/NotifyAction.ts +39 -0
  45. package/api/src/utils/actions/RenameAction.ts +57 -0
  46. package/api/src/utils/actions/WebhookAction.ts +58 -0
  47. package/api/src/utils/actions/utils.ts +293 -0
  48. package/api/src/utils/llmResponse.ts +61 -0
  49. package/api/src/utils/logger.ts +67 -0
  50. package/bin/folio-deploy.js +12 -0
  51. package/bin/folio-setup.js +45 -0
  52. package/bin/folio.js +65 -0
  53. package/dist/api/server.js +106 -0
  54. package/dist/api/src/config/index.js +81 -0
  55. package/dist/api/src/middleware/auth.js +93 -0
  56. package/dist/api/src/middleware/errorHandler.js +73 -0
  57. package/dist/api/src/middleware/index.js +4 -0
  58. package/dist/api/src/middleware/rateLimit.js +43 -0
  59. package/dist/api/src/middleware/validation.js +54 -0
  60. package/dist/api/src/routes/accounts.js +110 -0
  61. package/dist/api/src/routes/baseline-config.js +91 -0
  62. package/dist/api/src/routes/chat.js +114 -0
  63. package/dist/api/src/routes/health.js +52 -0
  64. package/dist/api/src/routes/index.js +31 -0
  65. package/dist/api/src/routes/ingestions.js +207 -0
  66. package/dist/api/src/routes/migrate.js +91 -0
  67. package/dist/api/src/routes/policies.js +86 -0
  68. package/dist/api/src/routes/processing.js +75 -0
  69. package/dist/api/src/routes/rules.js +8 -0
  70. package/dist/api/src/routes/sdk.js +80 -0
  71. package/dist/api/src/routes/settings.js +68 -0
  72. package/dist/api/src/routes/setup.js +315 -0
  73. package/dist/api/src/routes/stats.js +62 -0
  74. package/dist/api/src/routes/tts.js +178 -0
  75. package/dist/api/src/services/BaselineConfigService.js +168 -0
  76. package/dist/api/src/services/ChatService.js +166 -0
  77. package/dist/api/src/services/GoogleDriveService.js +280 -0
  78. package/dist/api/src/services/GoogleSheetsService.js +795 -0
  79. package/dist/api/src/services/IngestionService.js +990 -0
  80. package/dist/api/src/services/ModelCapabilityService.js +179 -0
  81. package/dist/api/src/services/PolicyEngine.js +1353 -0
  82. package/dist/api/src/services/PolicyLearningService.js +397 -0
  83. package/dist/api/src/services/PolicyLoader.js +159 -0
  84. package/dist/api/src/services/RAGService.js +295 -0
  85. package/dist/api/src/services/SDKService.js +212 -0
  86. package/dist/api/src/services/supabase.js +72 -0
  87. package/dist/api/src/utils/Actuator.js +225 -0
  88. package/dist/api/src/utils/actions/ActionHandler.js +1 -0
  89. package/dist/api/src/utils/actions/AppendToGSheetAction.js +191 -0
  90. package/dist/api/src/utils/actions/AutoRenameAction.js +49 -0
  91. package/dist/api/src/utils/actions/CopyAction.js +112 -0
  92. package/dist/api/src/utils/actions/CopyToGDriveAction.js +55 -0
  93. package/dist/api/src/utils/actions/LogCsvAction.js +42 -0
  94. package/dist/api/src/utils/actions/NotifyAction.js +32 -0
  95. package/dist/api/src/utils/actions/RenameAction.js +51 -0
  96. package/dist/api/src/utils/actions/WebhookAction.js +51 -0
  97. package/dist/api/src/utils/actions/utils.js +237 -0
  98. package/dist/api/src/utils/llmResponse.js +63 -0
  99. package/dist/api/src/utils/logger.js +51 -0
  100. package/dist/assets/index-DzN8-j-e.css +1 -0
  101. package/dist/assets/index-Uy-ai3Dh.js +113 -0
  102. package/dist/favicon.svg +31 -0
  103. package/dist/folio-logo.svg +46 -0
  104. package/dist/index.html +14 -0
  105. package/docs-dev/FPE-spec.md +196 -0
  106. package/docs-dev/folio-prd.md +47 -0
  107. package/docs-dev/foundation-checklist.md +30 -0
  108. package/docs-dev/hybrid-routing-architecture.md +205 -0
  109. package/docs-dev/ingestion-engine.md +69 -0
  110. package/docs-dev/port-from-email-automator.md +32 -0
  111. package/docs-dev/tech-spec.md +98 -0
  112. package/index.html +13 -0
  113. package/package.json +101 -0
  114. package/public/favicon.svg +31 -0
  115. package/public/folio-logo.svg +46 -0
  116. package/scripts/dev-task.mjs +51 -0
  117. package/scripts/get-latest-migration-timestamp.mjs +34 -0
  118. package/scripts/migrate.sh +91 -0
  119. package/supabase/.temp/cli-latest +1 -0
  120. package/supabase/.temp/gotrue-version +1 -0
  121. package/supabase/.temp/pooler-url +1 -0
  122. package/supabase/.temp/postgres-version +1 -0
  123. package/supabase/.temp/project-ref +1 -0
  124. package/supabase/.temp/rest-version +1 -0
  125. package/supabase/.temp/storage-migration +1 -0
  126. package/supabase/.temp/storage-version +1 -0
  127. package/supabase/config.toml +64 -0
  128. package/supabase/functions/_shared/auth.ts +35 -0
  129. package/supabase/functions/_shared/cors.ts +12 -0
  130. package/supabase/functions/_shared/supabaseAdmin.ts +17 -0
  131. package/supabase/functions/api-v1-settings/index.ts +66 -0
  132. package/supabase/functions/setup/index.ts +91 -0
  133. package/supabase/migrations/20260223000000_initial_foundation.sql +136 -0
  134. package/supabase/migrations/20260223000001_add_migration_rpc.sql +10 -0
  135. package/supabase/migrations/20260224000002_add_init_state_view.sql +20 -0
  136. package/supabase/migrations/20260224000003_port_user_creation_parity.sql +139 -0
  137. package/supabase/migrations/20260224000004_add_avatars_storage.sql +26 -0
  138. package/supabase/migrations/20260224000005_add_tts_and_embed_settings.sql +24 -0
  139. package/supabase/migrations/20260224000006_add_policies_table.sql +48 -0
  140. package/supabase/migrations/20260224000007_fix_migration_rpc.sql +9 -0
  141. package/supabase/migrations/20260224000008_add_ingestions_table.sql +42 -0
  142. package/supabase/migrations/20260225000000_setup_compatible_mode.sql +119 -0
  143. package/supabase/migrations/20260225000001_restore_ingestions.sql +49 -0
  144. package/supabase/migrations/20260225000002_add_ingestion_trace.sql +2 -0
  145. package/supabase/migrations/20260225000003_add_baseline_configs.sql +35 -0
  146. package/supabase/migrations/20260226000000_add_processing_events.sql +26 -0
  147. package/supabase/migrations/20260226000001_add_ingestion_file_hash.sql +10 -0
  148. package/supabase/migrations/20260226000002_add_dynamic_rag.sql +150 -0
  149. package/supabase/migrations/20260226000003_add_ingestion_summary.sql +4 -0
  150. package/supabase/migrations/20260226000004_add_ingestion_tags.sql +7 -0
  151. package/supabase/migrations/20260226000005_add_chat_tables.sql +60 -0
  152. package/supabase/migrations/20260227000000_harden_chat_messages_rls.sql +25 -0
  153. package/supabase/migrations/20260228000000_add_vision_model_capabilities.sql +8 -0
  154. package/supabase/migrations/20260228000001_add_policy_match_feedback.sql +51 -0
  155. package/supabase/migrations/29991231235959_test_migration.sql +0 -0
  156. package/supabase/templates/confirmation.html +76 -0
  157. package/supabase/templates/email-change.html +76 -0
  158. package/supabase/templates/invite.html +72 -0
  159. package/supabase/templates/magic-link.html +68 -0
  160. package/supabase/templates/recovery.html +82 -0
  161. package/tsconfig.api.json +16 -0
  162. package/tsconfig.json +25 -0
  163. package/vite.config.ts +146 -0
@@ -0,0 +1,76 @@
1
+ <!doctype html>
2
+ <html>
3
+
4
+ <head>
5
+ <style>
6
+ body {
7
+ font-family: Arial, sans-serif;
8
+ background-color: #f4f4f4;
9
+ margin: 0;
10
+ padding: 0;
11
+ }
12
+
13
+ .container {
14
+ width: 100%;
15
+ max-width: 600px;
16
+ margin: 0 auto;
17
+ background-color: #ffffff;
18
+ padding: 20px;
19
+ border-radius: 8px;
20
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
21
+ }
22
+
23
+ .header {
24
+ text-align: center;
25
+ padding: 10px 0;
26
+ }
27
+
28
+ .header h2 {
29
+ margin: 0;
30
+ color: #333333;
31
+ }
32
+
33
+ .content {
34
+ padding: 20px;
35
+ line-height: 1.6;
36
+ color: #555555;
37
+ }
38
+
39
+ .content p {
40
+ margin: 0 0 10px;
41
+ }
42
+
43
+ .button {
44
+ display: block;
45
+ width: 200px;
46
+ margin: 20px auto;
47
+ padding: 10px;
48
+ text-align: center;
49
+ background-color: #007bff;
50
+ color: #ffffff !important;
51
+ text-decoration: none;
52
+ border-radius: 5px;
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body>
58
+ <div class="container">
59
+ <div class="header">
60
+ <h2>Confirm your new email address</h2>
61
+ </div>
62
+ <div class="content">
63
+ <p>Hello,</p>
64
+ <p>
65
+ You've requested to change your email address for Folio.
66
+ Please click the button below to confirm this change.
67
+ </p>
68
+ <p>
69
+ <a href="{{ .ConfirmationURL }}auth-callback.html" class="button">Confirm new email</a>
70
+ </p>
71
+ <p>The Folio team</p>
72
+ </div>
73
+ </div>
74
+ </body>
75
+
76
+ </html>
@@ -0,0 +1,72 @@
1
+ <!doctype html>
2
+ <html>
3
+
4
+ <head>
5
+ <style>
6
+ body {
7
+ font-family: Arial, sans-serif;
8
+ background-color: #f4f4f4;
9
+ margin: 0;
10
+ padding: 0;
11
+ }
12
+
13
+ .container {
14
+ width: 100%;
15
+ max-width: 600px;
16
+ margin: 0 auto;
17
+ background-color: #ffffff;
18
+ padding: 20px;
19
+ border-radius: 8px;
20
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
21
+ }
22
+
23
+ .content {
24
+ padding: 20px;
25
+ line-height: 1.6;
26
+ color: #555555;
27
+ }
28
+
29
+ .content p {
30
+ margin: 0 0 10px;
31
+ }
32
+
33
+ h2,
34
+ h3 {
35
+ color: #333333;
36
+ }
37
+ </style>
38
+ </head>
39
+
40
+ <body>
41
+ <div class="container">
42
+ <div class="content">
43
+ <h2>Welcome to Folio</h2>
44
+
45
+ <p>Hi there,</p>
46
+
47
+ <p>Your Folio account has been successfully created.</p>
48
+
49
+ <h3>How to Access Your Account</h3>
50
+
51
+ <ol style="line-height: 1.8">
52
+ <li>Open the Folio application.</li>
53
+ <li>Select <strong>"Login with Email Code (OTP)"</strong>.</li>
54
+ <li>Enter your email address: <strong>{{ .Email }}</strong>.</li>
55
+ <li>Check your inbox for a 6-digit verification code.</li>
56
+ <li>Enter the code in the app when prompted.</li>
57
+ <li>Create a password to complete setup.</li>
58
+ </ol>
59
+
60
+ <h3>Need Help?</h3>
61
+
62
+ <p>If you have any questions, please contact your administrator.</p>
63
+
64
+ <p style="color: #666; font-size: 12px">
65
+ If you did not request this account, please reach out to your
66
+ administrator immediately.
67
+ </p>
68
+ </div>
69
+ </div>
70
+ </body>
71
+
72
+ </html>
@@ -0,0 +1,68 @@
1
+ <!doctype html>
2
+ <html>
3
+
4
+ <head>
5
+ <style>
6
+ body {
7
+ font-family: Arial, sans-serif;
8
+ background-color: #f4f4f4;
9
+ margin: 0;
10
+ padding: 0;
11
+ }
12
+
13
+ .container {
14
+ width: 100%;
15
+ max-width: 600px;
16
+ margin: 0 auto;
17
+ background-color: #ffffff;
18
+ padding: 20px;
19
+ border-radius: 8px;
20
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
21
+ }
22
+
23
+ .content {
24
+ padding: 20px;
25
+ line-height: 1.6;
26
+ color: #555555;
27
+ }
28
+
29
+ .content p {
30
+ margin: 0 0 10px;
31
+ }
32
+
33
+ h2 {
34
+ color: #333333;
35
+ }
36
+
37
+ .otp-code {
38
+ font-size: 24px;
39
+ font-weight: bold;
40
+ letter-spacing: 4px;
41
+ color: #007bff;
42
+ margin: 20px 0;
43
+ text-align: center;
44
+ }
45
+ </style>
46
+ </head>
47
+
48
+ <body>
49
+ <div class="container">
50
+ <div class="content">
51
+ <h2>Folio Magic OTP</h2>
52
+
53
+ <p>Hi there,</p>
54
+
55
+ <p>Use the following verification code to log in to your account:</p>
56
+
57
+ <div class="otp-code">{{ .Token }}</div>
58
+
59
+ <p>This code will expire in 1 hour.</p>
60
+
61
+ <p>
62
+ If you did not request this code, you can safely ignore this email.
63
+ </p>
64
+ </div>
65
+ </div>
66
+ </body>
67
+
68
+ </html>
@@ -0,0 +1,82 @@
1
+ <!doctype html>
2
+ <html>
3
+
4
+ <head>
5
+ <style>
6
+ body {
7
+ font-family: Arial, sans-serif;
8
+ background-color: #f4f4f4;
9
+ margin: 0;
10
+ padding: 0;
11
+ }
12
+
13
+ .container {
14
+ width: 100%;
15
+ max-width: 600px;
16
+ margin: 0 auto;
17
+ background-color: #ffffff;
18
+ padding: 20px;
19
+ border-radius: 8px;
20
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
21
+ }
22
+
23
+ .header {
24
+ text-align: center;
25
+ padding: 10px 0;
26
+ }
27
+
28
+ .header h2 {
29
+ margin: 0;
30
+ color: #333333;
31
+ }
32
+
33
+ .content {
34
+ padding: 20px;
35
+ line-height: 1.6;
36
+ color: #555555;
37
+ }
38
+
39
+ .content p {
40
+ margin: 0 0 10px;
41
+ }
42
+
43
+ .button {
44
+ display: block;
45
+ width: 200px;
46
+ margin: 20px auto;
47
+ padding: 10px;
48
+ text-align: center;
49
+ background-color: #007bff;
50
+ color: #ffffff !important;
51
+ text-decoration: none;
52
+ border-radius: 5px;
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body>
58
+ <div class="container">
59
+ <div class="header">
60
+ <h2>Reset Your Folio Password</h2>
61
+ </div>
62
+ <div class="content">
63
+ <p>Hello,</p>
64
+ <p>
65
+ We received a request to reset the password for the Folio
66
+ account associated with the email {{ .Email }}. No changes have been
67
+ made to your account yet.
68
+ </p>
69
+ <p>You can reset your password by clicking the button below.</p>
70
+ <p>
71
+ <a href="{{ .ConfirmationURL }}auth-callback.html" class="button">Reset your password</a>
72
+ </p>
73
+ <p>
74
+ If you did not request a new password, please contact the Folio
75
+ administrator immediately.
76
+ </p>
77
+ <p>The Folio team</p>
78
+ </div>
79
+ </div>
80
+ </body>
81
+
82
+ </html>
@@ -0,0 +1,16 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "target": "ESNext",
7
+ "outDir": "dist/api",
8
+ "noEmit": false,
9
+ "declaration": false,
10
+ "allowJs": true,
11
+ "skipLibCheck": true,
12
+ "rootDir": "api"
13
+ },
14
+ "include": ["api/**/*"],
15
+ "exclude": ["node_modules", "dist"]
16
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "useDefineForClassFields": true,
5
+ "lib": ["DOM", "DOM.Iterable", "ESNext"],
6
+ "allowJs": false,
7
+ "skipLibCheck": true,
8
+ "esModuleInterop": true,
9
+ "allowSyntheticDefaultImports": true,
10
+ "strict": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "module": "ESNext",
13
+ "moduleResolution": "Node",
14
+ "resolveJsonModule": true,
15
+ "isolatedModules": true,
16
+ "noEmit": true,
17
+ "jsx": "react-jsx",
18
+ "types": ["vite/client"],
19
+ "baseUrl": ".",
20
+ "paths": {
21
+ "@/*": ["src/*"]
22
+ }
23
+ },
24
+ "include": ["src", "api", "tests"]
25
+ }
package/vite.config.ts ADDED
@@ -0,0 +1,146 @@
1
+ import { defineConfig } from "vite";
2
+ import react from "@vitejs/plugin-react";
3
+ import tailwindcss from "@tailwindcss/vite";
4
+ import { execSync } from "node:child_process";
5
+ import path from "node:path";
6
+ import pkg from "./package.json";
7
+
8
+ function getLatestMigrationTimestamp() {
9
+ try {
10
+ return execSync("node ./scripts/get-latest-migration-timestamp.mjs", {
11
+ encoding: "utf8"
12
+ }).trim();
13
+ } catch {
14
+ return "unknown";
15
+ }
16
+ }
17
+
18
+ export default defineConfig({
19
+ define: {
20
+ "import.meta.env.VITE_APP_VERSION": JSON.stringify(pkg.version),
21
+ "import.meta.env.VITE_LATEST_MIGRATION_TIMESTAMP": JSON.stringify(getLatestMigrationTimestamp())
22
+ },
23
+ plugins: [
24
+ react(),
25
+ tailwindcss(),
26
+ {
27
+ name: "api-migrate",
28
+ configureServer(server) {
29
+ server.middlewares.use("/api/migrate", async (req, res, next) => {
30
+ if (req.method !== "POST") return next();
31
+
32
+ try {
33
+ // Parse request body
34
+ const buffers = [];
35
+ for await (const chunk of req) {
36
+ buffers.push(chunk);
37
+ }
38
+
39
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
40
+ let body: any = {};
41
+ try {
42
+ body = JSON.parse(Buffer.concat(buffers).toString());
43
+ } catch {
44
+ res.writeHead(400, { "Content-Type": "application/json" });
45
+ res.end(JSON.stringify({ error: "Invalid JSON in request body" }));
46
+ return;
47
+ }
48
+
49
+ const { projectRef, accessToken } = body;
50
+
51
+ if (!projectRef) {
52
+ res.writeHead(400, { "Content-Type": "application/json" });
53
+ res.end(JSON.stringify({ error: "projectRef is required" }));
54
+ return;
55
+ }
56
+
57
+ // Set up streaming response (SSE style for logs)
58
+ res.writeHead(200, {
59
+ "Content-Type": "text/event-stream",
60
+ "Cache-Control": "no-cache",
61
+ "Connection": "keep-alive"
62
+ });
63
+
64
+ const sendEvent = (type: string, data: string) => {
65
+ res.write(`data: ${JSON.stringify({ type, data })}\n\n`);
66
+ };
67
+
68
+ sendEvent("info", "🚀 Starting migration (Development Mode)...");
69
+
70
+ const { spawn } = await import("node:child_process");
71
+ const scriptPath = path.join(process.cwd(), "scripts", "migrate.sh");
72
+
73
+ const migrationProcess = spawn("bash", [scriptPath], {
74
+ env: {
75
+ ...process.env,
76
+ SUPABASE_PROJECT_ID: projectRef,
77
+ SUPABASE_ACCESS_TOKEN: accessToken
78
+ },
79
+ cwd: process.cwd(),
80
+ stdio: ["ignore", "pipe", "pipe"]
81
+ });
82
+
83
+ migrationProcess.stdout.on("data", (data) => {
84
+ const lines = data.toString().split("\n");
85
+ lines.forEach((line: string) => {
86
+ if (line.trim()) sendEvent("stdout", line);
87
+ });
88
+ });
89
+
90
+ migrationProcess.stderr.on("data", (data) => {
91
+ const lines = data.toString().split("\n");
92
+ lines.forEach((line: string) => {
93
+ if (line.trim()) sendEvent("stderr", line);
94
+ });
95
+ });
96
+
97
+ migrationProcess.on("close", (code) => {
98
+ if (code === 0) {
99
+ sendEvent("info", "✅ Migration completed successfully!");
100
+ sendEvent("done", "success");
101
+ } else {
102
+ sendEvent("error", `❌ Migration failed with exit code: ${code}`);
103
+ sendEvent("done", "failed");
104
+ }
105
+ res.end();
106
+ });
107
+
108
+ migrationProcess.on("error", (error) => {
109
+ sendEvent("error", `❌ Failed to start migration: ${error.message}`);
110
+ sendEvent("done", "failed");
111
+ res.end();
112
+ });
113
+
114
+ req.on("close", () => {
115
+ if (!migrationProcess.killed) {
116
+ migrationProcess.kill();
117
+ }
118
+ });
119
+ } catch (error) {
120
+ console.error("[Migration API] Error:", error);
121
+ if (!res.headersSent) {
122
+ res.writeHead(500, { "Content-Type": "application/json" });
123
+ res.end(JSON.stringify({ error: "Internal server error" }));
124
+ }
125
+ }
126
+ });
127
+ }
128
+ }
129
+ ],
130
+ server: {
131
+ port: 5173,
132
+ proxy: {
133
+ "/api": {
134
+ target: "http://localhost:3006",
135
+ changeOrigin: true,
136
+ timeout: 600_000,
137
+ proxyTimeout: 600_000
138
+ }
139
+ }
140
+ },
141
+ resolve: {
142
+ alias: {
143
+ "@": path.resolve(__dirname, "./src")
144
+ }
145
+ }
146
+ });