diff --git a/apps/api/.wundergraph/operations/insertDB.ts b/apps/api/.wundergraph/operations/insertDB.ts index 44228ba..731db77 100644 --- a/apps/api/.wundergraph/operations/insertDB.ts +++ b/apps/api/.wundergraph/operations/insertDB.ts @@ -110,7 +110,6 @@ const metaSchema = { function generateRandomObject() { return { $schema: metaSchema.$id, - $id: `https://alpha.ipfs.homin.io/UserSchema${Math.floor(Math.random() * 10000)}`, type: "object", author: "HominioAlpha", prev: null, diff --git a/apps/api/.wundergraph/operations/insertObject.ts b/apps/api/.wundergraph/operations/insertObject.ts new file mode 100644 index 0000000..f3fed9f --- /dev/null +++ b/apps/api/.wundergraph/operations/insertObject.ts @@ -0,0 +1,96 @@ +import { createOperation, z } from '../generated/wundergraph.factory'; +import Ajv from 'ajv'; +import addFormats from 'ajv-formats'; + +const ajv = new Ajv({ + schemaId: '$id', + strict: false, + validateSchema: false, + addUsedSchema: false +}); +addFormats(ajv); + +export default createOperation.mutation({ + input: z.object({ + object: z.any() + }), + handler: async ({ input, context, operations }) => { + try { + console.log('Step 1: Received input object:', JSON.stringify(input.object, null, 2)); + + if (!input.object.$schema) { + throw new Error('Object must have a $schema property'); + } + console.log('Step 2: Validated $schema property exists:', input.object.$schema); + + // Fetch the schema + console.log('Step 3: Fetching schema from database...'); + const { data: schemaData, error: schemaError } = await context.supabase + .from('db') + .select('json') + .eq('json->>$id', input.object.$schema) + .single(); + + if (schemaError) { + throw new Error('Failed to fetch schema: ' + schemaError.message); + } + console.log('Step 4: Schema fetched successfully:', JSON.stringify(schemaData.json, null, 2)); + + const schema = schemaData.json; + + // Calculate CID for the object + console.log('Step 5: Calculating CID for the object...'); + const calcCIDResult = await operations.mutate({ + operationName: 'calculateCID', + input: { json: input.object }, + }); + + if (!calcCIDResult.data?.success) { + throw new Error('Failed to calculate CID: ' + (calcCIDResult.data?.error || 'Unknown error')); + } + console.log('Step 6: CID calculated successfully:', calcCIDResult.data.json.$id); + + const objectWithId = { + ...calcCIDResult.data.json, + $id: calcCIDResult.data.json.$id, + $schema: input.object.$schema + }; + console.log('Step 7: Created object with ID:', JSON.stringify(objectWithId, null, 2)); + + // Validate the object against the schema + console.log('Step 8: Validating object against schema...'); + const validate = ajv.compile(schema); + const valid = validate(objectWithId); + + if (!valid) { + console.error('Validation errors:', ajv.errorsText(validate.errors)); + throw new Error('Validation error: ' + ajv.errorsText(validate.errors)); + } + console.log('Step 9: Object validated successfully against schema'); + + // Insert the object into the database + console.log('Step 10: Inserting object into database...'); + const { data, error } = await context.supabase + .from('db') + .insert({ json: objectWithId }) + .select(); + + if (error) { + throw new Error('Database insert error: ' + error.message); + } + console.log('Step 11: Object inserted successfully:', JSON.stringify(data[0], null, 2)); + + return { + success: true, + insertedData: data[0] + }; + } catch (error) { + console.error('Unexpected error in insertObject:', error); + return { + success: false, + error: 'Unexpected error', + details: error.message + }; + } + }, +}); \ No newline at end of file diff --git a/apps/app/src/lib/components/HominioDB.svelte b/apps/app/src/lib/components/HominioDB.svelte index 1f4f64d..c43fe89 100644 --- a/apps/app/src/lib/components/HominioDB.svelte +++ b/apps/app/src/lib/components/HominioDB.svelte @@ -13,6 +13,10 @@ operationName: 'insertDB' }); + const insertObjectMutation = createMutation({ + operationName: 'insertObject' + }); + function sortByTimestamp(a, b) { return new Date(b.json.timestamp).getTime() - new Date(a.json.timestamp).getTime(); } @@ -94,13 +98,61 @@ console.log('HominioDB: Selected item changed, resetting expandedProperties'); expandedProperties = []; } + + async function insertHardcodedObject() { + message = { text: '', type: '' }; + const hardcodedObject = { + $schema: 'https://alpha.ipfs.homin.io/QmWqLHcJsrMpmZrbxfMA3oM2YVbHjJfGw94UbZgBwm1mYR', + $id: '', // This will be filled by the server + prev: null, + type: 'object', + title: 'John Doe User Object', + author: 'HominioDB Client', + version: 1, + description: 'A sample user object for John Doe', + properties: { + username: 'john_doe', + email: 'john.doe@example.com', + password: 'hashedpassword123', + profile: { + fullName: 'John Doe', + birthDate: '1990-01-01', + bio: "I'm a software developer who loves coding and outdoor activities.", + location: { + country: 'United States', + city: 'San Francisco' + } + }, + settings: { + theme: 'dark', + notifications: true, + language: 'en' + } + } + }; + + const result = await $insertObjectMutation.mutateAsync({ + object: hardcodedObject + }); + + if (result.success) { + message = { text: 'Hardcoded object inserted successfully!', type: 'success' }; + await $query.refetch(); + } else { + message = { text: `Failed: ${result.details}`, type: 'error' }; + console.error('Failed:', result.details); + } + }