import { IBootstrapActionParams, IBootstrapActionResponse, IBootstrapNotificationParams, IBootstrapNotificationResponse, IBootstrapStorageParams, IBootstrapStorageResponse, IBootstrapSessionParams, IBootstrapSessionResponse, IBootstrapDatabaseParams, IBootstrapDatabaseResponse, IBootstrapBrokerParams, IBootstrapBrokerResponse, IBootstrapGraphParams, IBootstrapGraphResponse, IBootstrapVectorParams, IBootstrapVectorResponse, IBootstrapResilienceParams, IBootstrapResilienceResponse, IBootstrapIntelligenceParams, IBootstrapIntelligenceResponse, IBootstrapFeatureParams, IGenerateExecutablePayloadParams, IGenerateExecutablePayloadResponse } from '../../api/services/productsApi.service'; import { IApp, IAppAccess, IAppAction, IAppWebhook, ISample, IVersion } from '../../types/appBuilder.types'; import { IBuilderInit } from '../../types/index.types'; import { IActionDataParserInput, IActionRequest, ICreateProductsBuilder, IStepEvent, IStepInput, IStepSequence, IProduct, IProductApp, IProductCache, IProductDatabase, IProductDatabaseAction, IProductEnv, ISequenceValidationContext, IProductFunction, IProductJobs, IParseActionEventInput, IParseInputStringInput, IParseInputStringMetaData, IProductStorage, IDbActionRequest, INotificationRequest, IProductQuota, IProductFallback, IProductDatabaseMigration, IQuotaOptions, IFallbackOptions, IProductSession, IFetchFilesPayload, IFetchUsersPayload, IProductAppHealth, IProductGraph, IProductFeature, IProductVector, IProductAgent, IProductLLMModel, IProductDatabaseTrigger, IProductVectorAction } from '../../types/productsBuilder.types'; import { KeyValuePair } from '../../imports/imports.types'; import { IProductNotification, INotificationEnv, IProductNotificationTemplate, IProductMessageBroker, IProductMessageBrokerTopic, IMessageBrokerProducer, IMessageBrokerConsumer, IFileURLPayload } from '../../types/processor.types'; import { IParsedSample } from '../../types/inputs.types'; export interface IProductsBuilderService { fetchPrivateKey(): string; fetchWorkspaceId(): string; fetchProductId(): string; fetchThirdPartyAppByAccessTag(access_tag: string): Promise<(IApp & IVersion) | null>; createProduct(data: ICreateProductsBuilder): Promise; updateProduct(data: Partial): Promise; initializeProduct(product_id: string): Promise; fetchProduct(): Promise; initializeProductByTag(tag: string): Promise; bootstrapAction(params: IBootstrapActionParams): Promise; applyBootstrapActionResult(result: IBootstrapActionResponse, product_tag?: string): void; bootstrapNotification(params: IBootstrapNotificationParams): Promise; bootstrapStorage(params: IBootstrapStorageParams): Promise; bootstrapSession(params: IBootstrapSessionParams): Promise; bootstrapDatabase(params: IBootstrapDatabaseParams): Promise; bootstrapBroker(params: IBootstrapBrokerParams): Promise; bootstrapGraph(params: IBootstrapGraphParams): Promise; bootstrapVector(params: IBootstrapVectorParams): Promise; bootstrapResilience(params: IBootstrapResilienceParams): Promise; bootstrapIntelligence(params: IBootstrapIntelligenceParams): Promise; bootstrapFeature(params: Omit): Promise>; generateExecutablePayload(params: IGenerateExecutablePayloadParams): Promise; createEnv(data: Partial): Promise; updateEnv(slug: string, data: Partial): Promise; fetchEnv(slug: string, refresh?: boolean): Promise; fetchEnvs(): Promise>; createSession(data: IProductSession): Promise; updateSession(tag: string, data: Partial): Promise; fetchSession(tag: string): Promise; fetchSessions(): Promise>; createFunction(data: Partial): Promise; updateFunction(tag: string, data: Partial): Promise; fetchFunction(tag: string): Promise; fetchFunctions(): Promise>; createCache(data: Partial, throwErrorIfExists?: boolean): Promise; updateCache(tag: string, data: Partial): Promise; fetchCache(tag: string): Promise; fetchCaches(): Promise>; createStorage(data: Partial): Promise; updateStorage(tag: string, data: Partial): Promise; fetchStorage(tag: string): Promise; fetchStorages(): Promise>; createNotification(data: Partial): Promise; updateNotification(tag: string, data: Partial): Promise; fetchNotification(tag: string): Promise; fetchNotifications(): Promise>; createMessageBroker(data: Partial): Promise; updateMessageBroker(tag: string, data: Partial): Promise; fetchMessageBroker(tag: string): Promise; fetchMessageBrokers(): Promise>; createMessageBrokerTopic(data: Partial): Promise; updateMessageBrokerTopic(data: Partial): Promise; fetchMessageBrokerTopic(tag: string): Promise; fetchMessageBrokerTopics(messageBrokerTag: string): Promise>; createMessageBrokerProducer(data: Partial): Promise; updateMessageBrokerProducer(data: Partial): Promise; fetchMessageBrokerProducer(brokerTag: string, tag: string): Promise; fetchMessageBrokerProducers(messageBrokerTag: string): Promise>; createMessageBrokerConsumer(data: Partial): Promise; updateMessageBrokerConsumer(data: Partial): Promise; fetchMessageBrokerConsumer(brokerTag: string, tag: string): Promise; fetchMessageBrokerConsumers(messageBrokerTag: string): Promise>; createQuota(data: Partial): Promise; updateQuota(tag: string, data: Partial): Promise; fetchQuota(tag: string): Promise; fetchQuotas(): Promise>; createFallback(data: Partial): Promise; updateFallback(tag: string, data: Partial): Promise; fetchFallback(tag: string): Promise; fetchFallbacks(): Promise>; createNotificationMessage(data: Partial): Promise; updateNotificationMessage(data: Partial): Promise; fetchNotificationMessage(tag: string): Promise; fetchNotificationMessages(notificationTag: string): Promise>; updateApp(tag: string, data: Partial): Promise; fetchApp(tag: string): Promise; fetchApps(): Promise>; addApp(app: IProductApp, throwErrorIfExists?: boolean): Promise; createDatabase(data: Partial, throwErrorIfExists?: boolean): Promise; updateDatabase(tag: string, data: Partial): Promise; fetchDatabase(tag: string): Promise; fetchDatabases(): Promise>; createDatabaseAction(data: Partial, throwErrorIfExists?: boolean): Promise; updateDatabaseAction(data: Partial): Promise; fetchDatabaseAction(tag: string): Promise; fetchDatabaseActions(databaseTag: string): Promise>; createDatabaseMigration(data: Partial, throwErrorIfExists?: boolean): Promise; updateDatabaseMigration(data: Partial): Promise; fetchDatabaseMigration(tag: string): Promise; fetchDatabaseMigrations(databaseTag: string): Promise>; createDatabaseTrigger(data: Partial, throwErrorIfExists?: boolean): Promise; updateDatabaseTrigger(data: Partial): Promise; fetchDatabaseTrigger(tag: string): Promise; fetchDatabaseTriggers(databaseTag: string): Promise>; deleteDatabaseTrigger(tag: string): Promise; createGraph(data: Partial, throwErrorIfExists?: boolean): Promise; updateGraph(tag: string, data: Partial): Promise; fetchGraph(tag: string): Promise; fetchGraphs(): Promise>; deleteGraph(tag: string): Promise; createGraphAction(graphTag: string, data: any): Promise; updateGraphAction(graphTag: string, actionTag: string, data: any): Promise; fetchGraphAction(graphTag: string, actionTag: string): Promise; fetchGraphActions(graphTag: string): Promise>; deleteGraphAction(graphTag: string, actionTag: string): Promise; createVectorAction(vectorTag: string, data: Partial): Promise; updateVectorAction(vectorTag: string, data: Partial): Promise; fetchVectorAction(vectorTag: string, actionTag: string): Promise; fetchVectorActions(vectorTag: string): Promise>; deleteVectorAction(vectorTag: string, actionTag: string): Promise; createJob(data: Partial, throwErrorIfExists?: boolean): Promise; updateJob(tag: string, data: Partial): Promise; fetchJob(tag: string): Promise; fetchJobs(): Promise>; createHealthcheck(data: Partial): Promise; updateHealthcheck(tag: string, data: Partial): Promise; updateHealthcheckStatuses(productTag: string, checks: Array<{ tag: string; environments: Array & { slug: string; }>; }>): Promise; fetchHealthcheck(access_tag: string, tag: string): Promise; fetchHealthchecks(access_tag: string): Promise>; fetchProductHealthchecks(): Promise>; createFeature(data: Partial, throwErrorIfExists?: boolean): Promise; updateFeature(tag: string, data: Partial): Promise; fetchFeature(tag: string): Promise; fetchFeatures(): Promise>; deleteFeature(tag: string): Promise; createAppAccessTag(app_tag: string, known_app_id?: string): Promise; extractStages(input: string): Array; updateDataValidation(tag: string, update: Partial): Promise; fetchStorageFiles(filter: IFetchFilesPayload): Promise>; fetchSessionUser(ductape_user_id: string): Promise; } export default class ProductsBuilderService implements IProductsBuilderService { private user_id; private workspace_id; private workspace; private private_key; private workspace_private_key; private product_id; private token; private app_id; private public_key; private access_key; private session; private product; private userApi; private appApi; private webhooksApi; private productApi; private workspaceApi; private inputsService; private thirdPartyApps; private isQuotaFallbackInput; private redisClient?; private queues; private env_type; /** In-memory cache for the current product run (cleared on init) to avoid repeated API calls in workflows */ private brokerCache; private envCache; private readonly bootstrapCache; /** Only log when DUCTAPE_DEBUG is set (avoids sync I/O cost in feature hot path) */ private static _debug; private _debugLog; constructor({ workspace_id, public_key, user_id, token, env_type, redis_client, queues, access_key, workspace_private_key }: IBuilderInit); private applyBootstrapProductContext; private cachedBootstrap; fetchPrivateKey(): string; fetchWorkspaceId(): string; fetchProductId(): string; private requireProductId; createHealthcheck(data: Partial): Promise; updateHealthcheck(tag: string, data: Partial): Promise; /** * Persist monitor results without re-validating or re-encrypting the probe payload. * This is used by the local SDK's batched Redis-to-backend status flush. */ updateHealthcheckStatuses(productTag: string, checks: Array<{ tag: string; environments: Array & { slug: string; }>; }>): Promise; fetchHealthcheck(access_tag: string, tag: string, throwError?: boolean): Promise; fetchHealthchecks(access_tag: string, throwError?: boolean): Promise>; fetchProductHealthchecks(): Promise>; /** Validate quota/fallback provider references a registered product healthcheck component. */ validateProviderHealthcheckTag(option: { healthcheck?: string; check_interval?: number; }): Promise; /** Validate a quota/fallback action provider (app action or product feature). */ validateQuotaFallbackProvider(option: { type?: string; app?: string | null; event: string; healthcheck?: string; check_interval?: number; }): Promise; /** Keep in-memory product component arrays in sync after component CRUD (components API can lag). */ private mergeProductComponent; /** * Validate app healthchecks against the product's connected app and its selected action. * Every environment carries an explicit payload, including `{}` for actions with no inputs. */ private validateAppHealthcheckSchema; /** * Create a healthcheck from a schema (e.g. from resilience health.define/create). * Persists as product component so processor healthcheck workers and health.list/fetch see it. * Env inputs (probe/action/feature input) are encrypted with the product private key using * SHA-256 key derivation + AES (see processor.utils encrypt/decrypt). */ createHealthcheckFromSchema(schema: { tag: string; name?: string; description?: string; probe?: any; interval: number; retries: number; envs: Array<{ slug: string; input?: any; [k: string]: any; }>; onFailure?: any; }): Promise; updateHealthcheckFromSchema(schema: { tag: string; name?: string; description?: string; probe?: any; interval: number; retries: number; envs: Array<{ slug: string; input?: any; [k: string]: any; }>; onFailure?: any; }): Promise; updateDataValidation(selector: string, update: Partial): Promise; createProduct(data: ICreateProductsBuilder): Promise; initializeWorkspace(subCheck?: boolean): Promise; /** * Get the workspace private key for secrets encryption * @returns The workspace private key or null if not available */ getWorkspacePrivateKey(): string | null; initializeProduct(product_id: string): Promise; initializeProductByTag(tag: string): Promise; /** * Refresh product-backed component state after an administrative mutation. * * ProductBuilder instances are cached by the proxy, so clearing only the * component caches is insufficient: fetchMessageBroker() would otherwise * repopulate them from the pre-mutation product snapshot. */ private refreshProductState; /** * Bootstrap action - ultra-lightweight API call to fetch action data needed for processAction * Replaces 5+ separate API calls: initializeProduct, fetchApp, fetchThirdPartyApp, fetchEnv, initializePricing * Returns only the minimal action data needed to execute */ bootstrapAction(params: IBootstrapActionParams): Promise; /** * Apply bootstrap action result to this builder (product_id + minimal product for fetchPrivateKey). * Used when bootstrap data is loaded from cache so fetchPrivateKey() and fetchProductId() work. */ applyBootstrapActionResult(result: IBootstrapActionResponse, product_tag?: string): void; bootstrapNotification(params: IBootstrapNotificationParams): Promise; bootstrapStorage(params: IBootstrapStorageParams): Promise; bootstrapSession(params: IBootstrapSessionParams): Promise; bootstrapDatabase(params: IBootstrapDatabaseParams): Promise; bootstrapBroker(params: IBootstrapBrokerParams): Promise; bootstrapGraph(params: IBootstrapGraphParams): Promise; bootstrapVector(params: IBootstrapVectorParams): Promise; bootstrapResilience(params: IBootstrapResilienceParams): Promise; bootstrapIntelligence(params: IBootstrapIntelligenceParams): Promise; /** * Bootstrap feature - fetch all action/notification/storage data for multiple steps in one API call */ bootstrapFeature(params: Omit): Promise>; generateExecutablePayload(params: IGenerateExecutablePayloadParams): Promise; updateProduct(data: Partial): Promise; private createNewProduct; checkIfProductExists(name: string): Promise; fetchProduct(): Promise; createSession(data: Partial, throwErrorIfExists?: boolean): Promise; updateSession(tag: string, data: Partial): Promise; fetchSessions(version?: string): Promise>; fetchSession(tag: string): Promise; deleteSession(tag: string): Promise; createMessageBrokerTopic(data: Partial, throwErrorIfExists?: boolean): Promise; updateMessageBrokerTopic(data: Partial): Promise; fetchMessageBrokerTopic(tag: string, throwErrorIfExists?: boolean): Promise; fetchMessageBrokerTopics(messageBrokerTag: string): Promise>; createMessageBrokerProducer(data: Partial): Promise; updateMessageBrokerProducer(data: Partial): Promise; fetchMessageBrokerProducer(brokerTag: string, tag: string): Promise; fetchMessageBrokerProducers(messageBrokerTag: string): Promise>; createMessageBrokerConsumer(data: Partial): Promise; updateMessageBrokerConsumer(data: Partial): Promise; fetchMessageBrokerConsumer(brokerTag: string, tag: string): Promise; fetchMessageBrokerConsumers(messageBrokerTag: string): Promise>; validateQuotaFallbackInputAndOutput(data: Partial | Partial, type: string): Promise; validateQuotaFallbackInput(option: IQuotaOptions | IFallbackOptions, input: Record, type: string): Promise; checkKeyValuesInput(keyValues: Array, input: Record, type: string): void; checkActionQuotaFallbackInput(sample: ISample, obj: any, featureInput: Record, type: string): void; checkFuncArgsForInputs(value: string, input: Record, type: string): void; checkInput(value: string, input: Record, type: string): void; validateQuotaFallbackOutput(option: IQuotaOptions | IFallbackOptions, pastResponse: Record | null, input: Record, type: string): Promise; checkFuncArgsForResponse(value: string, output: Record, input: Record, type: string): void; checkResponse(value: string, output: Record, input: Record, type: string): void; createQuota(data: Partial): Promise; updateQuota(tag: string, data: Partial): Promise; fetchQuotas(version?: string): Promise>; fetchQuota(tag: string, version?: string): Promise; deleteQuota(tag: string): Promise; createFallback(data: Partial): Promise; updateFallback(tag: string, data: Partial): Promise; fetchFallbacks(version?: string): Promise>; fetchFallback(tag: string, version?: string): Promise; deleteFallback(tag: string): Promise; createEnv(data: IProductEnv, throwErrorIfExists?: boolean): Promise; updateEnv(slug: string, data: Partial): Promise; fetchEnvs(version?: string): Promise>; fetchEnv(slug: string, refresh?: boolean): Promise; deleteEnv(slug: string): Promise; createMessageBroker(data: Partial, throwErrorIfExists?: boolean): Promise; updateMessageBroker(tag: string, data: Partial): Promise; fetchMessageBrokers(version?: string): Promise>; fetchMessageBroker(tag: string, version?: string): Promise; deleteMessageBroker(tag: string): Promise; fetchStorageFiles(filter: IFetchFilesPayload): Promise>; fetchSessionUsers(filter: IFetchUsersPayload): Promise>; createStorage(data: Partial, throwErrorIfExists?: boolean): Promise; updateStorage(tag: string, data: Partial): Promise; fetchStorages(version?: string): Promise>; fetchStorage(tag: string, version?: string): Promise; deleteStorage(tag: string): Promise; /** * Create a new vector database configuration * @param data Vector database configuration * @param throwErrorIfExists Whether to throw error if vector config already exists */ createVector(data: Partial, throwErrorIfExists?: boolean): Promise; /** * Update an existing vector database configuration * @param tag Vector config tag * @param data Updated vector configuration */ updateVector(tag: string, data: Partial): Promise; /** * Fetch all vector database configurations * @param version Optional version */ fetchVectors(version?: string): Promise>; /** * Fetch a specific vector database configuration by tag * @param tag Vector config tag * @param version Optional version */ fetchVector(tag: string, version?: string): Promise; /** * Delete a vector database configuration * @param tag Vector config tag */ deleteVector(tag: string): Promise; /** * Create a new vector action * @param vectorTag Vector database tag * @param data Vector action data * @returns Created vector action */ createVectorAction(vectorTag: string, data: Partial): Promise; /** * Update an existing vector action * @param vectorTag Vector database tag * @param data Vector action update data (must include tag) * @returns Updated vector action */ updateVectorAction(vectorTag: string, data: Partial): Promise; /** * Fetch a specific vector action * @param vectorTag Vector database tag * @param actionTag Action tag * @returns Vector action or null */ fetchVectorAction(vectorTag: string, actionTag: string): Promise; /** * Fetch all vector actions for a vector database * @param vectorTag Vector database tag * @returns Array of vector actions */ fetchVectorActions(vectorTag: string): Promise>; /** * Delete a vector action * @param vectorTag Vector database tag * @param actionTag Action tag to delete */ deleteVectorAction(vectorTag: string, actionTag: string): Promise; /** * Create a new agent configuration * @param data Agent configuration data * @param throwErrorIfExists Whether to throw an error if agent already exists */ createAgent(data: Partial, throwErrorIfExists?: boolean): Promise; /** * Update an existing agent configuration * @param tag Agent tag * @param data Updated agent configuration */ updateAgent(tag: string, data: Partial): Promise; /** * Fetch all agent configurations * @param version Optional version */ fetchAgents(version?: string): Promise>; /** * Fetch a specific agent configuration by tag * @param tag Agent tag * @param version Optional version */ fetchAgent(tag: string, version?: string): Promise; /** * Delete an agent configuration * @param tag Agent tag */ deleteAgent(tag: string): Promise; /** * Create a new LLM model configuration * API keys are automatically encrypted using the product's private key * @param data LLM model configuration * @param throwErrorIfExists Whether to throw error if model already exists */ createModel(data: Partial, throwErrorIfExists?: boolean): Promise; /** * Update an existing LLM model configuration * @param tag Model tag * @param data Updated model configuration */ updateModel(tag: string, data: Partial): Promise; /** * Fetch all LLM model configurations * @param version Optional version */ fetchModels(version?: string): Promise>; /** * Fetch a specific LLM model configuration by tag * @param tag Model tag * @param version Optional version */ fetchModel(tag: string, version?: string): Promise; /** * Delete an LLM model configuration * @param tag Model tag */ deleteModel(tag: string): Promise; private validateAppData; private validateVariablesSchema; private validateVariablesValues; /** * base_url placeholders ({{key}} / :key) are syntactically required for the URL to resolve * to something requestable — unlike custom app variables, there is no "optional" case here. */ private validateBaseUrlVariablesRequired; private validateAppEnvs; private validateAppAuth; createAppAccessTag(app_tag: string, known_app_id?: string): Promise; private accessAppIsLive; addApp(app: IProductApp, throwErrorIfExists?: boolean): Promise; fetchAppWebhooks(access_tag: string): Promise>; updateApp(access_tag: string, data: Partial): Promise; fetchApps(): Promise>; fetchApp(tag: string, throwErrorIfExists?: boolean): Promise; deleteApp(tag: string): Promise; createFunction(data: Partial, throwErrorIfExists?: boolean): Promise; updateFunction(tag: string, data: Partial): Promise; fetchFunctions(version?: string): Promise>; fetchFunction(tag: string, version?: string): Promise; deleteFunction(tag: string): Promise; createCache(data: Partial, throwErrorIfExists?: boolean): Promise; updateCache(tag: string, data: Partial): Promise; fetchCaches(version?: string): Promise>; fetchCache(tag: string, version?: string): Promise; deleteCache(tag: string): Promise; createNotification(data: Partial, throwErrorIfExists?: boolean): Promise; createNotificationMessage(data: Partial, throwErrorIfExists?: boolean): Promise; fetchNotificationMessage(tag: string, throwErrorIfExists?: boolean): Promise; fetchNotificationMessages(notificationTag: string, throwErrorIfExists?: boolean): Promise>; updateNotificationMessage(data: Partial): Promise; updateNotification(tag: string, data: Partial): Promise; fetchNotifications(version?: string): Promise>; fetchNotification(tag: string, version?: string): Promise; /** * Decrypt notification env channel configs (push_notifications, emails, callbacks, sms). * @param notification - notification with possibly encrypted env configs * @param privateKey - product private key; when omitted uses this.product.private_key (e.g. from fetch) */ private decryptNotificationChannelConfigs; deleteNotification(tag: string): Promise; validateSequenceInputParents(parent: string, sequence_index: number, sequence: Array): void; validateDBActionDataInput(data: ISequenceValidationContext, action: { filterData: IParsedSample[]; data: IParsedSample[]; template: string | object; filter: string | object; }, event_input: IDbActionRequest, event_index: number, sequence_index: number): Promise; validateNotificationDataInput(data: ISequenceValidationContext, action: { callback: IParsedSample[]; notification: IParsedSample[]; email: IParsedSample[]; sms: IParsedSample[]; }, event_input: INotificationRequest, event_index: number, sequence_index: number): Promise; validateActionDataInput(data: ISequenceValidationContext, action: IAppAction, event_input: Partial, event_index: number, sequence_index: number): Promise; validateActionInputData(data: IActionDataParserInput, skipSample?: boolean, option?: boolean, optionIndex?: number): Promise; parseActionEventInput(data: IParseActionEventInput): Promise; parseInputString(payload: IParseInputStringInput, meta: IParseInputStringMetaData): Promise; compareInputWithExpectedInput(datapoint: IParsedSample, found_input: IParsedSample, value: string): void; extractStages(input: string): Array; fetchSequenceEvent(sequence: IStepSequence, event: string): IStepEvent | null; fetchPriorSequence(meta: IParseInputStringMetaData, stage: string): IStepSequence; validateActionKeyPlacement(data: IParseActionEventInput): IParsedSample; fetchThirdPartyAppByAccessTag(access_tag: string): Promise; /** * When workspace access-tag lookup fails (common for product-scoped tags like ductape:paystack:ductape), * resolve the app via product-linked components or fetchAppByTag. */ private fetchThirdPartyAppByAppTagFallback; private resolveAppTagFromAccessReference; fetchThirdPartyAppActionByTag(actions: Array, action_tag: string): IAppAction; createDatabase(data: Partial, throwErrorIfExists?: boolean): Promise; updateDatabase(tag: string, data: Partial): Promise; fetchDatabases(): Promise>; fetchDatabase(tag: string): Promise; /** Resolve database config from in-memory product cache, falling back to API fetch. */ private resolveDatabaseConfig; private normalizeDatabaseTriggers; deleteDatabase(tag: string): Promise; createGraph(data: Partial, throwErrorIfExists?: boolean): Promise; updateGraph(tag: string, data: Partial): Promise; fetchGraphs(): Promise>; fetchGraph(tag: string): Promise; deleteGraph(tag: string): Promise; createGraphAction(graphTag: string, data: any): Promise; updateGraphAction(graphTag: string, actionTag: string, data: any): Promise; fetchGraphAction(graphTag: string, actionTag: string): Promise; fetchGraphActions(graphTag: string): Promise>; deleteGraphAction(graphTag: string, actionTag: string): Promise; createDatabaseAction(data: Partial, throwErrorIfExists?: boolean): Promise; fetchDatabaseAction(tag: string, throwErrorIfExists?: boolean): Promise; updateDatabaseAction(data: Partial): Promise; fetchDatabaseActions(databaseTag: string): Promise>; deleteDatabaseAction(tag: string): Promise; createDatabaseMigration(data: Partial, throwErrorIfExists?: boolean): Promise; /** * Process migration operations - handles both string and object formats * Strings are passed through as-is (raw SQL/CQL) * Objects are serialized for storage and executed by the migration engine */ private processMigrationOperations; updateDatabaseMigration(data: Partial): Promise; fetchDatabaseMigration(tag: string, throwError?: boolean): Promise; fetchDatabaseMigrations(databaseTag: string): Promise>; deleteDatabaseMigration(tag: string): Promise; createDatabaseTrigger(data: Partial, throwErrorIfExists?: boolean): Promise; updateDatabaseTrigger(data: Partial): Promise; fetchDatabaseTrigger(tag: string, throwError?: boolean): Promise; fetchDatabaseTriggers(databaseTag: string): Promise>; deleteDatabaseTrigger(tag: string): Promise; validateJobEvent(data: Partial): Promise; createJob(data: Partial, throwErrorIfExists?: boolean): Promise; updateJob(tag: string, data: Partial): Promise; fetchJobs(): Promise>; fetchJob(tag: string): Promise; deleteJob(tag: string): Promise; createFeature(data: Partial, throwErrorIfExists?: boolean): Promise; updateFeature(tag: string, data: Partial): Promise; fetchFeatures(): Promise>; fetchFeature(tag: string): Promise; deleteFeature(tag: string): Promise; private getUserAccess; fetchSessionUser(ductape_user_id: string): Promise; /** * Process storage config to store sensitive credentials as secrets * Format: STORAGE_{PRODUCT}_{STORAGE_TAG}_{ENV}_{KEY} * * Product parsing: split by ":", select first element * Storage tag: replace "-" with "_" */ private processStorageConfigSecrets; /** * Process message broker config to store sensitive credentials as secrets * Format: BROKER_{PRODUCT}_{BROKER_TAG}_{ENV}_{KEY} * * Product parsing: split by ":", select first element * Broker tag: replace "-" with "_" */ private processMessageBrokerConfigSecrets; /** * Process notification environment config to store sensitive credentials as secrets * Format: NOTIFIER_{PRODUCT}_{NOTIFIER_TAG}_{ENV}_{KEY} * * Product parsing: split by ":", select first element * Notifier tag: replace "-" with "_" */ private processNotificationEnvSecrets; /** * Store graph connection URL as a secret * Format: GRAPH_{PRODUCT}_{GRAPH_TAG}_{ENV}_URL */ private storeGraphConnectionUrlAsSecret; /** * Generate a secret key for vector configuration field * Format: VECTOR_{PRODUCT}_{ASSET_TAG}_{ENV}_{KEY} * * Where: * - PRODUCT = productTag.split('.')[1] (second part after workspace) * - ASSET_TAG = if vectorTag starts with same workspace prefix, use second part; otherwise sanitize full tag * - All parts are automatically capitalized */ private generateVectorSecretKey; /** * Store a vector field value as a secret if it exists and is not already a secret reference * @returns The secret reference if stored, or the original value */ private storeVectorFieldAsSecret; private storeVectorApiKeyAsSecret; private storeVectorEndpointAsSecret; /** * Store LLM model API key as a secret * Format: MODEL_{PRODUCT}_{MODEL_TAG}_{ENV}_API_KEY */ private storeModelApiKeyAsSecret; }