diff --git a/Makefile b/Makefile index 2c7f1231..38c57f0f 100644 --- a/Makefile +++ b/Makefile @@ -39,6 +39,8 @@ integrate-export: @cp -R ../krow-workforce-export-latest/src ./frontend-web/src @echo " - Copying new index.html..." @cp ../krow-workforce-export-latest/index.html ./frontend-web/index.html + @echo " - Patching base44Client.js for local development..." + @node scripts/patch-base44-client.js @echo "--> Integration complete. Next step: 'make prepare-export'." # Applies all necessary patches to a fresh Base44 export to run it locally. diff --git a/scripts/patch-base44-client.js b/scripts/patch-base44-client.js new file mode 100644 index 00000000..01fda976 --- /dev/null +++ b/scripts/patch-base44-client.js @@ -0,0 +1,123 @@ +const fs = require('fs'); +const path = require('path'); + +const projectRoot = path.resolve(__dirname, '..'); +const clientFilePath = path.join(projectRoot, 'frontend-web', 'src', 'api', 'base44Client.js'); + +const originalMock = `// import { createClient } from '@base44/sdk'; + +// --- MIGRATION MOCK --- +// This mock completely disables the Base44 SDK to allow for local development. +export const base44 = { + auth: { + me: () => Promise.resolve(null), + logout: () => {}, + }, + entities: { + ActivityLog: { + filter: () => Promise.resolve([]), + }, + }, +};`; + +const patchedMock = `// import { createClient } from '@base44/sdk'; + +// --- MIGRATION MOCK --- +// This mock completely disables the Base44 SDK to allow for local development. +// It also simulates user roles for the RoleSwitcher component. + +const MOCK_USER_KEY = 'krow_mock_user_role'; + +// Default mock user data +const DEFAULT_MOCK_USER = { + id: "mock-user-123", + email: "dev@example.com", + full_name: "Dev User", + // 'role' is the Base44 default, 'user_role' is our custom field + role: "admin", + user_role: "admin", // Default role for testing + profile_picture: "https://i.pravatar.cc/150?u=a042581f4e29026024d", +}; + +// Function to get the current mock user state +const getMockUser = () => { + try { + const storedRole = localStorage.getItem(MOCK_USER_KEY); + if (storedRole) { + return { ...DEFAULT_MOCK_USER, user_role: storedRole, role: storedRole }; + } + // If no role is stored, set the default and return it + localStorage.setItem(MOCK_USER_KEY, DEFAULT_MOCK_USER.user_role); + return DEFAULT_MOCK_USER; + } catch (e) { + // localStorage is not available (e.g., in SSR) + return DEFAULT_MOCK_USER; + } +}; + +export const base44 = { + auth: { + me: () => Promise.resolve(getMockUser()), + logout: () => { + try { + localStorage.removeItem(MOCK_USER_KEY); // Clear role on logout + // Optionally, redirect to login page or reload + window.location.reload(); + } catch (e) { + // localStorage is not available + } + return Promise.resolve(); + }, + updateMe: (data) => { + try { + if (data.user_role) { + localStorage.setItem(MOCK_USER_KEY, data.user_role); + } + } catch (e) { + // localStorage is not available + } + // Simulate a successful update + return Promise.resolve({ ...getMockUser(), ...data }); + }, + }, + entities: { + ActivityLog: { + filter: () => Promise.resolve([]), + }, + // Add other entity mocks as needed for the RoleSwitcher to function + // For now, the RoleSwitcher only updates the user role, so other entities might not be critical. + }, + integrations: { + Core: { + SendEmail: () => Promise.resolve({ status: "sent" }), + UploadFile: () => Promise.resolve({ file_url: "mock-file-url" }), + InvokeLLM: () => Promise.resolve({ result: "mock-ai-response" }), + // Add other integration mocks if the RoleSwitcher indirectly calls them + } + } +};`; + +try { + let content = fs.readFileSync(clientFilePath, 'utf8'); + + if (content.includes('me: () => Promise.resolve(null),')) { + content = content.replace(originalMock.trim(), patchedMock.trim()); + fs.writeFileSync(clientFilePath, content, 'utf8'); + console.log('✅ Successfully patched frontend-web/src/api/base44Client.js'); + } else if (content.includes('const MOCK_USER_KEY')) { + console.log('ℹ️ base44Client.js is already patched. Skipping.'); + } else { + // Fallback to a simpler, more brittle replacement if the full mock doesn't match + const simpleOriginal = 'me: () => Promise.resolve(null),'; + if (content.includes(simpleOriginal)) { + fs.writeFileSync(clientFilePath, patchedMock, 'utf8'); + console.log('✅ Successfully patched frontend-web/src/api/base44Client.js using fallback.'); + } else { + console.error('❌ Patching failed: Could not find the original mock code in base44Client.js.'); + process.exit(1); + } + } +} catch (error) { + console.error('❌ An error occurred during patching:', error); + process.exit(1); +}