492 lines
12 KiB
JavaScript
492 lines
12 KiB
JavaScript
import apiClient from './client';
|
|
import { auth, dataConnect } from '../firebase';
|
|
import { signOut } from 'firebase/auth';
|
|
|
|
import * as dcSdk from '@dataconnect/generated'; // listEvents, createEvent, etc.
|
|
|
|
// --- Auth Module ---
|
|
const authModule = {
|
|
/**
|
|
* Fetches the currently authenticated user's profile from the backend.
|
|
* @returns {Promise<object>} The user profile.
|
|
*/
|
|
me: async () => {
|
|
// 1. Firebase auth user
|
|
const fbUser = auth.currentUser;
|
|
|
|
if (!fbUser) {
|
|
return null; // NO ESTÁ LOGGEADO
|
|
}
|
|
|
|
// 2. Attempt to load matching Krow User from DataConnect
|
|
// (because your Krow user metadata is stored in the "users" table)
|
|
let krowUser = null;
|
|
try {
|
|
const response = await dcSdk.getUserById(dataConnect, { id: fbUser.uid });
|
|
krowUser = response.data?.user || null;
|
|
} catch (err) {
|
|
console.warn("Krow user not found in DataConnect, returning Firebase-only info.");
|
|
}
|
|
|
|
// 3. Build unified "me" object
|
|
return {
|
|
id: fbUser.uid,
|
|
email: fbUser.email,
|
|
fullName: krowUser?.fullName || fbUser.displayName || null,
|
|
role: krowUser?.role || "user",
|
|
user_role: krowUser?.userRole || null,
|
|
firebase: fbUser,
|
|
krow: krowUser
|
|
};
|
|
},
|
|
|
|
/**
|
|
* Logs the user out.
|
|
* @param {string} [redirectUrl] - Optional URL to redirect to after logout.
|
|
*/
|
|
logout: async (redirectUrl) => {
|
|
await signOut(auth);
|
|
if (redirectUrl) {
|
|
window.location.href = redirectUrl;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Checks if a user is currently authenticated.
|
|
* @returns {boolean} True if a user is authenticated.
|
|
*/
|
|
isAuthenticated: () => {
|
|
return !!auth.currentUser;
|
|
},
|
|
};
|
|
|
|
// --- Core Integrations Module ---
|
|
const coreIntegrationsModule = {
|
|
/**
|
|
* Sends an email.
|
|
* @param {object} params - { to, subject, body }
|
|
* @returns {Promise<object>} API response.
|
|
*/
|
|
SendEmail: async (params) => {
|
|
const { data } = await apiClient.post('/sendEmail', params);
|
|
return data;
|
|
},
|
|
|
|
/**
|
|
* Invokes a large language model.
|
|
* @param {object} params - { prompt, response_json_schema, file_urls }
|
|
* @returns {Promise<object>} API response.
|
|
*/
|
|
InvokeLLM: async (params) => {
|
|
const { data } = await apiClient.post('/invokeLLM', params);
|
|
return data;
|
|
},
|
|
|
|
/**
|
|
* Uploads a public file.
|
|
* @param {File} file - The file to upload.
|
|
* @returns {Promise<object>} API response with file_url.
|
|
*/
|
|
UploadFile: async ({ file }) => {
|
|
const formData = new FormData();
|
|
formData.append('file', file);
|
|
const { data } = await apiClient.post('/uploadFile', formData, {
|
|
headers: { 'Content-Type': 'multipart/form-data' },
|
|
});
|
|
return data;
|
|
},
|
|
|
|
/**
|
|
* Uploads a private file.
|
|
* @param {File} file - The file to upload.
|
|
* @returns {Promise<object>} API response with file_uri.
|
|
*/
|
|
UploadPrivateFile: async ({ file }) => {
|
|
const formData = new FormData();
|
|
formData.append('file', file);
|
|
const { data } = await apiClient.post('/uploadPrivateFile', formData, {
|
|
headers: { 'Content-Type': 'multipart/form-data' },
|
|
});
|
|
return data;
|
|
},
|
|
|
|
/**
|
|
* Creates a temporary signed URL for a private file.
|
|
* @param {object} params - { file_uri, expires_in }
|
|
* @returns {Promise<object>} API response with signed_url.
|
|
*/
|
|
CreateFileSignedUrl: async (params) => {
|
|
const { data } = await apiClient.post('/createSignedUrl', params);
|
|
return data;
|
|
},
|
|
};
|
|
|
|
const dataconnectEntityConfig = {
|
|
User: {
|
|
list: 'listUsers',
|
|
get: 'getUserById',
|
|
create: 'createUser',
|
|
update: 'updateUser',
|
|
delete: 'deleteUser',
|
|
filter: 'filterUsers',
|
|
},
|
|
Event: {
|
|
list: 'listEvents',
|
|
create: 'createEvent',
|
|
get: 'getEventById',
|
|
update: 'updateEvent',
|
|
delete: 'deleteEvent',
|
|
filter: 'filterEvents',
|
|
},
|
|
|
|
Staff: {
|
|
list: 'listStaff',
|
|
create: 'createStaff',
|
|
get: 'getStaffById',
|
|
update: 'updateStaff',
|
|
delete: 'deleteStaff',
|
|
filter: 'filterStaff',
|
|
},
|
|
|
|
Vendor: {
|
|
list: 'listVendor',
|
|
get: 'getVendorById',
|
|
create: 'createVendor',
|
|
update: 'updateVendor',
|
|
delete: 'deleteVendor',
|
|
filter: 'filterVendors',
|
|
},
|
|
|
|
VendorRate: {
|
|
list: 'listVendorRate',
|
|
get: 'getVendorRateById',
|
|
create: 'createVendorRate',
|
|
update: 'updateVendorRate',
|
|
delete: 'deleteVendorRate',
|
|
filter: 'filterVendorRates',
|
|
},
|
|
|
|
VendorDefaultSetting:{
|
|
list: 'listVendorDefaultSettings',
|
|
get: 'getVendorDefaultSettingById',
|
|
create: 'createVendorDefaultSetting',
|
|
update: 'updateVendorDefaultSetting',
|
|
delete: 'deleteVendorDefaultSetting',
|
|
filter: 'filterVendorDefaultSettings',
|
|
},
|
|
|
|
Invoice:{
|
|
list: 'listInvoice',
|
|
get: 'getInvoiceById',
|
|
create: 'createInvoice',
|
|
update: 'updateInvoice',
|
|
delete: 'deleteInvoice',
|
|
filter: 'filterInvoices',
|
|
|
|
},
|
|
|
|
Business:{
|
|
list: 'listBusiness',
|
|
get: 'getBusinessById',
|
|
create: 'createBusiness',
|
|
update: 'updateBusiness',
|
|
delete: 'deleteBusiness',
|
|
filter: 'filterBusiness',
|
|
},
|
|
|
|
Certification:{
|
|
list: 'listCertification',
|
|
get: 'getCertificationById',
|
|
create: 'createCertification',
|
|
update: 'updateCertification',
|
|
delete: 'deleteCertification',
|
|
filter: 'filterCertification',
|
|
},
|
|
|
|
Team:{
|
|
list: 'listTeam',
|
|
get: 'getTeamById',
|
|
create: 'createTeam',
|
|
update: 'updateTeam',
|
|
delete: 'deleteTeam',
|
|
filter: 'filterTeam',
|
|
},
|
|
|
|
TeamMember: {
|
|
list: 'listTeamMember',
|
|
get: 'getTeamMemberById',
|
|
create: 'createTeamMember',
|
|
update: 'updateTeamMember',
|
|
delete: 'deleteTeamMember',
|
|
filter: 'filterTeamMember',
|
|
},
|
|
|
|
TeamHub: {
|
|
list: 'listTeamHub',
|
|
get: 'getTeamHubById',
|
|
create: 'createTeamHub',
|
|
update: 'updateTeamHub',
|
|
delete: 'deleteTeamHub',
|
|
filter: 'filterTeamHub',
|
|
},
|
|
|
|
TeamMemberInvite: {
|
|
list: 'listTeamMemberInvite',
|
|
get: 'getTeamMemberInviteById',
|
|
create: 'createTeamMemberInvite',
|
|
update: 'updateTeamMemberInvite',
|
|
delete: 'deleteTeamMemberInvite',
|
|
filter: 'filterTeamMemberInvite',
|
|
},
|
|
|
|
Conversation:{
|
|
list: 'listConversation',
|
|
get: 'getConversationById',
|
|
create: 'createConversation',
|
|
update: 'updateConversation',
|
|
delete: 'deleteConversation',
|
|
filter: 'filterConversation',
|
|
},
|
|
|
|
Message:{
|
|
list: 'listMessage',
|
|
get: 'getMessageById',
|
|
create: 'createMessage',
|
|
update: 'updateMessage',
|
|
delete: 'deleteMessage',
|
|
filter: 'filterMessage',
|
|
},
|
|
|
|
ActivityLog:{
|
|
list: 'listActivityLog',
|
|
get: 'getActivityLogById',
|
|
create: 'createActivityLog',
|
|
update: 'updateActivityLog',
|
|
delete: 'deleteActivityLog',
|
|
filter: 'filterActivityLog',
|
|
},
|
|
|
|
Enterprise:{
|
|
list: 'listEnterprise',
|
|
get: 'getEnterpriseById',
|
|
create: 'createEnterprise',
|
|
update: 'updateEnterprise',
|
|
delete: 'deleteEnterprise',
|
|
filter: 'filterEnterprise',
|
|
},
|
|
|
|
Sector:{
|
|
|
|
},
|
|
|
|
Partner:{
|
|
|
|
},
|
|
|
|
Order:{
|
|
|
|
},
|
|
|
|
Shift:{
|
|
|
|
}
|
|
|
|
};
|
|
|
|
// Helper for methods not implemented
|
|
const notImplemented = (entityName, method) => async () => {
|
|
throw new Error(`${entityName}.${method} is not implemented yet for Data Connect`);
|
|
};
|
|
|
|
// --- Entities Module ( Data Connect, without REST Base44) ---
|
|
const entitiesModule = {};
|
|
|
|
Object.entries(dataconnectEntityConfig).forEach(([entityName, ops]) => {
|
|
entitiesModule[entityName] = {
|
|
|
|
get: notImplemented(entityName, 'get'),
|
|
update: notImplemented(entityName, 'update'),
|
|
delete: notImplemented(entityName, 'delete'),
|
|
filter: notImplemented(entityName, 'filter'),
|
|
list: notImplemented(entityName, 'list'),
|
|
create: notImplemented(entityName, 'create'),
|
|
|
|
// list
|
|
...(ops.list && {
|
|
list: async (params) => {
|
|
const fn = dcSdk[ops.list];
|
|
if (typeof fn !== 'function') {
|
|
throw new Error(
|
|
`Data Connect operation "${ops.list}" not found for entity "${entityName}".`
|
|
);
|
|
}
|
|
|
|
return fn(dataConnect);
|
|
},
|
|
}),
|
|
|
|
// create
|
|
...(ops.create && {
|
|
create: async (params) => {
|
|
const fn = dcSdk[ops.create];
|
|
if (typeof fn !== 'function') {
|
|
throw new Error(
|
|
`Data Connect operation "${ops.create}" not found for entity "${entityName}".`
|
|
);
|
|
}
|
|
|
|
const { data } = params ?? {};
|
|
if (!data) {
|
|
throw new Error(
|
|
`${entityName}.create expects a payload like { data: { ...fields } }`
|
|
);
|
|
}
|
|
|
|
return fn(dataConnect, data);
|
|
},
|
|
}),
|
|
|
|
//get
|
|
...(ops.get && {
|
|
get: async (params) => {
|
|
const fn = dcSdk[ops.get];
|
|
if (typeof fn !== 'function') {
|
|
throw new Error(
|
|
`Data Connect operation "${ops.get}" not found for entity "${entityName}".`
|
|
);
|
|
}
|
|
|
|
if (!params || typeof params !== 'object') {
|
|
throw new Error(`${entityName}.get expects an object of variables (e.g. { id })`);
|
|
}
|
|
|
|
return fn(dataConnect, params);
|
|
},
|
|
}),
|
|
|
|
//update
|
|
...(ops.update && {
|
|
update: async (params) => {
|
|
const fn = dcSdk[ops.update];
|
|
if (typeof fn !== 'function') {
|
|
throw new Error(
|
|
`Data Connect operation "${ops.update}" not found for entity "${entityName}".`
|
|
);
|
|
}
|
|
|
|
if (!params || typeof params !== 'object') {
|
|
throw new Error(
|
|
`${entityName}.update expects an object of variables matching the GraphQL mutation`
|
|
);
|
|
}
|
|
|
|
const { id, data } = params;
|
|
|
|
if (!id) {
|
|
throw new Error(`${entityName}.update requires an "id" field`);
|
|
}
|
|
|
|
if (!data || typeof data !== 'object') {
|
|
throw new Error(
|
|
`${entityName}.update requires a "data" object with the fields to update`
|
|
);
|
|
}
|
|
|
|
const vars = { id, ...data };
|
|
|
|
return fn(dataConnect, vars);
|
|
|
|
},
|
|
}),
|
|
|
|
|
|
// delete
|
|
...(ops.delete && {
|
|
delete: async (params) => {
|
|
const fn = dcSdk[ops.delete];
|
|
if (typeof fn !== 'function') {
|
|
throw new Error(
|
|
`Data Connect operation "${ops.delete}" not found for entity "${entityName}".`
|
|
);
|
|
}
|
|
|
|
if (!params || typeof params !== 'object') {
|
|
throw new Error(
|
|
`${entityName}.delete expects an object like { id }`
|
|
);
|
|
}
|
|
|
|
const { id } = params;
|
|
|
|
if (!id) {
|
|
throw new Error(`${entityName}.delete requires an "id" field`);
|
|
}
|
|
|
|
// Data Connect solo espera { id } como variables
|
|
return fn(dataConnect, { id });
|
|
},
|
|
}),
|
|
|
|
|
|
// filter
|
|
...(ops.filter && {
|
|
filter: async (params) => {
|
|
const fn = dcSdk[ops.filter];
|
|
if (typeof fn !== 'function') {
|
|
throw new Error(
|
|
`Data Connect operation "${ops.filter}" not found for entity "${entityName}".`
|
|
);
|
|
}
|
|
|
|
if (!params) {
|
|
if (ops.list) {//if no params, call to list()
|
|
const listFn = dcSdk[ops.list];
|
|
if (typeof listFn !== 'function') {
|
|
throw new Error(
|
|
`Data Connect operation "${ops.list}" not found for entity "${entityName}".`
|
|
);
|
|
}
|
|
return listFn(dataConnect);
|
|
}
|
|
throw new Error(`${entityName}.filter expects params or a list operation`);
|
|
}
|
|
const rawFilters = params.filters ?? params;
|
|
const variables = {};
|
|
|
|
for (const [key, value] of Object.entries(rawFilters)) {//cleaning undefined/null/'' values
|
|
if (value !== undefined && value !== null && value !== '') {
|
|
variables[key] = value;
|
|
}
|
|
}
|
|
|
|
// if no valid filters, call to list()
|
|
if (Object.keys(variables).length === 0) {
|
|
if (ops.list) {
|
|
const listFn = dcSdk[ops.list];
|
|
if (typeof listFn !== 'function') {
|
|
throw new Error(
|
|
`Data Connect operation "${ops.list}" not found for entity "${entityName}".`
|
|
);
|
|
}
|
|
return listFn(dataConnect);
|
|
}
|
|
throw new Error(`${entityName}.filter received no valid filters and no list operation`);
|
|
}
|
|
|
|
return fn(dataConnect, variables);
|
|
},
|
|
}),
|
|
|
|
};
|
|
});
|
|
|
|
|
|
// --- Main SDK Export ---
|
|
export const krowSDK = {
|
|
auth: authModule,
|
|
integrations: {
|
|
Core: coreIntegrationsModule,
|
|
},
|
|
entities: entitiesModule,
|
|
};
|