Created
September 24, 2025 17:34
-
-
Save mrtnzlml/c59ea5c370a551a7e417638a3e67ff1f to your computer and use it in GitHub Desktop.
Deduplicates shared queue schemas for Rossum.ai
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // --- Configuration --- | |
| // Replace with your Rossum API credentials and base URL. | |
| const ROSSUM_API_TOKEN = 'YOUR_API_TOKEN'; // Replace with your actual API token | |
| const BASE_URL = 'https://api.elis.rossum.ai/v1'; // Adjust if you have a dedicated instance URL | |
| // --- Script Mode --- | |
| // Set to true to simulate changes without writing to the API. | |
| // Set to false to perform live changes. | |
| const DRY_RUN = true; | |
| /** | |
| * A wrapper for the native fetch API to interact with the Rossum API. | |
| * @param {string} path - The API endpoint path (e.g., '/schemas'). | |
| * @param {object} options - Standard fetch options (method, body, etc.). | |
| * @returns {Promise<any>} A promise that resolves to the JSON response. | |
| */ | |
| async function rossumFetch(path, options = {}) { | |
| const url = path.startsWith('http') ? path : `${BASE_URL}${path}`; | |
| const headers = { | |
| 'Authorization': `Bearer ${ROSSUM_API_TOKEN}`, | |
| 'Content-Type': 'application/json', | |
| ...options.headers, | |
| }; | |
| const response = await fetch(url, { ...options, headers }); | |
| if (!response.ok) { | |
| const errorData = await response.json().catch(() => ({ message: response.statusText })); | |
| const error = new Error(`API request failed with status ${response.status}`); | |
| error.response = { data: errorData }; | |
| throw error; | |
| } | |
| // Handle responses that might not have a JSON body (e.g., 204 No Content for PATCH) | |
| if (response.status === 204) { | |
| return null; | |
| } | |
| return response.json(); | |
| } | |
| /** | |
| * Fetches all schemas from the Rossum API, handling pagination. | |
| * @returns {Promise<Array<Object>>} A promise that resolves to an array of all schema objects. | |
| */ | |
| async function getAllSchemas() { | |
| let schemas = []; | |
| let nextUrl = '/schemas'; | |
| console.log('Fetching all schemas...'); | |
| while (nextUrl) { | |
| try { | |
| const response = await rossumFetch(nextUrl); | |
| schemas = schemas.concat(response.results); | |
| nextUrl = response.pagination.next; | |
| } catch (error) { | |
| console.error(`Error fetching schemas from ${nextUrl}:`, error.response ? error.response.data : error.message); | |
| return []; | |
| } | |
| } | |
| console.log(`Successfully fetched ${schemas.length} schemas.`); | |
| return schemas; | |
| } | |
| /** | |
| * Creates a copy of a given schema. In dry run mode, it simulates this action. | |
| * @param {Object} originalSchema - The schema object to copy. | |
| * @param {string} queueId - The ID of the queue for which the new schema is being created. | |
| * @returns {Promise<Object>} A promise that resolves to the newly created (or simulated) schema object. | |
| */ | |
| async function copySchema(originalSchema, queueId) { | |
| const newSchemaName = `${originalSchema.name} (Copy for Queue ${queueId})`; | |
| if (DRY_RUN) { | |
| console.log(`[DRY RUN] Would create schema copy: "${newSchemaName}"`); | |
| // Return a mock object for the rest of the script to simulate the full flow | |
| return { | |
| id: `new-schema-for-${queueId}`, | |
| url: `${BASE_URL}/schemas/new-schema-for-${queueId}` | |
| }; | |
| } | |
| const originalSchemaContent = (await rossumFetch(originalSchema.url)).content | |
| const newSchemaPayload = { | |
| name: newSchemaName, | |
| content: originalSchemaContent | |
| }; | |
| try { | |
| console.log(`Creating a copy of schema "${originalSchema.name}" for queue ${queueId}...`); | |
| const response = await rossumFetch('/schemas', { | |
| method: 'POST', | |
| body: JSON.stringify(newSchemaPayload), | |
| }); | |
| console.log(`Successfully created new schema with ID: ${response.id}`); | |
| return response; | |
| } catch (error) { | |
| console.error(`Failed to create schema copy for queue ${queueId}:`, error.response ? error.response.data : error.message); | |
| throw error; | |
| } | |
| } | |
| /** | |
| * Updates a queue to use a new schema. In dry run mode, it simulates this action. | |
| * @param {string} queueUrl - The URL of the queue to update. | |
| * @param {string} newSchemaUrl - The URL of the new schema to assign to the queue. | |
| */ | |
| async function updateQueueSchema(queueUrl, newSchemaUrl) { | |
| const queueId = queueUrl.split('/').pop(); | |
| if (DRY_RUN) { | |
| console.log(`[DRY RUN] Would update queue ${queueId} to use new schema: ${newSchemaUrl}`); | |
| return; | |
| } | |
| try { | |
| console.log(`Updating queue ${queueId} to use new schema ${newSchemaUrl}...`); | |
| await rossumFetch(queueUrl, { | |
| method: 'PATCH', | |
| body: JSON.stringify({ schema: newSchemaUrl }), | |
| }); | |
| console.log(`Successfully updated queue ${queueId}.`); | |
| } catch (error) { | |
| console.error(`Failed to update queue ${queueUrl}:`, error.response ? error.response.data : error.message); | |
| throw error; | |
| } | |
| } | |
| /** | |
| * Main function to find shared schemas and assign unique copies to each queue. | |
| */ | |
| async function main() { | |
| console.log('--- Rossum Schema Deduplication Script ---'); | |
| if (DRY_RUN) { | |
| console.log('\n*** RUNNING IN DRY RUN MODE. NO CHANGES WILL BE MADE. ***\n'); | |
| } else { | |
| console.log('\n*** RUNNING IN LIVE MODE. CHANGES WILL BE APPLIED. ***\n'); | |
| } | |
| const allSchemas = await getAllSchemas(); | |
| const sharedSchemas = allSchemas.filter(schema => schema.queues && schema.queues.length > 1); | |
| if (sharedSchemas.length === 0) { | |
| console.log('No shared schemas found. Exiting.'); | |
| return; | |
| } | |
| console.log(`Found ${sharedSchemas.length} shared schemas to process.`); | |
| for (const schema of sharedSchemas) { | |
| console.log(`\nProcessing shared schema: "${schema.name}" (ID: ${schema.id}), used by ${schema.queues.length} queues.`); | |
| for (const queueUrl of schema.queues) { | |
| try { | |
| const queueId = queueUrl.split('/').pop(); | |
| const newSchema = await copySchema(schema, queueId); | |
| await updateQueueSchema(queueUrl, newSchema.url); | |
| } catch (err) { | |
| console.error(`Could not process queue ${queueUrl} for schema ${schema.id}. Skipping.`); | |
| } | |
| } | |
| } | |
| console.log('\n--- Schema deduplication process finished. ---'); | |
| } | |
| // Run the main function | |
| main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment