Files
AtreidesAssetsFree/tests/db/schema-snapshot.test.mjs
T

568 lines
26 KiB
JavaScript
Raw Normal View History

2026-10-29 11:57:29 +01:00
// Generated, do not edit. sha256:95b828575da8a035648fa6c5b1be9927259b17fc10e9fccfc392b7da47d8f94f
import { describe, it, before } from 'node:test';
import assert from 'node:assert/strict';
import { openBaselineDb } from '../helpers/baseline-db.mjs';
import { schemaVorm } from '../helpers/schema-vorm.mjs';
import { CONFIG } from '../../shared/config.js';
let REGELS;
before(() => {
const db = openBaselineDb();
REGELS = schemaVorm(db);
db.close();
});
describe('schema-snapshot', () => {
it('heeft de verwachte omvang', () => {
const nieuw = REGELS.filter(r => !VERWACHT.includes(r));
const weg = VERWACHT.filter(r => !REGELS.includes(r));
assert.deepEqual({ nieuw, weg }, { nieuw: [], weg: [] },
'de vorm van het schema is gewijzigd; genereer de snapshot opnieuw met scripts/schema-snapshot.mjs');
});
it('staat regel voor regel gelijk aan de vastgelegde vorm', () => {
assert.deepEqual(REGELS, VERWACHT);
});
it('hoort bij deze schemaversie', () => {
assert.equal(CONFIG.SCHEMA_VERSION, 128,'nieuwe schemaversie? dan hoort er een migratie bij (§8)');
});
});
const VERWACHT = [
"Account.closedAt: TEXT",
"Account.createdAt: TEXT",
"Account.description: TEXT",
"Account.id: INTEGER PK1",
"Account.isActive: INTEGER NOT NULL",
"Account.isOwnCustody: INTEGER NOT NULL",
"Account.kind: TEXT NOT NULL",
"Account.name: TEXT NOT NULL",
"Account.scanEnabled: INTEGER NOT NULL",
"Account.searchName: TEXT NOT NULL",
"Account.taxCategory: TEXT",
"Account.taxScope: TEXT",
"Account.updatedAt: TEXT",
"Account.wealthScope: TEXT",
"AiProposal.accountId -> Account.id ON DELETE CASCADE",
"AiProposal.accountId: INTEGER",
"AiProposal.accountKind: TEXT",
"AiProposal.amount: INTEGER",
"AiProposal.assetId -> Asset.id ON DELETE CASCADE",
"AiProposal.assetId: INTEGER",
"AiProposal.balance: INTEGER",
"AiProposal.createdAccountId -> Account.id ON DELETE SET NULL",
"AiProposal.createdAccountId: INTEGER",
"AiProposal.createdAt: TEXT NOT NULL",
"AiProposal.createdEventId -> Event.id ON DELETE SET NULL",
"AiProposal.createdEventId: INTEGER",
"AiProposal.createdValuationId -> Valuation.id ON DELETE SET NULL",
"AiProposal.createdValuationId: INTEGER",
"AiProposal.currency: TEXT",
"AiProposal.detail: TEXT",
"AiProposal.eventType: TEXT",
"AiProposal.fiatFee: REAL",
"AiProposal.fiatPrice: REAL",
"AiProposal.fromAccountId -> Account.id ON DELETE CASCADE",
"AiProposal.fromAccountId: INTEGER",
"AiProposal.id: INTEGER PK1",
"AiProposal.isOwnCustody: INTEGER",
"AiProposal.key: TEXT",
"AiProposal.kind: TEXT NOT NULL",
"AiProposal.name: TEXT",
"AiProposal.note: TEXT",
"AiProposal.observedAt: TEXT",
"AiProposal.resolvedAt: TEXT",
"AiProposal.scope: TEXT",
"AiProposal.status: TEXT NOT NULL",
"AiProposal.toAccountId -> Account.id ON DELETE CASCADE",
"AiProposal.toAccountId: INTEGER",
"AiProposal.unitFee: INTEGER",
"AiProposal.value: TEXT",
"AiToolCall.arguments: TEXT",
"AiToolCall.charactersOut: INTEGER",
"AiToolCall.client: TEXT",
"AiToolCall.detail: TEXT",
"AiToolCall.fieldsShared: TEXT",
"AiToolCall.id: INTEGER PK1",
"AiToolCall.occurredAt: TEXT NOT NULL",
"AiToolCall.outcome: TEXT NOT NULL",
"AiToolCall.serverVersion: TEXT",
"AiToolCall.sessionId: TEXT NOT NULL",
"AiToolCall.tool: TEXT NOT NULL",
"AiToolCallMessage.callId -> AiToolCall.id ON DELETE CASCADE",
"AiToolCallMessage.callId: INTEGER NOT NULL",
"AiToolCallMessage.id: INTEGER PK1",
"AiToolCallMessage.kind: TEXT NOT NULL",
"AiToolCallMessage.occurredAt: TEXT NOT NULL",
"AiToolCallMessage.text: TEXT NOT NULL",
"ApiCallMetric.bucketMinute: TEXT NOT NULL PK3",
"ApiCallMetric.capability: TEXT NOT NULL PK2",
"ApiCallMetric.failCount: INTEGER NOT NULL",
"ApiCallMetric.maxLatencyMs: INTEGER NOT NULL",
"ApiCallMetric.okCount: INTEGER NOT NULL",
"ApiCallMetric.providerId -> Provider.id ON DELETE CASCADE",
"ApiCallMetric.providerId: INTEGER NOT NULL PK1",
"ApiCallMetric.sumLatencyMs: INTEGER NOT NULL",
"Asset.balanceCapture: INTEGER",
"Asset.createdAt: TEXT",
"Asset.decimals: INTEGER NOT NULL",
"Asset.description: TEXT",
"Asset.displayUnit: TEXT NOT NULL",
"Asset.id: INTEGER PK1",
"Asset.kind: TEXT NOT NULL",
"Asset.name: TEXT NOT NULL",
"Asset.searchName: TEXT NOT NULL",
"Asset.subunit: TEXT",
"Asset.symbol: TEXT NOT NULL",
"Asset.taxCategory: TEXT",
"Asset.taxScope: TEXT",
"Asset.unit: TEXT NOT NULL",
"Asset.updatedAt: TEXT",
"AssetNote.assetId -> Asset.id ON DELETE CASCADE",
"AssetNote.assetId: INTEGER NOT NULL",
"AssetNote.body: TEXT NOT NULL",
"AssetNote.createdAt: TEXT NOT NULL",
"AssetNote.id: INTEGER PK1",
"BusSignal.id: INTEGER PK1",
"BusSignal.name: TEXT NOT NULL",
"BusSignal.occurredAt: TEXT NOT NULL",
"ChangeLog.changes: TEXT NOT NULL",
"ChangeLog.id: INTEGER PK1",
"ChangeLog.occurredAt: TEXT NOT NULL",
"ChangeLog.operation: TEXT NOT NULL",
"ChangeLog.origin: TEXT NOT NULL",
"ChangeLog.originId: INTEGER",
"ChangeLog.rowId: INTEGER NOT NULL",
"ChangeLog.tableName: TEXT NOT NULL",
"Command.claimedAt: TEXT",
"Command.claimedBy: TEXT",
"Command.createdAt: TEXT NOT NULL",
"Command.detail: TEXT",
"Command.expiresAt: TEXT",
"Command.id: INTEGER PK1",
"Command.kind: TEXT NOT NULL",
"Command.payload: TEXT",
"Command.resolvedAt: TEXT",
"Command.state: TEXT NOT NULL",
"Connection.createdAt: TEXT NOT NULL",
"Connection.description: TEXT",
"Connection.id: INTEGER PK1",
"Connection.isActive: INTEGER NOT NULL",
"Connection.isSystem: INTEGER NOT NULL",
"Connection.kind: TEXT NOT NULL",
"Connection.lastCheckedAt: TEXT",
"Connection.lastStatus: TEXT",
"Connection.name: TEXT NOT NULL",
"Connection.searchName: TEXT NOT NULL",
"Connection.updatedAt: TEXT NOT NULL",
"Connection.url: TEXT NOT NULL",
"DashboardProfile.createdAt: TEXT NOT NULL",
"DashboardProfile.description: TEXT",
"DashboardProfile.id: INTEGER PK1",
"DashboardProfile.isActive: INTEGER NOT NULL",
"DashboardProfile.isSystem: INTEGER NOT NULL",
"DashboardProfile.name: TEXT NOT NULL",
"DashboardProfile.searchName: TEXT NOT NULL",
"DashboardProfile.sortOrder: INTEGER NOT NULL",
"DashboardProfile.updatedAt: TEXT NOT NULL",
"DashboardWidget.assetId -> Asset.id ON DELETE CASCADE",
"DashboardWidget.assetId: INTEGER",
"DashboardWidget.createdAt: TEXT",
"DashboardWidget.gridX: INTEGER NOT NULL",
"DashboardWidget.gridY: INTEGER NOT NULL",
"DashboardWidget.id: INTEGER PK1",
"DashboardWidget.instanceKey: TEXT NOT NULL",
"DashboardWidget.profileId -> DashboardProfile.id ON DELETE CASCADE",
"DashboardWidget.profileId: INTEGER NOT NULL",
"DashboardWidget.settings: TEXT",
"DashboardWidget.spanHeight: INTEGER",
"DashboardWidget.spanWidth: INTEGER NOT NULL",
"DashboardWidget.type: TEXT NOT NULL",
"Event.amount: INTEGER NOT NULL",
"Event.assetId -> Asset.id ON DELETE CASCADE",
"Event.assetId: INTEGER NOT NULL",
"Event.createdAt: TEXT NOT NULL",
"Event.externalAddress: TEXT",
"Event.fiatFee: REAL",
"Event.fiatPrice: REAL",
"Event.fromAccountId -> Account.id ON DELETE NO ACTION",
"Event.fromAccountId: INTEGER",
"Event.id: INTEGER PK1",
"Event.importReference: TEXT",
"Event.note: TEXT",
"Event.occurredAt: TEXT NOT NULL",
"Event.priceOrigin: TEXT",
"Event.productCount: INTEGER",
"Event.productId -> MetalProduct.id ON DELETE NO ACTION",
"Event.productId: INTEGER",
"Event.source: TEXT NOT NULL",
"Event.toAccountId -> Account.id ON DELETE NO ACTION",
"Event.toAccountId: INTEGER",
"Event.type: TEXT NOT NULL",
"Event.unitFee: INTEGER",
"Event.updatedAt: TEXT",
"HygieneAcceptance.createdAt: TEXT NOT NULL",
"HygieneAcceptance.fingerprint: TEXT NOT NULL",
"HygieneAcceptance.id: INTEGER PK1",
"HygieneAcceptance.kind: TEXT NOT NULL",
"HygieneAcceptance.note: TEXT",
"HygieneAcceptance.summary: TEXT NOT NULL",
"INDEX IxAccountSearchName ON Account(searchName)",
"INDEX IxAiProposalAccountId ON AiProposal(accountId)",
"INDEX IxAiProposalAssetId ON AiProposal(assetId)",
"INDEX IxAiProposalCreatedAccountId ON AiProposal(createdAccountId)",
"INDEX IxAiProposalCreatedEventId ON AiProposal(createdEventId)",
"INDEX IxAiProposalCreatedValuationId ON AiProposal(createdValuationId)",
"INDEX IxAiProposalFromAccountId ON AiProposal(fromAccountId)",
"INDEX IxAiProposalStatus ON AiProposal(status)",
"INDEX IxAiProposalToAccountId ON AiProposal(toAccountId)",
"INDEX IxAiToolCallMessageCallId ON AiToolCallMessage(callId)",
"INDEX IxAiToolCallOccurredAt ON AiToolCall(occurredAt)",
"INDEX IxAssetSearchName ON Asset(searchName)",
"INDEX IxChangeLogOccurredAt ON ChangeLog(occurredAt)",
"INDEX IxChangeLogTableNameRowId ON ChangeLog(tableName,rowId)",
"INDEX IxDashboardWidgetAssetId ON DashboardWidget(assetId)",
"INDEX IxEventAssetId ON Event(assetId)",
"INDEX IxEventExternalAddress ON Event(externalAddress)",
"INDEX IxEventFromAccountId ON Event(fromAccountId)",
"INDEX IxEventImportReference ON Event(importReference)",
"INDEX IxEventOccurredAt ON Event(occurredAt)",
"INDEX IxEventProductId ON Event(productId)",
"INDEX IxEventToAccountId ON Event(toAccountId)",
"INDEX IxEventType ON Event(type)",
"INDEX IxHygieneAcceptanceKind ON HygieneAcceptance(kind)",
"INDEX IxIgnoredPriceGapAssetId ON IgnoredPriceGap(assetId)",
"INDEX IxImportBatchAccountId ON ImportBatch(accountId)",
"INDEX IxIntegrationCallOccurredAt ON IntegrationCall(occurredAt)",
"INDEX IxInterestCreditEventId ON InterestCredit(eventId)",
"INDEX IxInterestScheduleAccountId ON InterestSchedule(accountId)",
"INDEX IxInterestSchedulePayoutAssetId ON InterestSchedule(payoutAssetId)",
"INDEX IxInterestSchedulePrincipalAssetId ON InterestSchedule(principalAssetId)",
"INDEX IxNotificationKind ON Notification(kind)",
"INDEX IxPriceAbsenceProviderId ON PriceAbsence(providerId)",
"INDEX IxPriceHistoryAssetIdObservedAt ON PriceHistory(assetId,observedAt)",
"INDEX IxPriceHistoryProviderId ON PriceHistory(providerId)",
"INDEX IxPriceSourceProviderId ON PriceSource(providerId)",
"INDEX IxProviderCoverageSymbol ON ProviderCoverage(symbol)",
"INDEX IxProviderOutputMapProviderIdCapability ON ProviderOutputMap(providerId,capability)",
"INDEX IxProviderSearchName ON Provider(searchName)",
"INDEX IxReconcileProposalAccountId ON ReconcileProposal(accountId)",
"INDEX IxReconcileProposalAssetId ON ReconcileProposal(assetId)",
"INDEX IxReconcileProposalResolvedEventId ON ReconcileProposal(resolvedEventId)",
"INDEX IxReconcileProposalStatus ON ReconcileProposal(status)",
"INDEX IxReconcileProposalWalletTransactionId ON ReconcileProposal(walletTransactionId)",
"INDEX IxScanLogAccountIdScannedAt ON ScanLog(accountId,scannedAt)",
"INDEX IxValuationAccountId ON Valuation(accountId)",
"INDEX IxWalletAddressAccountId ON WalletAddress(accountId)",
"INDEX IxWalletAddressSourceId ON WalletAddress(sourceId)",
"INDEX IxWalletSourceAccountId ON WalletSource(accountId)",
"INDEX IxWalletSourceConnectionId ON WalletSource(connectionId)",
"INDEX IxWalletTransactionAccountId ON WalletTransaction(accountId)",
"INDEX IxWalletTransactionEventLinkEventId ON WalletTransactionEventLink(eventId)",
"INDEX IxWalletTransactionLabelId ON WalletTransaction(labelId)",
"INDEX IxWalletTransactionSourceId ON WalletTransaction(sourceId)",
"IgnoredPriceGap.assetId -> Asset.id ON DELETE CASCADE",
"IgnoredPriceGap.assetId: INTEGER NOT NULL",
"IgnoredPriceGap.createdAt: TEXT NOT NULL",
"IgnoredPriceGap.fromDay: TEXT NOT NULL",
"IgnoredPriceGap.id: INTEGER PK1",
"IgnoredPriceGap.untilDay: TEXT NOT NULL",
"ImportBatch.accountId -> Account.id ON DELETE SET NULL",
"ImportBatch.accountId: INTEGER",
"ImportBatch.filename: TEXT NOT NULL",
"ImportBatch.id: INTEGER PK1",
"ImportBatch.importedAt: TEXT NOT NULL",
"ImportBatch.origin: TEXT",
"ImportBatch.rawData: TEXT",
"ImportBatch.rowCount: INTEGER NOT NULL",
"IntegrationCall.detail: TEXT",
"IntegrationCall.errorKey: TEXT",
"IntegrationCall.httpStatus: INTEGER",
"IntegrationCall.id: INTEGER PK1",
"IntegrationCall.latencyMs: INTEGER",
"IntegrationCall.occurredAt: TEXT NOT NULL",
"IntegrationCall.operation: TEXT NOT NULL",
"IntegrationCall.outcome: TEXT NOT NULL",
"IntegrationCall.providerKey: TEXT",
"IntegrationCall.requestId: TEXT",
"IntegrationCall.subject: TEXT",
"IntegrationCall.target: TEXT NOT NULL",
"InterestCredit.createdAt: TEXT NOT NULL",
"InterestCredit.eventId -> Event.id ON DELETE CASCADE",
"InterestCredit.eventId: INTEGER",
"InterestCredit.id: INTEGER PK1",
"InterestCredit.periodEnd: TEXT NOT NULL",
"InterestCredit.periodStart: TEXT NOT NULL",
"InterestCredit.scheduleId -> InterestSchedule.id ON DELETE CASCADE",
"InterestCredit.scheduleId: INTEGER NOT NULL",
"InterestCredit.status: TEXT NOT NULL",
"InterestCredit.updatedAt: TEXT",
"InterestPeriod.annualRate: REAL NOT NULL",
"InterestPeriod.createdAt: TEXT",
"InterestPeriod.id: INTEGER PK1",
"InterestPeriod.scheduleId -> InterestSchedule.id ON DELETE CASCADE",
"InterestPeriod.scheduleId: INTEGER NOT NULL",
"InterestPeriod.startsOn: TEXT NOT NULL",
"InterestPeriod.updatedAt: TEXT",
"InterestSchedule.accountId -> Account.id ON DELETE CASCADE",
"InterestSchedule.accountId: INTEGER NOT NULL",
"InterestSchedule.annualRate: REAL",
"InterestSchedule.compounding: INTEGER NOT NULL",
"InterestSchedule.createdAt: TEXT NOT NULL",
"InterestSchedule.creditCadence: TEXT",
"InterestSchedule.creditDayOfMonth: INTEGER",
"InterestSchedule.creditWeekday: INTEGER",
"InterestSchedule.endsOn: TEXT",
"InterestSchedule.id: INTEGER PK1",
"InterestSchedule.note: TEXT",
"InterestSchedule.payoutAssetId -> Asset.id ON DELETE CASCADE",
"InterestSchedule.payoutAssetId: INTEGER NOT NULL",
"InterestSchedule.principalAmount: INTEGER",
"InterestSchedule.principalAssetId -> Asset.id ON DELETE NO ACTION",
"InterestSchedule.principalAssetId: INTEGER",
"InterestSchedule.rateKind: TEXT NOT NULL",
"InterestSchedule.startsOn: TEXT NOT NULL",
"InterestSchedule.updatedAt: TEXT",
"Label.createdAt: TEXT",
"Label.description: TEXT",
"Label.id: INTEGER PK1",
"Label.name: TEXT NOT NULL",
"Label.searchName: TEXT NOT NULL",
"Label.updatedAt: TEXT",
"MetalProduct.assetId -> Asset.id ON DELETE CASCADE",
"MetalProduct.assetId: INTEGER NOT NULL",
"MetalProduct.createdAt: TEXT",
"MetalProduct.description: TEXT",
"MetalProduct.fineGrams: INTEGER NOT NULL",
"MetalProduct.form: TEXT NOT NULL",
"MetalProduct.id: INTEGER PK1",
"MetalProduct.name: TEXT NOT NULL",
"MetalProduct.searchName: TEXT NOT NULL",
"MetalProduct.updatedAt: TEXT",
"Notification.count: INTEGER NOT NULL",
"Notification.createdAt: TEXT NOT NULL",
"Notification.dismissedAt: TEXT",
"Notification.highWater: INTEGER NOT NULL",
"Notification.id: INTEGER PK1",
"Notification.kind: TEXT NOT NULL",
"Portfolio.baseCurrency: TEXT NOT NULL",
"Portfolio.createdAt: TEXT",
"Portfolio.id: INTEGER PK1",
"Preference.createdAt: TEXT",
"Preference.key: TEXT NOT NULL PK2",
"Preference.scope: TEXT NOT NULL PK1",
"Preference.value: TEXT NOT NULL",
"PriceAbsence.assetId -> Asset.id ON DELETE CASCADE",
"PriceAbsence.assetId: INTEGER NOT NULL",
"PriceAbsence.createdAt: TEXT NOT NULL",
"PriceAbsence.day: TEXT NOT NULL",
"PriceAbsence.id: INTEGER PK1",
"PriceAbsence.providerId -> Provider.id ON DELETE CASCADE",
"PriceAbsence.providerId: INTEGER NOT NULL",
"PriceHistory.assetId -> Asset.id ON DELETE CASCADE",
"PriceHistory.assetId: INTEGER NOT NULL",
"PriceHistory.createdAt: TEXT",
"PriceHistory.fiatPrice: REAL NOT NULL",
"PriceHistory.id: INTEGER PK1",
"PriceHistory.observedAt: TEXT NOT NULL",
"PriceHistory.providerId -> Provider.id ON DELETE RESTRICT",
"PriceHistory.providerId: INTEGER NOT NULL",
"PriceHistory.resolution: TEXT NOT NULL",
"PriceHistory.sourceName: TEXT",
"PriceHistory.updatedAt: TEXT",
"PriceSource.assetId -> Asset.id ON DELETE CASCADE",
"PriceSource.assetId: INTEGER NOT NULL",
"PriceSource.capability: TEXT NOT NULL",
"PriceSource.createdAt: TEXT",
"PriceSource.id: INTEGER PK1",
"PriceSource.providerId -> Provider.id ON DELETE RESTRICT",
"PriceSource.providerId: INTEGER NOT NULL",
"PriceSource.rank: INTEGER",
"PriceSource.status: TEXT NOT NULL",
"Provider.authenticationHeaderName: TEXT",
"Provider.authenticationKind: TEXT NOT NULL",
"Provider.authenticationParameterName: TEXT",
"Provider.authenticationRequired: INTEGER NOT NULL",
"Provider.baseUrl: TEXT NOT NULL",
"Provider.createdAt: TEXT NOT NULL",
"Provider.description: TEXT",
"Provider.id: INTEGER PK1",
"Provider.isActive: INTEGER NOT NULL",
"Provider.isSeed: INTEGER NOT NULL",
"Provider.isSystem: INTEGER NOT NULL",
"Provider.key: TEXT NOT NULL",
"Provider.name: TEXT NOT NULL",
"Provider.searchName: TEXT NOT NULL",
"ProviderAuthenticationHmac.createdAt: TEXT",
"ProviderAuthenticationHmac.encoding: TEXT NOT NULL",
"ProviderAuthenticationHmac.hashAlgorithm: TEXT NOT NULL",
"ProviderAuthenticationHmac.keyHeader: TEXT NOT NULL",
"ProviderAuthenticationHmac.messageParts: TEXT NOT NULL",
"ProviderAuthenticationHmac.providerId -> Provider.id ON DELETE CASCADE",
"ProviderAuthenticationHmac.providerId: INTEGER PK1",
"ProviderAuthenticationHmac.signatureHeader: TEXT NOT NULL",
"ProviderAuthenticationHmac.timestampHeader: TEXT NOT NULL",
"ProviderAuthenticationHmac.windowHeader: TEXT",
"ProviderAuthenticationHmac.windowMs: INTEGER",
"ProviderCallLimit.callsPerMonth: INTEGER NOT NULL",
"ProviderCallLimit.createdAt: TEXT",
"ProviderCallLimit.providerId -> Provider.id ON DELETE CASCADE",
"ProviderCallLimit.providerId: INTEGER PK1",
"ProviderCoverage.createdAt: TEXT",
"ProviderCoverage.id: INTEGER PK1",
"ProviderCoverage.providerId -> Provider.id ON DELETE CASCADE",
"ProviderCoverage.providerId: INTEGER NOT NULL",
"ProviderCoverage.symbol: TEXT NOT NULL",
"ProviderEndpoint.capability: TEXT NOT NULL",
"ProviderEndpoint.createdAt: TEXT",
"ProviderEndpoint.id: INTEGER PK1",
"ProviderEndpoint.method: TEXT NOT NULL",
"ProviderEndpoint.minIntervalSeconds: INTEGER",
"ProviderEndpoint.pathTemplate: TEXT NOT NULL",
"ProviderEndpoint.providerId -> Provider.id ON DELETE CASCADE",
"ProviderEndpoint.providerId: INTEGER NOT NULL",
"ProviderEndpoint.queryTemplate: TEXT",
"ProviderEndpoint.quoteCurrency: TEXT",
"ProviderFixedRate.createdAt: TEXT",
"ProviderFixedRate.fiatPrice: REAL NOT NULL",
"ProviderFixedRate.providerId -> Provider.id ON DELETE CASCADE",
"ProviderFixedRate.providerId: INTEGER PK1",
"ProviderInputMap.createdAt: TEXT",
"ProviderInputMap.externalId: TEXT NOT NULL",
"ProviderInputMap.id: INTEGER PK1",
"ProviderInputMap.isCatchAll: INTEGER NOT NULL",
"ProviderInputMap.providerId -> Provider.id ON DELETE CASCADE",
"ProviderInputMap.providerId: INTEGER NOT NULL",
"ProviderInputMap.quoteUnit: TEXT",
"ProviderInputMap.symbol: TEXT",
"ProviderOutputMap.capability: TEXT NOT NULL",
"ProviderOutputMap.createdAt: TEXT",
"ProviderOutputMap.id: INTEGER PK1",
"ProviderOutputMap.internalField: TEXT NOT NULL",
"ProviderOutputMap.jsonPath: TEXT NOT NULL",
"ProviderOutputMap.providerId -> Provider.id ON DELETE CASCADE",
"ProviderOutputMap.providerId: INTEGER NOT NULL",
"ProviderOutputMap.transform: TEXT NOT NULL",
"ReconcileProposal.accountId -> Account.id ON DELETE CASCADE",
"ReconcileProposal.accountId: INTEGER NOT NULL",
"ReconcileProposal.amount: INTEGER NOT NULL",
"ReconcileProposal.assetId -> Asset.id ON DELETE CASCADE",
"ReconcileProposal.assetId: INTEGER NOT NULL",
"ReconcileProposal.detectedAt: TEXT NOT NULL",
"ReconcileProposal.direction: TEXT NOT NULL",
"ReconcileProposal.id: INTEGER PK1",
"ReconcileProposal.resolvedEventId -> Event.id ON DELETE SET NULL",
"ReconcileProposal.resolvedEventId: INTEGER",
"ReconcileProposal.status: TEXT NOT NULL",
"ReconcileProposal.suggestedType: TEXT NOT NULL",
"ReconcileProposal.transactionHash: TEXT",
"ReconcileProposal.walletTransactionId -> WalletTransaction.id ON DELETE CASCADE",
"ReconcileProposal.walletTransactionId: INTEGER",
"ScanLog.accountId -> Account.id ON DELETE CASCADE",
"ScanLog.accountId: INTEGER NOT NULL",
"ScanLog.addressesFound: INTEGER",
"ScanLog.balanceFound: INTEGER",
"ScanLog.id: INTEGER PK1",
"ScanLog.proposalsCreated: INTEGER",
"ScanLog.rawData: TEXT",
"ScanLog.scannedAt: TEXT NOT NULL",
"ScanLog.status: TEXT NOT NULL",
"Schema.id: INTEGER PK1",
"Schema.version: INTEGER NOT NULL",
"UNIQUE INDEX UxAssetNoteAssetId ON AssetNote(assetId)",
"UNIQUE INDEX UxConnectionActiveBtcExplorer ON Connection(kind) PARTIAL",
"UNIQUE INDEX UxDashboardProfileActive ON DashboardProfile(isActive) PARTIAL",
"UNIQUE INDEX UxHygieneAcceptanceFingerprint ON HygieneAcceptance(fingerprint)",
"UNIQUE INDEX UxPriceAbsenceAssetIdProviderIdDay ON PriceAbsence(assetId,providerId,day)",
"UNIQUE INDEX UxProviderInputMapCatchAll ON ProviderInputMap(providerId) PARTIAL",
"UNIQUE INDEX UxReconcileProposalLink ON ReconcileProposal(walletTransactionId,resolvedEventId) PARTIAL",
"UNIQUE INDEX UxWalletTransactionAccountIdTxid ON WalletTransaction(accountId,txid) PARTIAL",
"UNIQUE INDEX UxWalletTransactionSourceIdTxid ON WalletTransaction(sourceId,txid) PARTIAL",
"UNIQUE INDEX sqlite_autoindex_ApiCallMetric_1 ON ApiCallMetric(providerId,capability,bucketMinute)",
"UNIQUE INDEX sqlite_autoindex_Asset_1 ON Asset(symbol) [uit UNIQUE]",
"UNIQUE INDEX sqlite_autoindex_Connection_1 ON Connection(kind,searchName) [uit UNIQUE]",
"UNIQUE INDEX sqlite_autoindex_DashboardProfile_1 ON DashboardProfile(searchName) [uit UNIQUE]",
"UNIQUE INDEX sqlite_autoindex_DashboardWidget_1 ON DashboardWidget(profileId,instanceKey) [uit UNIQUE]",
"UNIQUE INDEX sqlite_autoindex_InterestCredit_1 ON InterestCredit(scheduleId,periodEnd) [uit UNIQUE]",
"UNIQUE INDEX sqlite_autoindex_InterestPeriod_1 ON InterestPeriod(scheduleId,startsOn) [uit UNIQUE]",
"UNIQUE INDEX sqlite_autoindex_Label_1 ON Label(searchName) [uit UNIQUE]",
"UNIQUE INDEX sqlite_autoindex_MetalProduct_1 ON MetalProduct(assetId,searchName) [uit UNIQUE]",
"UNIQUE INDEX sqlite_autoindex_Preference_1 ON Preference(scope,key)",
"UNIQUE INDEX sqlite_autoindex_PriceHistory_1 ON PriceHistory(assetId,providerId,observedAt,resolution) [uit UNIQUE]",
"UNIQUE INDEX sqlite_autoindex_PriceSource_1 ON PriceSource(assetId,capability,providerId) [uit UNIQUE]",
"UNIQUE INDEX sqlite_autoindex_PriceSource_2 ON PriceSource(assetId,capability,rank) [uit UNIQUE]",
"UNIQUE INDEX sqlite_autoindex_ProviderCoverage_1 ON ProviderCoverage(providerId,symbol) [uit UNIQUE]",
"UNIQUE INDEX sqlite_autoindex_ProviderEndpoint_1 ON ProviderEndpoint(providerId,capability) [uit UNIQUE]",
"UNIQUE INDEX sqlite_autoindex_ProviderInputMap_1 ON ProviderInputMap(providerId,symbol) [uit UNIQUE]",
"UNIQUE INDEX sqlite_autoindex_Provider_1 ON Provider(key) [uit UNIQUE]",
"UNIQUE INDEX sqlite_autoindex_Valuation_1 ON Valuation(assetId,valuedOn,accountId) [uit UNIQUE]",
"UNIQUE INDEX sqlite_autoindex_WalletAddress_1 ON WalletAddress(address) [uit UNIQUE]",
"UNIQUE INDEX sqlite_autoindex_WalletTransactionEventLink_1 ON WalletTransactionEventLink(walletTransactionId,eventId) [uit UNIQUE]",
"Valuation.accountId -> Account.id ON DELETE NO ACTION",
"Valuation.accountId: INTEGER",
"Valuation.assetId -> Asset.id ON DELETE CASCADE",
"Valuation.assetId: INTEGER NOT NULL",
"Valuation.balance: INTEGER NOT NULL",
"Valuation.createdAt: TEXT",
"Valuation.fiatRate: REAL NOT NULL",
"Valuation.gapAcceptedAt: TEXT",
"Valuation.id: INTEGER PK1",
"Valuation.rateAt: TEXT NOT NULL",
"Valuation.source: TEXT NOT NULL",
"Valuation.updatedAt: TEXT",
"Valuation.valuedOn: TEXT NOT NULL",
"WalletAddress.accountId -> Account.id ON DELETE CASCADE",
"WalletAddress.accountId: INTEGER NOT NULL",
"WalletAddress.address: TEXT NOT NULL",
"WalletAddress.automaticLabel: TEXT",
"WalletAddress.balanceSats: INTEGER",
"WalletAddress.chainIndex: INTEGER",
"WalletAddress.createdAt: TEXT",
"WalletAddress.derivationIndex: INTEGER",
"WalletAddress.id: INTEGER PK1",
"WalletAddress.lastScannedAt: TEXT",
"WalletAddress.sourceId -> WalletSource.id ON DELETE CASCADE",
"WalletAddress.sourceId: INTEGER",
"WalletAddress.transactionCount: INTEGER",
"WalletSource.accountId -> Account.id ON DELETE CASCADE",
"WalletSource.accountId: INTEGER NOT NULL",
"WalletSource.balanceSats: INTEGER",
"WalletSource.connectionId -> Connection.id ON DELETE RESTRICT",
"WalletSource.connectionId: INTEGER",
"WalletSource.createdAt: TEXT NOT NULL",
"WalletSource.id: INTEGER PK1",
"WalletSource.kind: TEXT NOT NULL",
"WalletSource.lastScannedAt: TEXT",
"WalletSource.name: TEXT",
"WalletSource.scriptType: TEXT",
"WalletSource.updatedAt: TEXT",
"WalletSource.value: TEXT NOT NULL",
"WalletTransaction.accountId -> Account.id ON DELETE CASCADE",
"WalletTransaction.accountId: INTEGER NOT NULL",
"WalletTransaction.address: TEXT",
"WalletTransaction.blockHeight: INTEGER",
"WalletTransaction.blockTime: TEXT",
"WalletTransaction.createdAt: TEXT NOT NULL",
"WalletTransaction.direction: TEXT NOT NULL",
"WalletTransaction.feeSats: INTEGER",
"WalletTransaction.id: INTEGER PK1",
"WalletTransaction.kind: TEXT",
"WalletTransaction.labelId -> Label.id ON DELETE SET NULL",
"WalletTransaction.labelId: INTEGER",
"WalletTransaction.layer: TEXT NOT NULL",
"WalletTransaction.memo: TEXT",
"WalletTransaction.sourceId -> WalletSource.id ON DELETE CASCADE",
"WalletTransaction.sourceId: INTEGER",
"WalletTransaction.txid: TEXT NOT NULL",
"WalletTransaction.valueSats: INTEGER NOT NULL",
"WalletTransactionEventLink.createdAt: TEXT NOT NULL",
"WalletTransactionEventLink.eventId -> Event.id ON DELETE CASCADE",
"WalletTransactionEventLink.eventId: INTEGER NOT NULL",
"WalletTransactionEventLink.id: INTEGER PK1",
"WalletTransactionEventLink.method: TEXT NOT NULL",
"WalletTransactionEventLink.walletTransactionId -> WalletTransaction.id ON DELETE CASCADE",
"WalletTransactionEventLink.walletTransactionId: INTEGER NOT NULL",
];