diff --git a/README.md b/README.md index f535383ad..cf79ddbbc 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,10 @@ pnpm dev Homarr is available at `http://127.0.0.1:3000`. The foreground infrastructure command starts Redis and the optional database services from `development/development.docker-compose.yml`; stop it with Ctrl+C after stopping Homarr. +The unreleased v2 Custom Widget migration history is intentionally consolidated before release. A development database +that already applied the earlier `custom_widget_v2_reset` migration is unsupported: back up anything you need, reset +only that disposable database, and run the migration command again. Homarr never deletes or resets it automatically. + ## Run PocketBase and documentation locally The integrated command starts persistent PocketBase on port 8090, waits for its health endpoint and Workshop diff --git a/apps/workshop/README.md b/apps/workshop/README.md index b565aa28e..bd90b744f 100644 --- a/apps/workshop/README.md +++ b/apps/workshop/README.md @@ -44,6 +44,13 @@ docker compose -f apps/workshop/docker-compose.yml logs -f workshop docker compose -f apps/workshop/docker-compose.yml stop workshop ``` +### Pre-release migration reset + +The v2 branch consolidates the unreleased Workshop migrations into one initial migration. A PocketBase volume that ran +an earlier v2 Workshop migration chain is unsupported. Back up anything you need, then use the intentional local reset +command near the end of this document and start the stack again. Startup never deletes a volume automatically. This +exception applies only to disposable pre-release volumes and must not be used for production data. + ## Connect the Homarr application Use the same URL contract in the repository-root `.env`, then restart Homarr: diff --git a/apps/workshop/pb_migrations/1784240000_workshop_widgets.js b/apps/workshop/pb_migrations/1784240000_workshop_widgets.js index eee300564..729b7a8a7 100644 --- a/apps/workshop/pb_migrations/1784240000_workshop_widgets.js +++ b/apps/workshop/pb_migrations/1784240000_workshop_widgets.js @@ -2,6 +2,41 @@ const cloneJson = (value) => JSON.parse(JSON.stringify(value)); const cloneRule = (value) => (value === null ? null : String(value)); +const adminRule = "@request.auth.isAdmin = true"; +const identityFieldsUnchanged = [ + "@request.body.email:changed = false", + "@request.body.displayName:changed = false", + "@request.body.avatarUrl:changed = false", + "@request.body.githubUsername:changed = false", + "@request.body.githubProfileUrl:changed = false", +].join(" && "); +const immutableSubmissionFields = [ + "@request.body.author:changed = false", + "@request.body.type:changed = false", + "@request.body.widgetSchema:changed = false", +].join(" && "); +const moderatorSubmissionFieldsUnchanged = [ + "@request.body.title:changed = false", + "@request.body.description:changed = false", + "@request.body.content:changed = false", + "@request.body.changelog:changed = false", + "@request.body.screenshots:changed = false", +].join(" && "); +const workshopRateLimits = [ + { label: "submissions:create", audience: "@auth", duration: 60, maxRequests: 10 }, + { label: "submissions:update", audience: "@auth", duration: 60, maxRequests: 30 }, + { label: "submissions:delete", audience: "@auth", duration: 60, maxRequests: 10 }, + { label: "votes:create", audience: "@auth", duration: 10, maxRequests: 20 }, + { label: "votes:update", audience: "@auth", duration: 10, maxRequests: 20 }, + { label: "votes:delete", audience: "@auth", duration: 10, maxRequests: 20 }, + { label: "comments:create", audience: "@auth", duration: 60, maxRequests: 20 }, + { label: "comments:update", audience: "@auth", duration: 60, maxRequests: 20 }, + { label: "comments:delete", audience: "@auth", duration: 60, maxRequests: 20 }, + { label: "reports:create", audience: "@auth", duration: 60, maxRequests: 5 }, + { label: "reports:update", audience: "@auth", duration: 60, maxRequests: 30 }, + { label: "reports:delete", audience: "@auth", duration: 60, maxRequests: 30 }, + { label: "users:update", audience: "@auth", duration: 60, maxRequests: 20 }, +]; migrate( (app) => { @@ -63,11 +98,10 @@ migrate( addUserField(new URLField({ name: "githubProfileUrl" })); addUserField(new BoolField({ name: "isAdmin" })); - const adminRule = "@request.auth.isAdmin = true"; users.listRule = ""; users.viewRule = ""; users.createRule = '@request.context = "oauth2" && @request.body.isAdmin:isset = false'; - users.updateRule = "id = @request.auth.id && @request.body.isAdmin:isset = false"; + users.updateRule = `id = @request.auth.id && @request.body.isAdmin:isset = false && ${identityFieldsUnchanged}`; users.deleteRule = null; app.save(users); const stateRecord = new Record(stateCollection); @@ -80,7 +114,9 @@ migrate( listRule: "", viewRule: "", createRule: "@request.auth.id != '' && @request.body.author = @request.auth.id", - updateRule: `(author = @request.auth.id || ${adminRule}) && @request.body.author:changed = false && @request.body.type:changed = false && @request.body.widgetSchema:changed = false`, + updateRule: + `(author = @request.auth.id && ${immutableSubmissionFields}) || ` + + `(${adminRule} && author != @request.auth.id && ${immutableSubmissionFields} && ${moderatorSubmissionFieldsUnchanged})`, deleteRule: `author = @request.auth.id || ${adminRule}`, fields: [ { type: "select", name: "type", required: true, maxSelect: 1, values: ["customWidget", "customCss"] }, @@ -183,7 +219,12 @@ migrate( listRule: adminRule, viewRule: adminRule, createRule: "@request.auth.id != '' && @request.body.reporter = @request.auth.id", - updateRule: `${adminRule} && @request.body.reporter:changed = false && @request.body.submission:changed = false`, + updateRule: + `${adminRule} && ` + + "@request.body.reporter:changed = false && " + + "@request.body.submission:changed = false && " + + "@request.body.category:changed = false && " + + "@request.body.explanation:changed = false", deleteRule: adminRule, fields: [ { @@ -243,12 +284,9 @@ migrate( settings.rateLimits.enabled = true; settings.rateLimits.rules = [ ...settings.rateLimits.rules.filter( - (rule) => !["submissions:create", "votes:create", "comments:create", "reports:create"].includes(rule.label), + (rule) => !workshopRateLimits.some((workshopRule) => workshopRule.label === rule.label), ), - { label: "submissions:create", audience: "@auth", duration: 60, maxRequests: 10 }, - { label: "votes:create", audience: "@auth", duration: 10, maxRequests: 20 }, - { label: "comments:create", audience: "@auth", duration: 60, maxRequests: 20 }, - { label: "reports:create", audience: "@auth", duration: 60, maxRequests: 5 }, + ...workshopRateLimits, ]; app.save(settings); }, diff --git a/apps/workshop/pb_migrations/1784240001_workshop_write_rate_limits.js b/apps/workshop/pb_migrations/1784240001_workshop_write_rate_limits.js deleted file mode 100644 index 970235125..000000000 --- a/apps/workshop/pb_migrations/1784240001_workshop_write_rate_limits.js +++ /dev/null @@ -1,92 +0,0 @@ -/// - -const managedLabels = [ - "submissions:create", - "submissions:update", - "submissions:delete", - "votes:create", - "votes:update", - "votes:delete", - "comments:create", - "comments:update", - "comments:delete", - "reports:create", - "reports:update", - "reports:delete", - "users:update", -]; -const legacyCreateRules = [ - { label: "submissions:create", audience: "@auth", duration: 60, maxRequests: 10 }, - { label: "votes:create", audience: "@auth", duration: 10, maxRequests: 20 }, - { label: "comments:create", audience: "@auth", duration: 60, maxRequests: 20 }, - { label: "reports:create", audience: "@auth", duration: 60, maxRequests: 5 }, -]; -const legacyCreateLabels = legacyCreateRules.map((rule) => rule.label); - -const cloneJson = (value) => JSON.parse(JSON.stringify(value)); -const withoutManagedRules = (rules) => rules.filter((rule) => !managedLabels.includes(rule.label)); -const managedRules = (rules) => rules.filter((rule) => managedLabels.includes(rule.label)); -const deriveLegacyWriteRateLimitState = (snapshot) => ({ - enabled: true, - managedRules: managedRules([ - ...snapshot.rateLimits.rules.filter((rule) => !legacyCreateLabels.includes(rule.label)), - ...legacyCreateRules, - ]), -}); - -const findMigrationState = (app) => { - try { - const collection = app.findCollectionByNameOrId("workshop_migration_state"); - const record = app.findFirstRecordByFilter(collection.id, ""); - const snapshot = JSON.parse(record.getString("snapshot")); - if (!snapshot || typeof snapshot !== "object" || Array.isArray(snapshot)) { - throw new Error("Workshop migration state snapshot is invalid"); - } - return { record, snapshot }; - } catch { - throw new Error("Workshop write rate-limit migration state is unavailable"); - } -}; - -migrate( - (app) => { - const settings = app.settings(); - const state = findMigrationState(app); - state.snapshot.writeRateLimits = { - enabled: settings.rateLimits.enabled, - managedRules: cloneJson(managedRules(settings.rateLimits.rules)), - }; - state.record.set("snapshot", JSON.stringify(state.snapshot)); - app.save(state.record); - - settings.rateLimits.enabled = true; - settings.rateLimits.rules = [ - ...withoutManagedRules(settings.rateLimits.rules), - { label: "submissions:create", audience: "@auth", duration: 60, maxRequests: 10 }, - { label: "submissions:update", audience: "@auth", duration: 60, maxRequests: 30 }, - { label: "submissions:delete", audience: "@auth", duration: 60, maxRequests: 10 }, - { label: "votes:create", audience: "@auth", duration: 10, maxRequests: 20 }, - { label: "votes:update", audience: "@auth", duration: 10, maxRequests: 20 }, - { label: "votes:delete", audience: "@auth", duration: 10, maxRequests: 20 }, - { label: "comments:create", audience: "@auth", duration: 60, maxRequests: 20 }, - { label: "comments:update", audience: "@auth", duration: 60, maxRequests: 20 }, - { label: "comments:delete", audience: "@auth", duration: 60, maxRequests: 20 }, - { label: "reports:create", audience: "@auth", duration: 60, maxRequests: 5 }, - { label: "reports:update", audience: "@auth", duration: 60, maxRequests: 30 }, - { label: "reports:delete", audience: "@auth", duration: 60, maxRequests: 30 }, - { label: "users:update", audience: "@auth", duration: 60, maxRequests: 20 }, - ]; - app.save(settings); - }, - (app) => { - const settings = app.settings(); - const snapshot = findMigrationState(app).snapshot; - const state = snapshot.writeRateLimits || deriveLegacyWriteRateLimitState(snapshot); - if (!state || typeof state.enabled !== "boolean" || !Array.isArray(state.managedRules)) { - throw new Error("Workshop write rate-limit rollback snapshot is missing or invalid"); - } - settings.rateLimits.enabled = state.enabled; - settings.rateLimits.rules = [...withoutManagedRules(settings.rateLimits.rules), ...cloneJson(state.managedRules)]; - app.save(settings); - }, -); diff --git a/apps/workshop/pb_migrations/1784240002_workshop_access_hardening.js b/apps/workshop/pb_migrations/1784240002_workshop_access_hardening.js deleted file mode 100644 index 507f494e2..000000000 --- a/apps/workshop/pb_migrations/1784240002_workshop_access_hardening.js +++ /dev/null @@ -1,65 +0,0 @@ -/// - -const legacyUserUpdateRule = "id = @request.auth.id && @request.body.isAdmin:isset = false"; -const legacySubmissionUpdateRule = - "(author = @request.auth.id || @request.auth.isAdmin = true) && @request.body.author:changed = false && @request.body.type:changed = false && @request.body.widgetSchema:changed = false"; -const legacyReportUpdateRule = - "@request.auth.isAdmin = true && @request.body.reporter:changed = false && @request.body.submission:changed = false"; - -const identityFieldsUnchanged = [ - "@request.body.email:changed = false", - "@request.body.displayName:changed = false", - "@request.body.avatarUrl:changed = false", - "@request.body.githubUsername:changed = false", - "@request.body.githubProfileUrl:changed = false", -].join(" && "); - -const immutableSubmissionFields = [ - "@request.body.author:changed = false", - "@request.body.type:changed = false", - "@request.body.widgetSchema:changed = false", -].join(" && "); - -const moderatorSubmissionFieldsUnchanged = [ - "@request.body.title:changed = false", - "@request.body.description:changed = false", - "@request.body.content:changed = false", - "@request.body.changelog:changed = false", - "@request.body.screenshots:changed = false", -].join(" && "); - -migrate( - (app) => { - const users = app.findCollectionByNameOrId("users"); - users.updateRule = `id = @request.auth.id && @request.body.isAdmin:isset = false && ${identityFieldsUnchanged}`; - app.save(users); - - const submissions = app.findCollectionByNameOrId("submissions"); - submissions.updateRule = - `(author = @request.auth.id && ${immutableSubmissionFields}) || ` + - `(@request.auth.isAdmin = true && author != @request.auth.id && ${immutableSubmissionFields} && ${moderatorSubmissionFieldsUnchanged})`; - app.save(submissions); - - const reports = app.findCollectionByNameOrId("reports"); - reports.updateRule = - "@request.auth.isAdmin = true && " + - "@request.body.reporter:changed = false && " + - "@request.body.submission:changed = false && " + - "@request.body.category:changed = false && " + - "@request.body.explanation:changed = false"; - app.save(reports); - }, - (app) => { - const users = app.findCollectionByNameOrId("users"); - users.updateRule = legacyUserUpdateRule; - app.save(users); - - const submissions = app.findCollectionByNameOrId("submissions"); - submissions.updateRule = legacySubmissionUpdateRule; - app.save(submissions); - - const reports = app.findCollectionByNameOrId("reports"); - reports.updateRule = legacyReportUpdateRule; - app.save(reports); - }, -); diff --git a/apps/workshop/pb_migrations/1784240003_workshop_rate_limit_rollback_compatibility.js b/apps/workshop/pb_migrations/1784240003_workshop_rate_limit_rollback_compatibility.js deleted file mode 100644 index e551fd0ab..000000000 --- a/apps/workshop/pb_migrations/1784240003_workshop_rate_limit_rollback_compatibility.js +++ /dev/null @@ -1,61 +0,0 @@ -/// - -const managedLabels = [ - "submissions:create", - "submissions:update", - "submissions:delete", - "votes:create", - "votes:update", - "votes:delete", - "comments:create", - "comments:update", - "comments:delete", - "reports:create", - "reports:update", - "reports:delete", - "users:update", -]; -const legacyCreateRules = [ - { label: "submissions:create", audience: "@auth", duration: 60, maxRequests: 10 }, - { label: "votes:create", audience: "@auth", duration: 10, maxRequests: 20 }, - { label: "comments:create", audience: "@auth", duration: 60, maxRequests: 20 }, - { label: "reports:create", audience: "@auth", duration: 60, maxRequests: 5 }, -]; -const legacyCreateLabels = legacyCreateRules.map((rule) => rule.label); -const managedRules = (rules) => rules.filter((rule) => managedLabels.includes(rule.label)); - -const findMigrationState = (app) => { - try { - const collection = app.findCollectionByNameOrId("workshop_migration_state"); - const record = app.findFirstRecordByFilter(collection.id, ""); - const snapshot = JSON.parse(record.getString("snapshot")); - if (!snapshot || typeof snapshot !== "object" || Array.isArray(snapshot)) { - throw new Error("Workshop migration state snapshot is invalid"); - } - return { record, snapshot }; - } catch { - throw new Error("Workshop rate-limit compatibility state is unavailable"); - } -}; - -migrate( - (app) => { - const state = findMigrationState(app); - if (state.snapshot.writeRateLimits) return; - if (!state.snapshot.rateLimits || !Array.isArray(state.snapshot.rateLimits.rules)) { - throw new Error("Workshop legacy rate-limit snapshot is missing or invalid"); - } - state.snapshot.writeRateLimits = { - enabled: true, - managedRules: managedRules([ - ...state.snapshot.rateLimits.rules.filter((rule) => !legacyCreateLabels.includes(rule.label)), - ...legacyCreateRules, - ]), - }; - state.record.set("snapshot", JSON.stringify(state.snapshot)); - app.save(state.record); - }, - () => { - // Keep the backfill until 1784240001 is rolled back; 1784240000 removes the state collection afterward. - }, -); diff --git a/apps/workshop/test.sh b/apps/workshop/test.sh index cd96fcdc4..d9dc136f0 100644 --- a/apps/workshop/test.sh +++ b/apps/workshop/test.sh @@ -13,7 +13,6 @@ ROLLBACK_CONTAINER="" node apps/workshop/tests/workshop-contracts.mjs node apps/workshop/tests/workshop-migration.mjs -node apps/workshop/tests/workshop-rate-limit-migration.mjs node apps/workshop/tests/entrypoint-url.mjs node apps/workshop/tests/workshop-identity.mjs node apps/workshop/tests/workshop-oauth-hook.mjs diff --git a/apps/workshop/tests/workshop-contracts.mjs b/apps/workshop/tests/workshop-contracts.mjs index 9342e0cb8..9086192a1 100644 --- a/apps/workshop/tests/workshop-contracts.mjs +++ b/apps/workshop/tests/workshop-contracts.mjs @@ -97,34 +97,13 @@ for (const required of [ if (!migration.includes(required)) throw new Error(`Workshop rollback is missing state restoration: ${required}`); } -const hardeningMigration = await read("apps/workshop/pb_migrations/1784240001_workshop_write_rate_limits.js"); for (const operation of ["create", "update", "delete"]) { for (const collection of ["submissions", "votes", "comments", "reports"]) { const label = `${collection}:${operation}`; - if (!hardeningMigration.includes(label)) throw new Error(`Workshop write rate limit is missing: ${label}`); - } -} -if (!hardeningMigration.includes("users:update")) throw new Error("Workshop user file updates must be rate limited"); -for (const required of [ - "writeRateLimits", - "managedRules(settings.rateLimits.rules)", - "settings.rateLimits.enabled = state.enabled", - "...cloneJson(state.managedRules)", -]) { - if (!hardeningMigration.includes(required)) { - throw new Error(`Workshop write rate-limit rollback is missing persistent state restoration: ${required}`); - } -} - -const accessHardeningMigration = await read("apps/workshop/pb_migrations/1784240002_workshop_access_hardening.js"); -const rateLimitCompatibilityMigration = await read( - "apps/workshop/pb_migrations/1784240003_workshop_rate_limit_rollback_compatibility.js", -); -for (const required of ["writeRateLimits", "legacyCreateRules", "rate-limit compatibility state is unavailable"]) { - if (!rateLimitCompatibilityMigration.includes(required)) { - throw new Error(`Workshop rate-limit compatibility migration is missing: ${required}`); + if (!migration.includes(label)) throw new Error(`Workshop write rate limit is missing: ${label}`); } } +if (!migration.includes("users:update")) throw new Error("Workshop user file updates must be rate limited"); for (const protectedField of [ "email:changed", "displayName:changed", @@ -132,11 +111,11 @@ for (const protectedField of [ "githubUsername:changed", "githubProfileUrl:changed", ]) { - if (!accessHardeningMigration.includes(protectedField)) { + if (!migration.includes(protectedField)) { throw new Error(`Workshop OAuth identity field remains caller-controlled: ${protectedField}`); } } -if (accessHardeningMigration.includes("@request.body.avatar:changed")) { +if (migration.includes("@request.body.avatar:changed")) { throw new Error("Workshop access rules must not use the unsupported :changed modifier for file fields"); } if ( @@ -153,12 +132,12 @@ for (const protectedField of [ "changelog:changed", "screenshots:changed", ]) { - if (!accessHardeningMigration.includes(protectedField)) { + if (!migration.includes(protectedField)) { throw new Error(`Workshop moderators can still rewrite submissions: ${protectedField}`); } } for (const protectedField of ["category:changed", "explanation:changed"]) { - if (!accessHardeningMigration.includes(protectedField)) { + if (!migration.includes(protectedField)) { throw new Error(`Workshop moderators can still rewrite reports: ${protectedField}`); } } diff --git a/apps/workshop/tests/workshop-rate-limit-migration.mjs b/apps/workshop/tests/workshop-rate-limit-migration.mjs deleted file mode 100644 index 79896f551..000000000 --- a/apps/workshop/tests/workshop-rate-limit-migration.mjs +++ /dev/null @@ -1,205 +0,0 @@ -import assert from "node:assert/strict"; -import { readFile } from "node:fs/promises"; -import vm from "node:vm"; - -const normalized = (value) => JSON.parse(JSON.stringify(value)); -const managedLabels = [ - "submissions:create", - "submissions:update", - "submissions:delete", - "votes:create", - "votes:update", - "votes:delete", - "comments:create", - "comments:update", - "comments:delete", - "reports:create", - "reports:update", - "reports:delete", - "users:update", -]; -const originalManagedRules = managedLabels.map((label, index) => ({ - label, - audience: index % 2 === 0 ? "@auth" : "", - duration: index + 1, - maxRequests: index + 10, -})); -const originalUnmanagedRule = { - label: "unrelated:create", - audience: "", - duration: 41, - maxRequests: 42, -}; -const stateCollection = { id: "workshop_migration_state" }; -let stateSnapshot = JSON.stringify({ marker: "retain-existing-migration-state" }); -const stateRecord = { - getString(name) { - assert.equal(name, "snapshot"); - return stateSnapshot; - }, - set(name, value) { - assert.equal(name, "snapshot"); - stateSnapshot = value; - }, -}; -const settings = { - rateLimits: { - enabled: false, - rules: [originalUnmanagedRule, ...originalManagedRules], - }, -}; -const app = { - findCollectionByNameOrId(name) { - if (name !== stateCollection.id) throw new Error(`Missing collection ${name}`); - return stateCollection; - }, - findFirstRecordByFilter(collectionId) { - if (collectionId !== stateCollection.id) throw new Error(`Missing state record ${collectionId}`); - return stateRecord; - }, - save() {}, - settings() { - return settings; - }, -}; - -const loadMigration = async (path) => { - let loaded; - const source = await readFile(path, "utf8"); - vm.runInNewContext(source, { - console, - migrate: (up, down) => { - loaded = { up, down }; - }, - }); - if (!loaded) throw new Error(`Workshop migration did not register: ${path}`); - return loaded; -}; - -const migration = await loadMigration("apps/workshop/pb_migrations/1784240001_workshop_write_rate_limits.js"); - -migration.up(app); -const savedState = JSON.parse(stateSnapshot); -assert.equal(savedState.marker, "retain-existing-migration-state"); -assert.deepEqual(savedState.writeRateLimits, { - enabled: false, - managedRules: originalManagedRules, -}); -assert.equal(settings.rateLimits.enabled, true); -assert.deepEqual( - normalized(settings.rateLimits.rules.filter((rule) => !managedLabels.includes(rule.label))), - [originalUnmanagedRule], - "Applying Workshop rate limits changed unrelated rules", -); -assert.deepEqual( - new Set(settings.rateLimits.rules.map((rule) => rule.label)), - new Set([...managedLabels, originalUnmanagedRule.label]), - "Applying Workshop rate limits did not replace every managed label", -); - -const laterUnmanagedRule = { - label: "added-after-migration:update", - audience: "@auth", - duration: 51, - maxRequests: 52, -}; -settings.rateLimits.rules = [ - laterUnmanagedRule, - ...settings.rateLimits.rules.filter((rule) => managedLabels.includes(rule.label)), -]; -migration.down(app); - -assert.equal(settings.rateLimits.enabled, false, "Rollback did not restore the original enabled flag"); -assert.deepEqual( - normalized(settings.rateLimits.rules.filter((rule) => !managedLabels.includes(rule.label))), - [laterUnmanagedRule], - "Rollback changed unrelated rules added after the migration", -); -assert.deepEqual( - normalized(settings.rateLimits.rules.filter((rule) => managedLabels.includes(rule.label))), - originalManagedRules, - "Rollback did not restore every original managed-label rule", -); - -assert.throws( - () => - migration.up({ - ...app, - findCollectionByNameOrId() { - throw new Error("missing"); - }, - }), - /migration state is unavailable/u, - "Migration must fail closed when its persistent rollback snapshot is unavailable", -); - -const legacyOriginalRules = [ - { label: "unrelated:create", audience: "", duration: 71, maxRequests: 72 }, - { label: "submissions:create", audience: "", duration: 73, maxRequests: 74 }, - { label: "comments:update", audience: "@auth", duration: 75, maxRequests: 76 }, -]; -const legacyStateCollection = { id: "workshop_migration_state" }; -let legacyStateSnapshot = JSON.stringify({ - marker: "already-applied-old-0001", - rateLimits: { enabled: false, rules: legacyOriginalRules }, -}); -const legacyStateRecord = { - getString() { - return legacyStateSnapshot; - }, - set(_name, value) { - legacyStateSnapshot = value; - }, -}; -const legacySettings = { - rateLimits: { - enabled: true, - rules: [ - { label: "unrelated:create", audience: "", duration: 71, maxRequests: 72 }, - ...managedLabels.map((label) => ({ label, audience: "@auth", duration: 60, maxRequests: 30 })), - ], - }, -}; -const legacyApp = { - findCollectionByNameOrId() { - return legacyStateCollection; - }, - findFirstRecordByFilter() { - return legacyStateRecord; - }, - save() {}, - settings() { - return legacySettings; - }, -}; -const compatibilityMigration = await loadMigration( - "apps/workshop/pb_migrations/1784240003_workshop_rate_limit_rollback_compatibility.js", -); -compatibilityMigration.up(legacyApp); -compatibilityMigration.down(legacyApp); - -const backfilledState = JSON.parse(legacyStateSnapshot); -assert.equal(backfilledState.marker, "already-applied-old-0001"); -assert.deepEqual(backfilledState.writeRateLimits, { - enabled: true, - managedRules: [ - { label: "comments:update", audience: "@auth", duration: 75, maxRequests: 76 }, - { label: "submissions:create", audience: "@auth", duration: 60, maxRequests: 10 }, - { label: "votes:create", audience: "@auth", duration: 10, maxRequests: 20 }, - { label: "comments:create", audience: "@auth", duration: 60, maxRequests: 20 }, - { label: "reports:create", audience: "@auth", duration: 60, maxRequests: 5 }, - ], -}); - -migration.down(legacyApp); -assert.equal(legacySettings.rateLimits.enabled, true); -assert.deepEqual( - normalized(legacySettings.rateLimits.rules), - [ - { label: "unrelated:create", audience: "", duration: 71, maxRequests: 72 }, - ...backfilledState.writeRateLimits.managedRules, - ], - "An already-applied legacy migration could not be rolled back after the compatibility backfill", -); - -console.log("Workshop write rate-limit migration restoration passed"); diff --git a/packages/db/migrations/mysql/0044_custom_widget_v2_reset.sql b/packages/db/migrations/mysql/0044_custom_widget_v2_reset.sql deleted file mode 100644 index b717d7b81..000000000 --- a/packages/db/migrations/mysql/0044_custom_widget_v2_reset.sql +++ /dev/null @@ -1,30 +0,0 @@ -RENAME TABLE `custom_widget_definition` TO `legacy_custom_widget_definition`, `custom_widget_secret` TO `legacy_custom_widget_secret`;--> statement-breakpoint -ALTER TABLE `legacy_custom_widget_definition` DROP FOREIGN KEY `custom_widget_definition_creator_id_user_id_fk`;--> statement-breakpoint -ALTER TABLE `legacy_custom_widget_definition` ADD CONSTRAINT `legacy_cw_definition_creator_id_user_id_fk` FOREIGN KEY (`creator_id`) REFERENCES `user`(`id`) ON DELETE set null ON UPDATE no action;--> statement-breakpoint -ALTER TABLE `legacy_custom_widget_secret` DROP FOREIGN KEY `cw_secret_definition_id_cw_definition_id_fk`;--> statement-breakpoint -ALTER TABLE `legacy_custom_widget_secret` ADD CONSTRAINT `legacy_cw_secret_definition_id_fk` FOREIGN KEY (`definition_id`) REFERENCES `legacy_custom_widget_definition`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint -CREATE TABLE `custom_widget_definition` ( - `id` varchar(64) NOT NULL, - `name` varchar(256) NOT NULL, - `description` text, - `icon_url` text, - `sources` text NOT NULL, - `requests` text NOT NULL, - `options` text NOT NULL, - `template` text NOT NULL, - `enabled` boolean DEFAULT true NOT NULL, - `created_at` timestamp DEFAULT (now()) NOT NULL, - `updated_at` timestamp DEFAULT (now()) NOT NULL, - `creator_id` varchar(64), - CONSTRAINT `custom_widget_definition_id` PRIMARY KEY(`id`) -);--> statement-breakpoint -CREATE TABLE `custom_widget_secret` ( - `source_id` varchar(64) NOT NULL, - `kind` varchar(64) NOT NULL, - `encrypted_value` text NOT NULL, - `updated_at` timestamp NOT NULL, - `definition_id` varchar(64) NOT NULL, - CONSTRAINT `custom_widget_secret_definition_id_source_id_kind_pk` PRIMARY KEY(`definition_id`,`source_id`,`kind`) -);--> statement-breakpoint -ALTER TABLE `custom_widget_definition` ADD CONSTRAINT `custom_widget_definition_creator_id_user_id_fk` FOREIGN KEY (`creator_id`) REFERENCES `user`(`id`) ON DELETE set null ON UPDATE no action;--> statement-breakpoint -ALTER TABLE `custom_widget_secret` ADD CONSTRAINT `cw_secret_definition_id_fk` FOREIGN KEY (`definition_id`) REFERENCES `custom_widget_definition`(`id`) ON DELETE cascade ON UPDATE no action; diff --git a/packages/db/migrations/mysql/0044_custom_widget_v2_tables.sql b/packages/db/migrations/mysql/0044_custom_widget_v2_tables.sql new file mode 100644 index 000000000..629cbbc27 --- /dev/null +++ b/packages/db/migrations/mysql/0044_custom_widget_v2_tables.sql @@ -0,0 +1,26 @@ +CREATE TABLE `custom_widget_v2_definition` ( + `id` varchar(64) NOT NULL, + `name` varchar(256) NOT NULL, + `description` text, + `icon_url` text, + `sources` text NOT NULL, + `requests` text NOT NULL, + `options` text NOT NULL, + `template` text NOT NULL, + `enabled` boolean DEFAULT true NOT NULL, + `created_at` timestamp DEFAULT (now()) NOT NULL, + `updated_at` timestamp DEFAULT (now()) NOT NULL, + `creator_id` varchar(64), + CONSTRAINT `custom_widget_v2_definition_id` PRIMARY KEY(`id`) +);--> statement-breakpoint +CREATE TABLE `custom_widget_v2_secret` ( + `source_id` varchar(64) NOT NULL, + `kind` varchar(64) NOT NULL, + `encrypted_value` text NOT NULL, + `updated_at` timestamp NOT NULL, + `definition_id` varchar(64) NOT NULL, + CONSTRAINT `custom_widget_v2_secret_definition_id_source_id_kind_pk` PRIMARY KEY(`definition_id`,`source_id`,`kind`) +);--> statement-breakpoint +ALTER TABLE `custom_widget_v2_definition` ADD CONSTRAINT `custom_widget_v2_definition_creator_id_user_id_fk` FOREIGN KEY (`creator_id`) REFERENCES `user`(`id`) ON DELETE set null ON UPDATE no action;--> statement-breakpoint +ALTER TABLE `custom_widget_v2_secret` ADD CONSTRAINT `custom_widget_v2_secret_definition_id_fk` FOREIGN KEY (`definition_id`) REFERENCES `custom_widget_v2_definition`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +DELETE FROM `groupPermission` WHERE `permission` IN ('custom-widget-manage', 'custom-widget-secret-write'); diff --git a/packages/db/migrations/mysql/0045_custom_widget_v1_compatibility.sql b/packages/db/migrations/mysql/0045_custom_widget_v1_compatibility.sql deleted file mode 100644 index 508279e79..000000000 --- a/packages/db/migrations/mysql/0045_custom_widget_v1_compatibility.sql +++ /dev/null @@ -1,22 +0,0 @@ -RENAME TABLE - `custom_widget_definition` TO `custom_widget_v2_definition`, - `custom_widget_secret` TO `custom_widget_v2_secret`, - `legacy_custom_widget_definition` TO `custom_widget_definition`, - `legacy_custom_widget_secret` TO `custom_widget_secret`;--> statement-breakpoint -ALTER TABLE `custom_widget_v2_definition` - DROP FOREIGN KEY `custom_widget_definition_creator_id_user_id_fk`, - ADD CONSTRAINT `custom_widget_v2_definition_creator_id_user_id_fk` - FOREIGN KEY (`creator_id`) REFERENCES `user`(`id`) ON DELETE set null ON UPDATE no action;--> statement-breakpoint -ALTER TABLE `custom_widget_v2_secret` - DROP FOREIGN KEY `cw_secret_definition_id_fk`, - ADD CONSTRAINT `custom_widget_v2_secret_definition_id_fk` - FOREIGN KEY (`definition_id`) REFERENCES `custom_widget_v2_definition`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint -ALTER TABLE `custom_widget_definition` - DROP FOREIGN KEY `legacy_cw_definition_creator_id_user_id_fk`, - ADD CONSTRAINT `custom_widget_definition_creator_id_user_id_fk` - FOREIGN KEY (`creator_id`) REFERENCES `user`(`id`) ON DELETE set null ON UPDATE no action;--> statement-breakpoint -ALTER TABLE `custom_widget_secret` - DROP FOREIGN KEY `legacy_cw_secret_definition_id_fk`, - ADD CONSTRAINT `cw_secret_definition_id_cw_definition_id_fk` - FOREIGN KEY (`definition_id`) REFERENCES `custom_widget_definition`(`id`) ON DELETE cascade ON UPDATE no action;--> statement-breakpoint -DELETE FROM `groupPermission` WHERE `permission` IN ('custom-widget-manage', 'custom-widget-secret-write'); diff --git a/packages/db/migrations/mysql/meta/0044_snapshot.json b/packages/db/migrations/mysql/meta/0044_snapshot.json index 66b344f2c..e9fd750e8 100644 --- a/packages/db/migrations/mysql/meta/0044_snapshot.json +++ b/packages/db/migrations/mysql/meta/0044_snapshot.json @@ -1,7 +1,7 @@ { "version": "5", "dialect": "mysql", - "id": "1a10d79c-6c82-4036-8717-0283ebaece10", + "id": "e2f11bb0-59e9-4fab-8ae1-5bf764795c74", "prevId": "073d408e-ff80-4a57-8007-f1f32da1c71c", "tables": { "account": { @@ -534,198 +534,8 @@ "uniqueConstraints": {}, "checkConstraint": {} }, - "legacy_custom_widget_definition": { - "name": "legacy_custom_widget_definition", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "varchar(256)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "icon_url": { - "name": "icon_url", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "auth_type": { - "name": "auth_type", - "type": "varchar(32)", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'none'" - }, - "header_name": { - "name": "header_name", - "type": "varchar(256)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "method": { - "name": "method", - "type": "varchar(16)", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'GET'" - }, - "request_body": { - "name": "request_body", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "display_type": { - "name": "display_type", - "type": "varchar(32)", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'singleValue'" - }, - "display_config": { - "name": "display_config", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "('{\"json\": {}}')" - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "(now())" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "(now())" - }, - "creator_id": { - "name": "creator_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "url": { - "name": "url", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "enabled": { - "name": "enabled", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": true - } - }, - "indexes": {}, - "foreignKeys": { - "legacy_cw_definition_creator_id_user_id_fk": { - "name": "legacy_cw_definition_creator_id_user_id_fk", - "tableFrom": "legacy_custom_widget_definition", - "tableTo": "user", - "columnsFrom": ["creator_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "legacy_custom_widget_definition_id": { - "name": "legacy_custom_widget_definition_id", - "columns": ["id"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "legacy_custom_widget_secret": { - "name": "legacy_custom_widget_secret", - "columns": { - "kind": { - "name": "kind", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "value": { - "name": "value", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "definition_id": { - "name": "definition_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "legacy_cw_secret_definition_id_fk": { - "name": "legacy_cw_secret_definition_id_fk", - "tableFrom": "legacy_custom_widget_secret", - "tableTo": "legacy_custom_widget_definition", - "columnsFrom": ["definition_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "legacy_custom_widget_secret_definition_id_kind_pk": { - "name": "legacy_custom_widget_secret_definition_id_kind_pk", - "columns": ["definition_id", "kind"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "custom_widget_definition": { - "name": "custom_widget_definition", + "custom_widget_v2_definition": { + "name": "custom_widget_v2_definition", "columns": { "id": { "name": "id", @@ -817,9 +627,9 @@ }, "indexes": {}, "foreignKeys": { - "custom_widget_definition_creator_id_user_id_fk": { - "name": "custom_widget_definition_creator_id_user_id_fk", - "tableFrom": "custom_widget_definition", + "custom_widget_v2_definition_creator_id_user_id_fk": { + "name": "custom_widget_v2_definition_creator_id_user_id_fk", + "tableFrom": "custom_widget_v2_definition", "tableTo": "user", "columnsFrom": ["creator_id"], "columnsTo": ["id"], @@ -828,16 +638,16 @@ } }, "compositePrimaryKeys": { - "custom_widget_definition_id": { - "name": "custom_widget_definition_id", + "custom_widget_v2_definition_id": { + "name": "custom_widget_v2_definition_id", "columns": ["id"] } }, "uniqueConstraints": {}, "checkConstraint": {} }, - "custom_widget_secret": { - "name": "custom_widget_secret", + "custom_widget_v2_secret": { + "name": "custom_widget_v2_secret", "columns": { "source_id": { "name": "source_id", @@ -877,10 +687,10 @@ }, "indexes": {}, "foreignKeys": { - "cw_secret_definition_id_fk": { - "name": "cw_secret_definition_id_fk", - "tableFrom": "custom_widget_secret", - "tableTo": "custom_widget_definition", + "custom_widget_v2_secret_definition_id_fk": { + "name": "custom_widget_v2_secret_definition_id_fk", + "tableFrom": "custom_widget_v2_secret", + "tableTo": "custom_widget_v2_definition", "columnsFrom": ["definition_id"], "columnsTo": ["id"], "onDelete": "cascade", @@ -888,8 +698,8 @@ } }, "compositePrimaryKeys": { - "custom_widget_secret_definition_id_source_id_kind_pk": { - "name": "custom_widget_secret_definition_id_source_id_kind_pk", + "custom_widget_v2_secret_definition_id_source_id_kind_pk": { + "name": "custom_widget_v2_secret_definition_id_source_id_kind_pk", "columns": ["definition_id", "source_id", "kind"] } }, @@ -1718,6 +1528,196 @@ "uniqueConstraints": {}, "checkConstraint": {} }, + "custom_widget_definition": { + "name": "custom_widget_definition", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "icon_url": { + "name": "icon_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "auth_type": { + "name": "auth_type", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'none'" + }, + "header_name": { + "name": "header_name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "method": { + "name": "method", + "type": "varchar(16)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'GET'" + }, + "request_body": { + "name": "request_body", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "display_type": { + "name": "display_type", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'singleValue'" + }, + "display_config": { + "name": "display_config", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('{\"json\": {}}')" + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(now())" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(now())" + }, + "creator_id": { + "name": "creator_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "custom_widget_definition_creator_id_user_id_fk": { + "name": "custom_widget_definition_creator_id_user_id_fk", + "tableFrom": "custom_widget_definition", + "tableTo": "user", + "columnsFrom": ["creator_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "custom_widget_definition_id": { + "name": "custom_widget_definition_id", + "columns": ["id"] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "custom_widget_secret": { + "name": "custom_widget_secret", + "columns": { + "kind": { + "name": "kind", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "definition_id": { + "name": "definition_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "cw_secret_definition_id_cw_definition_id_fk": { + "name": "cw_secret_definition_id_cw_definition_id_fk", + "tableFrom": "custom_widget_secret", + "tableTo": "custom_widget_definition", + "columnsFrom": ["definition_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "custom_widget_secret_definition_id_kind_pk": { + "name": "custom_widget_secret_definition_id_kind_pk", + "columns": ["definition_id", "kind"] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, "media": { "name": "media", "columns": { diff --git a/packages/db/migrations/mysql/meta/0045_snapshot.json b/packages/db/migrations/mysql/meta/0045_snapshot.json deleted file mode 100644 index d29448416..000000000 --- a/packages/db/migrations/mysql/meta/0045_snapshot.json +++ /dev/null @@ -1,2543 +0,0 @@ -{ - "version": "5", - "dialect": "mysql", - "id": "e2f11bb0-59e9-4fab-8ae1-5bf764795c74", - "prevId": "1a10d79c-6c82-4036-8717-0283ebaece10", - "tables": { - "account": { - "name": "account", - "columns": { - "user_id": { - "name": "user_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "type": { - "name": "type", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "provider": { - "name": "provider", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "provider_account_id": { - "name": "provider_account_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "refresh_token": { - "name": "refresh_token", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "access_token": { - "name": "access_token", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "expires_at": { - "name": "expires_at", - "type": "int", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "token_type": { - "name": "token_type", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "scope": { - "name": "scope", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "id_token": { - "name": "id_token", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "session_state": { - "name": "session_state", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": { - "userId_idx": { - "name": "userId_idx", - "columns": ["user_id"], - "isUnique": false - } - }, - "foreignKeys": { - "account_user_id_user_id_fk": { - "name": "account_user_id_user_id_fk", - "tableFrom": "account", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "account_provider_provider_account_id_pk": { - "name": "account_provider_provider_account_id_pk", - "columns": ["provider", "provider_account_id"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "apiKey": { - "name": "apiKey", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "api_key": { - "name": "api_key", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "user_id": { - "name": "user_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "apiKey_user_id_user_id_fk": { - "name": "apiKey_user_id_user_id_fk", - "tableFrom": "apiKey", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "apiKey_id": { - "name": "apiKey_id", - "columns": ["id"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "app": { - "name": "app", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "icon_url": { - "name": "icon_url", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "href": { - "name": "href", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "ping_url": { - "name": "ping_url", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": { - "app_id": { - "name": "app_id", - "columns": ["id"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "boardGroupPermission": { - "name": "boardGroupPermission", - "columns": { - "board_id": { - "name": "board_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "group_id": { - "name": "group_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "permission": { - "name": "permission", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "boardGroupPermission_board_id_board_id_fk": { - "name": "boardGroupPermission_board_id_board_id_fk", - "tableFrom": "boardGroupPermission", - "tableTo": "board", - "columnsFrom": ["board_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "boardGroupPermission_group_id_group_id_fk": { - "name": "boardGroupPermission_group_id_group_id_fk", - "tableFrom": "boardGroupPermission", - "tableTo": "group", - "columnsFrom": ["group_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "boardGroupPermission_board_id_group_id_permission_pk": { - "name": "boardGroupPermission_board_id_group_id_permission_pk", - "columns": ["board_id", "group_id", "permission"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "boardUserPermission": { - "name": "boardUserPermission", - "columns": { - "board_id": { - "name": "board_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "user_id": { - "name": "user_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "permission": { - "name": "permission", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "boardUserPermission_board_id_board_id_fk": { - "name": "boardUserPermission_board_id_board_id_fk", - "tableFrom": "boardUserPermission", - "tableTo": "board", - "columnsFrom": ["board_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "boardUserPermission_user_id_user_id_fk": { - "name": "boardUserPermission_user_id_user_id_fk", - "tableFrom": "boardUserPermission", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "boardUserPermission_board_id_user_id_permission_pk": { - "name": "boardUserPermission_board_id_user_id_permission_pk", - "columns": ["board_id", "user_id", "permission"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "board": { - "name": "board", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "varchar(256)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "is_public": { - "name": "is_public", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": false - }, - "creator_id": { - "name": "creator_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "page_title": { - "name": "page_title", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "meta_title": { - "name": "meta_title", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "logo_image_url": { - "name": "logo_image_url", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "favicon_image_url": { - "name": "favicon_image_url", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "background_image_url": { - "name": "background_image_url", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "background_image_attachment": { - "name": "background_image_attachment", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "('fixed')" - }, - "background_image_repeat": { - "name": "background_image_repeat", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "('no-repeat')" - }, - "background_image_size": { - "name": "background_image_size", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "('cover')" - }, - "primary_color": { - "name": "primary_color", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "('#fa5252')" - }, - "secondary_color": { - "name": "secondary_color", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "('#fd7e14')" - }, - "opacity": { - "name": "opacity", - "type": "int", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": 100 - }, - "custom_css": { - "name": "custom_css", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "icon_color": { - "name": "icon_color", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "item_radius": { - "name": "item_radius", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "('lg')" - }, - "disable_status": { - "name": "disable_status", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": false - } - }, - "indexes": {}, - "foreignKeys": { - "board_creator_id_user_id_fk": { - "name": "board_creator_id_user_id_fk", - "tableFrom": "board", - "tableTo": "user", - "columnsFrom": ["creator_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "board_id": { - "name": "board_id", - "columns": ["id"] - } - }, - "uniqueConstraints": { - "board_name_unique": { - "name": "board_name_unique", - "columns": ["name"] - } - }, - "checkConstraint": {} - }, - "cron_job_configuration": { - "name": "cron_job_configuration", - "columns": { - "name": { - "name": "name", - "type": "varchar(256)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "cron_expression": { - "name": "cron_expression", - "type": "varchar(32)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "is_enabled": { - "name": "is_enabled", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": true - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": { - "cron_job_configuration_name": { - "name": "cron_job_configuration_name", - "columns": ["name"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "custom_widget_v2_definition": { - "name": "custom_widget_v2_definition", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "varchar(256)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "icon_url": { - "name": "icon_url", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "sources": { - "name": "sources", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "requests": { - "name": "requests", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "options": { - "name": "options", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "template": { - "name": "template", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "enabled": { - "name": "enabled", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "(now())" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "(now())" - }, - "creator_id": { - "name": "creator_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "custom_widget_v2_definition_creator_id_user_id_fk": { - "name": "custom_widget_v2_definition_creator_id_user_id_fk", - "tableFrom": "custom_widget_v2_definition", - "tableTo": "user", - "columnsFrom": ["creator_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "custom_widget_v2_definition_id": { - "name": "custom_widget_v2_definition_id", - "columns": ["id"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "custom_widget_v2_secret": { - "name": "custom_widget_v2_secret", - "columns": { - "source_id": { - "name": "source_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "kind": { - "name": "kind", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "encrypted_value": { - "name": "encrypted_value", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "definition_id": { - "name": "definition_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "custom_widget_v2_secret_definition_id_fk": { - "name": "custom_widget_v2_secret_definition_id_fk", - "tableFrom": "custom_widget_v2_secret", - "tableTo": "custom_widget_v2_definition", - "columnsFrom": ["definition_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "custom_widget_v2_secret_definition_id_source_id_kind_pk": { - "name": "custom_widget_v2_secret_definition_id_source_id_kind_pk", - "columns": ["definition_id", "source_id", "kind"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "groupMember": { - "name": "groupMember", - "columns": { - "group_id": { - "name": "group_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "user_id": { - "name": "user_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "groupMember_group_id_group_id_fk": { - "name": "groupMember_group_id_group_id_fk", - "tableFrom": "groupMember", - "tableTo": "group", - "columnsFrom": ["group_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "groupMember_user_id_user_id_fk": { - "name": "groupMember_user_id_user_id_fk", - "tableFrom": "groupMember", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "groupMember_group_id_user_id_pk": { - "name": "groupMember_group_id_user_id_pk", - "columns": ["group_id", "user_id"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "groupPermission": { - "name": "groupPermission", - "columns": { - "group_id": { - "name": "group_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "permission": { - "name": "permission", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "groupPermission_group_id_group_id_fk": { - "name": "groupPermission_group_id_group_id_fk", - "tableFrom": "groupPermission", - "tableTo": "group", - "columnsFrom": ["group_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "group": { - "name": "group", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "owner_id": { - "name": "owner_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "home_board_id": { - "name": "home_board_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "mobile_home_board_id": { - "name": "mobile_home_board_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "position": { - "name": "position", - "type": "smallint", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "group_owner_id_user_id_fk": { - "name": "group_owner_id_user_id_fk", - "tableFrom": "group", - "tableTo": "user", - "columnsFrom": ["owner_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - }, - "group_home_board_id_board_id_fk": { - "name": "group_home_board_id_board_id_fk", - "tableFrom": "group", - "tableTo": "board", - "columnsFrom": ["home_board_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - }, - "group_mobile_home_board_id_board_id_fk": { - "name": "group_mobile_home_board_id_board_id_fk", - "tableFrom": "group", - "tableTo": "board", - "columnsFrom": ["mobile_home_board_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "group_id": { - "name": "group_id", - "columns": ["id"] - } - }, - "uniqueConstraints": { - "group_name_unique": { - "name": "group_name_unique", - "columns": ["name"] - } - }, - "checkConstraint": {} - }, - "iconRepository": { - "name": "iconRepository", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "slug": { - "name": "slug", - "type": "varchar(150)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": { - "iconRepository_id": { - "name": "iconRepository_id", - "columns": ["id"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "icon": { - "name": "icon", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "varchar(250)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "url": { - "name": "url", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "checksum": { - "name": "checksum", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "icon_repository_id": { - "name": "icon_repository_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "icon_icon_repository_id_iconRepository_id_fk": { - "name": "icon_icon_repository_id_iconRepository_id_fk", - "tableFrom": "icon", - "tableTo": "iconRepository", - "columnsFrom": ["icon_repository_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "icon_id": { - "name": "icon_id", - "columns": ["id"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "integrationGroupPermissions": { - "name": "integrationGroupPermissions", - "columns": { - "integration_id": { - "name": "integration_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "group_id": { - "name": "group_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "permission": { - "name": "permission", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "integrationGroupPermissions_integration_id_integration_id_fk": { - "name": "integrationGroupPermissions_integration_id_integration_id_fk", - "tableFrom": "integrationGroupPermissions", - "tableTo": "integration", - "columnsFrom": ["integration_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "integrationGroupPermissions_group_id_group_id_fk": { - "name": "integrationGroupPermissions_group_id_group_id_fk", - "tableFrom": "integrationGroupPermissions", - "tableTo": "group", - "columnsFrom": ["group_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "integration_group_permission__pk": { - "name": "integration_group_permission__pk", - "columns": ["integration_id", "group_id", "permission"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "integration_item": { - "name": "integration_item", - "columns": { - "item_id": { - "name": "item_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "integration_id": { - "name": "integration_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "integration_item_item_id_item_id_fk": { - "name": "integration_item_item_id_item_id_fk", - "tableFrom": "integration_item", - "tableTo": "item", - "columnsFrom": ["item_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "integration_item_integration_id_integration_id_fk": { - "name": "integration_item_integration_id_integration_id_fk", - "tableFrom": "integration_item", - "tableTo": "integration", - "columnsFrom": ["integration_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "integration_item_item_id_integration_id_pk": { - "name": "integration_item_item_id_integration_id_pk", - "columns": ["item_id", "integration_id"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "integrationSecret": { - "name": "integrationSecret", - "columns": { - "kind": { - "name": "kind", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "value": { - "name": "value", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "integration_id": { - "name": "integration_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": { - "integration_secret__kind_idx": { - "name": "integration_secret__kind_idx", - "columns": ["kind"], - "isUnique": false - }, - "integration_secret__updated_at_idx": { - "name": "integration_secret__updated_at_idx", - "columns": ["updated_at"], - "isUnique": false - } - }, - "foreignKeys": { - "integrationSecret_integration_id_integration_id_fk": { - "name": "integrationSecret_integration_id_integration_id_fk", - "tableFrom": "integrationSecret", - "tableTo": "integration", - "columnsFrom": ["integration_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "integrationSecret_integration_id_kind_pk": { - "name": "integrationSecret_integration_id_kind_pk", - "columns": ["integration_id", "kind"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "integrationUserPermission": { - "name": "integrationUserPermission", - "columns": { - "integration_id": { - "name": "integration_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "user_id": { - "name": "user_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "permission": { - "name": "permission", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "integrationUserPermission_integration_id_integration_id_fk": { - "name": "integrationUserPermission_integration_id_integration_id_fk", - "tableFrom": "integrationUserPermission", - "tableTo": "integration", - "columnsFrom": ["integration_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "integrationUserPermission_user_id_user_id_fk": { - "name": "integrationUserPermission_user_id_user_id_fk", - "tableFrom": "integrationUserPermission", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "integrationUserPermission_integration_id_user_id_permission_pk": { - "name": "integrationUserPermission_integration_id_user_id_permission_pk", - "columns": ["integration_id", "user_id", "permission"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "integration": { - "name": "integration", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "url": { - "name": "url", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "kind": { - "name": "kind", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "app_id": { - "name": "app_id", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": { - "integration__kind_idx": { - "name": "integration__kind_idx", - "columns": ["kind"], - "isUnique": false - } - }, - "foreignKeys": { - "integration_app_id_app_id_fk": { - "name": "integration_app_id_app_id_fk", - "tableFrom": "integration", - "tableTo": "app", - "columnsFrom": ["app_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "integration_id": { - "name": "integration_id", - "columns": ["id"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "invite": { - "name": "invite", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "token": { - "name": "token", - "type": "varchar(512)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "expiration_date": { - "name": "expiration_date", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "creator_id": { - "name": "creator_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "invite_creator_id_user_id_fk": { - "name": "invite_creator_id_user_id_fk", - "tableFrom": "invite", - "tableTo": "user", - "columnsFrom": ["creator_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "invite_id": { - "name": "invite_id", - "columns": ["id"] - } - }, - "uniqueConstraints": { - "invite_token_unique": { - "name": "invite_token_unique", - "columns": ["token"] - } - }, - "checkConstraint": {} - }, - "item_layout": { - "name": "item_layout", - "columns": { - "item_id": { - "name": "item_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "section_id": { - "name": "section_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "layout_id": { - "name": "layout_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "x_offset": { - "name": "x_offset", - "type": "int", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "y_offset": { - "name": "y_offset", - "type": "int", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "width": { - "name": "width", - "type": "int", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "height": { - "name": "height", - "type": "int", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "item_layout_item_id_item_id_fk": { - "name": "item_layout_item_id_item_id_fk", - "tableFrom": "item_layout", - "tableTo": "item", - "columnsFrom": ["item_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "item_layout_section_id_section_id_fk": { - "name": "item_layout_section_id_section_id_fk", - "tableFrom": "item_layout", - "tableTo": "section", - "columnsFrom": ["section_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "item_layout_layout_id_layout_id_fk": { - "name": "item_layout_layout_id_layout_id_fk", - "tableFrom": "item_layout", - "tableTo": "layout", - "columnsFrom": ["layout_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "item_layout_item_id_section_id_layout_id_pk": { - "name": "item_layout_item_id_section_id_layout_id_pk", - "columns": ["item_id", "section_id", "layout_id"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "item": { - "name": "item", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "board_id": { - "name": "board_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "kind": { - "name": "kind", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "options": { - "name": "options", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "('{\"json\": {}}')" - }, - "advanced_options": { - "name": "advanced_options", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "('{\"json\": {}}')" - } - }, - "indexes": {}, - "foreignKeys": { - "item_board_id_board_id_fk": { - "name": "item_board_id_board_id_fk", - "tableFrom": "item", - "tableTo": "board", - "columnsFrom": ["board_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "item_id": { - "name": "item_id", - "columns": ["id"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "layout": { - "name": "layout", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "varchar(32)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "board_id": { - "name": "board_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "column_count": { - "name": "column_count", - "type": "tinyint", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "breakpoint": { - "name": "breakpoint", - "type": "smallint", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": 0 - } - }, - "indexes": {}, - "foreignKeys": { - "layout_board_id_board_id_fk": { - "name": "layout_board_id_board_id_fk", - "tableFrom": "layout", - "tableTo": "board", - "columnsFrom": ["board_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "layout_id": { - "name": "layout_id", - "columns": ["id"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "custom_widget_definition": { - "name": "custom_widget_definition", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "varchar(256)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "icon_url": { - "name": "icon_url", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "url": { - "name": "url", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "auth_type": { - "name": "auth_type", - "type": "varchar(32)", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'none'" - }, - "header_name": { - "name": "header_name", - "type": "varchar(256)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "method": { - "name": "method", - "type": "varchar(16)", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'GET'" - }, - "request_body": { - "name": "request_body", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "display_type": { - "name": "display_type", - "type": "varchar(32)", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'singleValue'" - }, - "display_config": { - "name": "display_config", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "('{\"json\": {}}')" - }, - "enabled": { - "name": "enabled", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "(now())" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "(now())" - }, - "creator_id": { - "name": "creator_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "custom_widget_definition_creator_id_user_id_fk": { - "name": "custom_widget_definition_creator_id_user_id_fk", - "tableFrom": "custom_widget_definition", - "tableTo": "user", - "columnsFrom": ["creator_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "custom_widget_definition_id": { - "name": "custom_widget_definition_id", - "columns": ["id"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "custom_widget_secret": { - "name": "custom_widget_secret", - "columns": { - "kind": { - "name": "kind", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "value": { - "name": "value", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "definition_id": { - "name": "definition_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "cw_secret_definition_id_cw_definition_id_fk": { - "name": "cw_secret_definition_id_cw_definition_id_fk", - "tableFrom": "custom_widget_secret", - "tableTo": "custom_widget_definition", - "columnsFrom": ["definition_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "custom_widget_secret_definition_id_kind_pk": { - "name": "custom_widget_secret_definition_id_kind_pk", - "columns": ["definition_id", "kind"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "media": { - "name": "media", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "varchar(512)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "content": { - "name": "content", - "type": "LONGBLOB", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "content_type": { - "name": "content_type", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "size": { - "name": "size", - "type": "int", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "(now())" - }, - "creator_id": { - "name": "creator_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "media_creator_id_user_id_fk": { - "name": "media_creator_id_user_id_fk", - "tableFrom": "media", - "tableTo": "user", - "columnsFrom": ["creator_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "media_id": { - "name": "media_id", - "columns": ["id"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "onboarding": { - "name": "onboarding", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "step": { - "name": "step", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "previous_step": { - "name": "previous_step", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": { - "onboarding_id": { - "name": "onboarding_id", - "columns": ["id"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "search_engine": { - "name": "search_engine", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "icon_url": { - "name": "icon_url", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "short": { - "name": "short", - "type": "varchar(8)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "url_template": { - "name": "url_template", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "type": { - "name": "type", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'generic'" - }, - "integration_id": { - "name": "integration_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "search_engine_integration_id_integration_id_fk": { - "name": "search_engine_integration_id_integration_id_fk", - "tableFrom": "search_engine", - "tableTo": "integration", - "columnsFrom": ["integration_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "search_engine_id": { - "name": "search_engine_id", - "columns": ["id"] - } - }, - "uniqueConstraints": { - "search_engine_short_unique": { - "name": "search_engine_short_unique", - "columns": ["short"] - } - }, - "checkConstraint": {} - }, - "section_collapse_state": { - "name": "section_collapse_state", - "columns": { - "user_id": { - "name": "user_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "section_id": { - "name": "section_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "collapsed": { - "name": "collapsed", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": false - } - }, - "indexes": {}, - "foreignKeys": { - "section_collapse_state_user_id_user_id_fk": { - "name": "section_collapse_state_user_id_user_id_fk", - "tableFrom": "section_collapse_state", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "section_collapse_state_section_id_section_id_fk": { - "name": "section_collapse_state_section_id_section_id_fk", - "tableFrom": "section_collapse_state", - "tableTo": "section", - "columnsFrom": ["section_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "section_collapse_state_user_id_section_id_pk": { - "name": "section_collapse_state_user_id_section_id_pk", - "columns": ["user_id", "section_id"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "section_layout": { - "name": "section_layout", - "columns": { - "section_id": { - "name": "section_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "layout_id": { - "name": "layout_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "parent_section_id": { - "name": "parent_section_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "x_offset": { - "name": "x_offset", - "type": "int", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "y_offset": { - "name": "y_offset", - "type": "int", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "width": { - "name": "width", - "type": "int", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "height": { - "name": "height", - "type": "int", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "section_layout_section_id_section_id_fk": { - "name": "section_layout_section_id_section_id_fk", - "tableFrom": "section_layout", - "tableTo": "section", - "columnsFrom": ["section_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "section_layout_layout_id_layout_id_fk": { - "name": "section_layout_layout_id_layout_id_fk", - "tableFrom": "section_layout", - "tableTo": "layout", - "columnsFrom": ["layout_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "section_layout_parent_section_id_section_id_fk": { - "name": "section_layout_parent_section_id_section_id_fk", - "tableFrom": "section_layout", - "tableTo": "section", - "columnsFrom": ["parent_section_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "section_layout_section_id_layout_id_pk": { - "name": "section_layout_section_id_layout_id_pk", - "columns": ["section_id", "layout_id"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "section": { - "name": "section", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "board_id": { - "name": "board_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "kind": { - "name": "kind", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "x_offset": { - "name": "x_offset", - "type": "int", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "y_offset": { - "name": "y_offset", - "type": "int", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "options": { - "name": "options", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false, - "default": "('{\"json\": {}}')" - } - }, - "indexes": {}, - "foreignKeys": { - "section_board_id_board_id_fk": { - "name": "section_board_id_board_id_fk", - "tableFrom": "section", - "tableTo": "board", - "columnsFrom": ["board_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "section_id": { - "name": "section_id", - "columns": ["id"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "serverSetting": { - "name": "serverSetting", - "columns": { - "setting_key": { - "name": "setting_key", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "value": { - "name": "value", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "('{\"json\": {}}')" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": { - "serverSetting_setting_key": { - "name": "serverSetting_setting_key", - "columns": ["setting_key"] - } - }, - "uniqueConstraints": { - "serverSetting_settingKey_unique": { - "name": "serverSetting_settingKey_unique", - "columns": ["setting_key"] - } - }, - "checkConstraint": {} - }, - "session": { - "name": "session", - "columns": { - "session_token": { - "name": "session_token", - "type": "varchar(512)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "user_id": { - "name": "user_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "expires": { - "name": "expires", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": { - "user_id_idx": { - "name": "user_id_idx", - "columns": ["user_id"], - "isUnique": false - } - }, - "foreignKeys": { - "session_user_id_user_id_fk": { - "name": "session_user_id_user_id_fk", - "tableFrom": "session", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "session_session_token": { - "name": "session_session_token", - "columns": ["session_token"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "trusted_certificate_hostname": { - "name": "trusted_certificate_hostname", - "columns": { - "hostname": { - "name": "hostname", - "type": "varchar(256)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "thumbprint": { - "name": "thumbprint", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "certificate": { - "name": "certificate", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": { - "trusted_certificate_hostname_hostname_thumbprint_pk": { - "name": "trusted_certificate_hostname_hostname_thumbprint_pk", - "columns": ["hostname", "thumbprint"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "user": { - "name": "user", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "email": { - "name": "email", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "email_verified": { - "name": "email_verified", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "image": { - "name": "image", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "password": { - "name": "password", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "provider": { - "name": "provider", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'credentials'" - }, - "home_board_id": { - "name": "home_board_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "mobile_home_board_id": { - "name": "mobile_home_board_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "default_search_engine_id": { - "name": "default_search_engine_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "open_search_in_new_tab": { - "name": "open_search_in_new_tab", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": false - }, - "ddg_bangs": { - "name": "ddg_bangs", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": true - }, - "color_scheme": { - "name": "color_scheme", - "type": "varchar(5)", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'dark'" - }, - "first_day_of_week": { - "name": "first_day_of_week", - "type": "tinyint", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": 1 - }, - "ping_icons_enabled": { - "name": "ping_icons_enabled", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": false - }, - "enable_right_click_on_widgets": { - "name": "enable_right_click_on_widgets", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": true - }, - "completed_manage_tour": { - "name": "completed_manage_tour", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": false - }, - "completed_board_tour": { - "name": "completed_board_tour", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": false - } - }, - "indexes": {}, - "foreignKeys": { - "user_home_board_id_board_id_fk": { - "name": "user_home_board_id_board_id_fk", - "tableFrom": "user", - "tableTo": "board", - "columnsFrom": ["home_board_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - }, - "user_mobile_home_board_id_board_id_fk": { - "name": "user_mobile_home_board_id_board_id_fk", - "tableFrom": "user", - "tableTo": "board", - "columnsFrom": ["mobile_home_board_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - }, - "user_default_search_engine_id_search_engine_id_fk": { - "name": "user_default_search_engine_id_search_engine_id_fk", - "tableFrom": "user", - "tableTo": "search_engine", - "columnsFrom": ["default_search_engine_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "user_id": { - "name": "user_id", - "columns": ["id"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "verificationToken": { - "name": "verificationToken", - "columns": { - "identifier": { - "name": "identifier", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "token": { - "name": "token", - "type": "varchar(512)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "expires": { - "name": "expires", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": { - "verificationToken_identifier_token_pk": { - "name": "verificationToken_identifier_token_pk", - "columns": ["identifier", "token"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - }, - "widget_secret": { - "name": "widget_secret", - "columns": { - "item_id": { - "name": "item_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "kind": { - "name": "kind", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "value": { - "name": "value", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "widget_secret_item_id_item_id_fk": { - "name": "widget_secret_item_id_item_id_fk", - "tableFrom": "widget_secret", - "tableTo": "item", - "columnsFrom": ["item_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "widget_secret_item_id_kind_pk": { - "name": "widget_secret_item_id_kind_pk", - "columns": ["item_id", "kind"] - } - }, - "uniqueConstraints": {}, - "checkConstraint": {} - } - }, - "views": {}, - "_meta": { - "schemas": {}, - "tables": {}, - "columns": {} - }, - "internal": { - "tables": {}, - "indexes": {} - } -} diff --git a/packages/db/migrations/mysql/meta/_journal.json b/packages/db/migrations/mysql/meta/_journal.json index ec9227a80..9b608ae05 100644 --- a/packages/db/migrations/mysql/meta/_journal.json +++ b/packages/db/migrations/mysql/meta/_journal.json @@ -314,14 +314,7 @@ "idx": 44, "version": "5", "when": 1784305537309, - "tag": "0044_custom_widget_v2_reset", - "breakpoints": true - }, - { - "idx": 45, - "version": "5", - "when": 1785225865332, - "tag": "0045_custom_widget_v1_compatibility", + "tag": "0044_custom_widget_v2_tables", "breakpoints": true } ] diff --git a/packages/db/migrations/postgresql/0010_custom_widget_v2_reset.sql b/packages/db/migrations/postgresql/0010_custom_widget_v2_reset.sql deleted file mode 100644 index 7b36b6468..000000000 --- a/packages/db/migrations/postgresql/0010_custom_widget_v2_reset.sql +++ /dev/null @@ -1,29 +0,0 @@ -ALTER TABLE "custom_widget_definition" RENAME TO "legacy_custom_widget_definition";--> statement-breakpoint -ALTER TABLE "custom_widget_secret" RENAME TO "legacy_custom_widget_secret";--> statement-breakpoint -ALTER TABLE "legacy_custom_widget_definition" RENAME CONSTRAINT "custom_widget_definition_creator_id_user_id_fk" TO "legacy_cw_definition_creator_id_user_id_fk";--> statement-breakpoint -ALTER TABLE "legacy_custom_widget_secret" RENAME CONSTRAINT "custom_widget_secret_definition_id_custom_widget_definition_id_fk" TO "legacy_cw_secret_definition_id_fk";--> statement-breakpoint -ALTER TABLE "legacy_custom_widget_secret" RENAME CONSTRAINT "custom_widget_secret_definition_id_kind_pk" TO "legacy_custom_widget_secret_definition_id_kind_pk";--> statement-breakpoint -CREATE TABLE "custom_widget_definition" ( - "id" varchar(64) PRIMARY KEY NOT NULL, - "name" varchar(256) NOT NULL, - "description" text, - "icon_url" text, - "sources" text NOT NULL, - "requests" text NOT NULL, - "options" text NOT NULL, - "template" text NOT NULL, - "enabled" boolean DEFAULT true NOT NULL, - "created_at" timestamp DEFAULT now() NOT NULL, - "updated_at" timestamp DEFAULT now() NOT NULL, - "creator_id" varchar(64) -);--> statement-breakpoint -CREATE TABLE "custom_widget_secret" ( - "source_id" varchar(64) NOT NULL, - "kind" varchar(64) NOT NULL, - "encrypted_value" text NOT NULL, - "updated_at" timestamp NOT NULL, - "definition_id" varchar(64) NOT NULL, - CONSTRAINT "custom_widget_secret_definition_id_source_id_kind_pk" PRIMARY KEY("definition_id","source_id","kind") -);--> statement-breakpoint -ALTER TABLE "custom_widget_definition" ADD CONSTRAINT "custom_widget_definition_creator_id_user_id_fk" FOREIGN KEY ("creator_id") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint -ALTER TABLE "custom_widget_secret" ADD CONSTRAINT "cw_secret_definition_id_fk" FOREIGN KEY ("definition_id") REFERENCES "public"."custom_widget_definition"("id") ON DELETE cascade ON UPDATE no action; diff --git a/packages/db/migrations/postgresql/0010_custom_widget_v2_tables.sql b/packages/db/migrations/postgresql/0010_custom_widget_v2_tables.sql new file mode 100644 index 000000000..e209f1b97 --- /dev/null +++ b/packages/db/migrations/postgresql/0010_custom_widget_v2_tables.sql @@ -0,0 +1,25 @@ +CREATE TABLE "custom_widget_v2_definition" ( + "id" varchar(64) PRIMARY KEY NOT NULL, + "name" varchar(256) NOT NULL, + "description" text, + "icon_url" text, + "sources" text NOT NULL, + "requests" text NOT NULL, + "options" text NOT NULL, + "template" text NOT NULL, + "enabled" boolean DEFAULT true NOT NULL, + "created_at" timestamp DEFAULT now() NOT NULL, + "updated_at" timestamp DEFAULT now() NOT NULL, + "creator_id" varchar(64) +);--> statement-breakpoint +CREATE TABLE "custom_widget_v2_secret" ( + "source_id" varchar(64) NOT NULL, + "kind" varchar(64) NOT NULL, + "encrypted_value" text NOT NULL, + "updated_at" timestamp NOT NULL, + "definition_id" varchar(64) NOT NULL, + CONSTRAINT "custom_widget_v2_secret_definition_id_source_id_kind_pk" PRIMARY KEY("definition_id","source_id","kind") +);--> statement-breakpoint +ALTER TABLE "custom_widget_v2_definition" ADD CONSTRAINT "custom_widget_v2_definition_creator_id_user_id_fk" FOREIGN KEY ("creator_id") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "custom_widget_v2_secret" ADD CONSTRAINT "custom_widget_v2_secret_definition_id_fk" FOREIGN KEY ("definition_id") REFERENCES "public"."custom_widget_v2_definition"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +DELETE FROM "groupPermission" WHERE "permission" IN ('custom-widget-manage', 'custom-widget-secret-write'); diff --git a/packages/db/migrations/postgresql/0011_custom_widget_v1_compatibility.sql b/packages/db/migrations/postgresql/0011_custom_widget_v1_compatibility.sql deleted file mode 100644 index 903e0fe4d..000000000 --- a/packages/db/migrations/postgresql/0011_custom_widget_v1_compatibility.sql +++ /dev/null @@ -1,23 +0,0 @@ -ALTER TABLE "custom_widget_definition" RENAME TO "custom_widget_v2_definition";--> statement-breakpoint -ALTER TABLE "custom_widget_secret" RENAME TO "custom_widget_v2_secret";--> statement-breakpoint -ALTER TABLE "legacy_custom_widget_definition" RENAME TO "custom_widget_definition";--> statement-breakpoint -ALTER TABLE "legacy_custom_widget_secret" RENAME TO "custom_widget_secret";--> statement-breakpoint -ALTER TABLE "custom_widget_v2_definition" - RENAME CONSTRAINT "custom_widget_definition_creator_id_user_id_fk" - TO "custom_widget_v2_definition_creator_id_user_id_fk";--> statement-breakpoint -ALTER TABLE "custom_widget_v2_secret" - RENAME CONSTRAINT "cw_secret_definition_id_fk" - TO "custom_widget_v2_secret_definition_id_fk";--> statement-breakpoint -ALTER TABLE "custom_widget_v2_secret" - RENAME CONSTRAINT "custom_widget_secret_definition_id_source_id_kind_pk" - TO "custom_widget_v2_secret_definition_id_source_id_kind_pk";--> statement-breakpoint -ALTER TABLE "custom_widget_definition" - RENAME CONSTRAINT "legacy_cw_definition_creator_id_user_id_fk" - TO "custom_widget_definition_creator_id_user_id_fk";--> statement-breakpoint -ALTER TABLE "custom_widget_secret" - RENAME CONSTRAINT "legacy_cw_secret_definition_id_fk" - TO "custom_widget_secret_definition_id_custom_widget_definition_id_fk";--> statement-breakpoint -ALTER TABLE "custom_widget_secret" - RENAME CONSTRAINT "legacy_custom_widget_secret_definition_id_kind_pk" - TO "custom_widget_secret_definition_id_kind_pk";--> statement-breakpoint -DELETE FROM "groupPermission" WHERE "permission" IN ('custom-widget-manage', 'custom-widget-secret-write'); diff --git a/packages/db/migrations/postgresql/meta/0010_snapshot.json b/packages/db/migrations/postgresql/meta/0010_snapshot.json index d95510800..0a1d58b0d 100644 --- a/packages/db/migrations/postgresql/meta/0010_snapshot.json +++ b/packages/db/migrations/postgresql/meta/0010_snapshot.json @@ -1,5 +1,5 @@ { - "id": "f2cd8146-b478-4617-870e-f601fb437d15", + "id": "99938d86-5059-41b3-a21c-ac767440ed00", "prevId": "97bda61f-0a71-4e41-8e60-874aafe17115", "version": "7", "dialect": "postgresql", @@ -498,180 +498,8 @@ "checkConstraints": {}, "isRLSEnabled": false }, - "public.legacy_custom_widget_definition": { - "name": "legacy_custom_widget_definition", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(256)", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "icon_url": { - "name": "icon_url", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "url": { - "name": "url", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "auth_type": { - "name": "auth_type", - "type": "varchar(32)", - "primaryKey": false, - "notNull": true, - "default": "'none'" - }, - "header_name": { - "name": "header_name", - "type": "varchar(256)", - "primaryKey": false, - "notNull": false - }, - "method": { - "name": "method", - "type": "varchar(16)", - "primaryKey": false, - "notNull": true, - "default": "'GET'" - }, - "request_body": { - "name": "request_body", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "display_type": { - "name": "display_type", - "type": "varchar(32)", - "primaryKey": false, - "notNull": true, - "default": "'singleValue'" - }, - "display_config": { - "name": "display_config", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'{\"json\": {}}'" - }, - "enabled": { - "name": "enabled", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "creator_id": { - "name": "creator_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "legacy_cw_definition_creator_id_user_id_fk": { - "name": "legacy_cw_definition_creator_id_user_id_fk", - "tableFrom": "legacy_custom_widget_definition", - "tableTo": "user", - "columnsFrom": ["creator_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.legacy_custom_widget_secret": { - "name": "legacy_custom_widget_secret", - "schema": "", - "columns": { - "kind": { - "name": "kind", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "value": { - "name": "value", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true - }, - "definition_id": { - "name": "definition_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "legacy_cw_secret_definition_id_fk": { - "name": "legacy_cw_secret_definition_id_fk", - "tableFrom": "legacy_custom_widget_secret", - "tableTo": "legacy_custom_widget_definition", - "columnsFrom": ["definition_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "legacy_custom_widget_secret_definition_id_kind_pk": { - "name": "legacy_custom_widget_secret_definition_id_kind_pk", - "columns": ["definition_id", "kind"] - } - }, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.custom_widget_definition": { - "name": "custom_widget_definition", + "public.custom_widget_v2_definition": { + "name": "custom_widget_v2_definition", "schema": "", "columns": { "id": { @@ -752,9 +580,9 @@ }, "indexes": {}, "foreignKeys": { - "custom_widget_definition_creator_id_user_id_fk": { - "name": "custom_widget_definition_creator_id_user_id_fk", - "tableFrom": "custom_widget_definition", + "custom_widget_v2_definition_creator_id_user_id_fk": { + "name": "custom_widget_v2_definition_creator_id_user_id_fk", + "tableFrom": "custom_widget_v2_definition", "tableTo": "user", "columnsFrom": ["creator_id"], "columnsTo": ["id"], @@ -768,8 +596,8 @@ "checkConstraints": {}, "isRLSEnabled": false }, - "public.custom_widget_secret": { - "name": "custom_widget_secret", + "public.custom_widget_v2_secret": { + "name": "custom_widget_v2_secret", "schema": "", "columns": { "source_id": { @@ -805,10 +633,10 @@ }, "indexes": {}, "foreignKeys": { - "cw_secret_definition_id_fk": { - "name": "cw_secret_definition_id_fk", - "tableFrom": "custom_widget_secret", - "tableTo": "custom_widget_definition", + "custom_widget_v2_secret_definition_id_fk": { + "name": "custom_widget_v2_secret_definition_id_fk", + "tableFrom": "custom_widget_v2_secret", + "tableTo": "custom_widget_v2_definition", "columnsFrom": ["definition_id"], "columnsTo": ["id"], "onDelete": "cascade", @@ -816,8 +644,8 @@ } }, "compositePrimaryKeys": { - "custom_widget_secret_definition_id_source_id_kind_pk": { - "name": "custom_widget_secret_definition_id_source_id_kind_pk", + "custom_widget_v2_secret_definition_id_source_id_kind_pk": { + "name": "custom_widget_v2_secret_definition_id_source_id_kind_pk", "columns": ["definition_id", "source_id", "kind"] } }, @@ -1632,6 +1460,178 @@ "checkConstraints": {}, "isRLSEnabled": false }, + "public.custom_widget_definition": { + "name": "custom_widget_definition", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "icon_url": { + "name": "icon_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "auth_type": { + "name": "auth_type", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'none'" + }, + "header_name": { + "name": "header_name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "method": { + "name": "method", + "type": "varchar(16)", + "primaryKey": false, + "notNull": true, + "default": "'GET'" + }, + "request_body": { + "name": "request_body", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "display_type": { + "name": "display_type", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "default": "'singleValue'" + }, + "display_config": { + "name": "display_config", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'{\"json\": {}}'" + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "creator_id": { + "name": "creator_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "custom_widget_definition_creator_id_user_id_fk": { + "name": "custom_widget_definition_creator_id_user_id_fk", + "tableFrom": "custom_widget_definition", + "tableTo": "user", + "columnsFrom": ["creator_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.custom_widget_secret": { + "name": "custom_widget_secret", + "schema": "", + "columns": { + "kind": { + "name": "kind", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "definition_id": { + "name": "definition_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "custom_widget_secret_definition_id_custom_widget_definition_id_fk": { + "name": "custom_widget_secret_definition_id_custom_widget_definition_id_fk", + "tableFrom": "custom_widget_secret", + "tableTo": "custom_widget_definition", + "columnsFrom": ["definition_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "custom_widget_secret_definition_id_kind_pk": { + "name": "custom_widget_secret_definition_id_kind_pk", + "columns": ["definition_id", "kind"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, "public.media": { "name": "media", "schema": "", diff --git a/packages/db/migrations/postgresql/meta/0011_snapshot.json b/packages/db/migrations/postgresql/meta/0011_snapshot.json deleted file mode 100644 index 117a87c4c..000000000 --- a/packages/db/migrations/postgresql/meta/0011_snapshot.json +++ /dev/null @@ -1,2403 +0,0 @@ -{ - "id": "99938d86-5059-41b3-a21c-ac767440ed00", - "prevId": "f2cd8146-b478-4617-870e-f601fb437d15", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.account": { - "name": "account", - "schema": "", - "columns": { - "user_id": { - "name": "user_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "type": { - "name": "type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "provider": { - "name": "provider", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "provider_account_id": { - "name": "provider_account_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "refresh_token": { - "name": "refresh_token", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "access_token": { - "name": "access_token", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "expires_at": { - "name": "expires_at", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "token_type": { - "name": "token_type", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "scope": { - "name": "scope", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "id_token": { - "name": "id_token", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "session_state": { - "name": "session_state", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "userId_idx": { - "name": "userId_idx", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "account_user_id_user_id_fk": { - "name": "account_user_id_user_id_fk", - "tableFrom": "account", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "account_provider_provider_account_id_pk": { - "name": "account_provider_provider_account_id_pk", - "columns": ["provider", "provider_account_id"] - } - }, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.apiKey": { - "name": "apiKey", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": true, - "notNull": true - }, - "api_key": { - "name": "api_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "apiKey_user_id_user_id_fk": { - "name": "apiKey_user_id_user_id_fk", - "tableFrom": "apiKey", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.app": { - "name": "app", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "icon_url": { - "name": "icon_url", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "href": { - "name": "href", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "ping_url": { - "name": "ping_url", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.boardGroupPermission": { - "name": "boardGroupPermission", - "schema": "", - "columns": { - "board_id": { - "name": "board_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "group_id": { - "name": "group_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "permission": { - "name": "permission", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "boardGroupPermission_board_id_board_id_fk": { - "name": "boardGroupPermission_board_id_board_id_fk", - "tableFrom": "boardGroupPermission", - "tableTo": "board", - "columnsFrom": ["board_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "boardGroupPermission_group_id_group_id_fk": { - "name": "boardGroupPermission_group_id_group_id_fk", - "tableFrom": "boardGroupPermission", - "tableTo": "group", - "columnsFrom": ["group_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "boardGroupPermission_board_id_group_id_permission_pk": { - "name": "boardGroupPermission_board_id_group_id_permission_pk", - "columns": ["board_id", "group_id", "permission"] - } - }, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.boardUserPermission": { - "name": "boardUserPermission", - "schema": "", - "columns": { - "board_id": { - "name": "board_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "permission": { - "name": "permission", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "boardUserPermission_board_id_board_id_fk": { - "name": "boardUserPermission_board_id_board_id_fk", - "tableFrom": "boardUserPermission", - "tableTo": "board", - "columnsFrom": ["board_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "boardUserPermission_user_id_user_id_fk": { - "name": "boardUserPermission_user_id_user_id_fk", - "tableFrom": "boardUserPermission", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "boardUserPermission_board_id_user_id_permission_pk": { - "name": "boardUserPermission_board_id_user_id_permission_pk", - "columns": ["board_id", "user_id", "permission"] - } - }, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.board": { - "name": "board", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(256)", - "primaryKey": false, - "notNull": true - }, - "is_public": { - "name": "is_public", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "creator_id": { - "name": "creator_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false - }, - "page_title": { - "name": "page_title", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "meta_title": { - "name": "meta_title", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "logo_image_url": { - "name": "logo_image_url", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "favicon_image_url": { - "name": "favicon_image_url", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "background_image_url": { - "name": "background_image_url", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "background_image_attachment": { - "name": "background_image_attachment", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'fixed'" - }, - "background_image_repeat": { - "name": "background_image_repeat", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'no-repeat'" - }, - "background_image_size": { - "name": "background_image_size", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'cover'" - }, - "primary_color": { - "name": "primary_color", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'#fa5252'" - }, - "secondary_color": { - "name": "secondary_color", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'#fd7e14'" - }, - "opacity": { - "name": "opacity", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 100 - }, - "custom_css": { - "name": "custom_css", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "icon_color": { - "name": "icon_color", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "item_radius": { - "name": "item_radius", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'lg'" - }, - "disable_status": { - "name": "disable_status", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - } - }, - "indexes": {}, - "foreignKeys": { - "board_creator_id_user_id_fk": { - "name": "board_creator_id_user_id_fk", - "tableFrom": "board", - "tableTo": "user", - "columnsFrom": ["creator_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "board_name_unique": { - "name": "board_name_unique", - "nullsNotDistinct": false, - "columns": ["name"] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.cron_job_configuration": { - "name": "cron_job_configuration", - "schema": "", - "columns": { - "name": { - "name": "name", - "type": "varchar(256)", - "primaryKey": true, - "notNull": true - }, - "cron_expression": { - "name": "cron_expression", - "type": "varchar(32)", - "primaryKey": false, - "notNull": true - }, - "is_enabled": { - "name": "is_enabled", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": true - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.custom_widget_v2_definition": { - "name": "custom_widget_v2_definition", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(256)", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "icon_url": { - "name": "icon_url", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "sources": { - "name": "sources", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "requests": { - "name": "requests", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "options": { - "name": "options", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "template": { - "name": "template", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "enabled": { - "name": "enabled", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "creator_id": { - "name": "creator_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "custom_widget_v2_definition_creator_id_user_id_fk": { - "name": "custom_widget_v2_definition_creator_id_user_id_fk", - "tableFrom": "custom_widget_v2_definition", - "tableTo": "user", - "columnsFrom": ["creator_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.custom_widget_v2_secret": { - "name": "custom_widget_v2_secret", - "schema": "", - "columns": { - "source_id": { - "name": "source_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "kind": { - "name": "kind", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "encrypted_value": { - "name": "encrypted_value", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true - }, - "definition_id": { - "name": "definition_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "custom_widget_v2_secret_definition_id_fk": { - "name": "custom_widget_v2_secret_definition_id_fk", - "tableFrom": "custom_widget_v2_secret", - "tableTo": "custom_widget_v2_definition", - "columnsFrom": ["definition_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "custom_widget_v2_secret_definition_id_source_id_kind_pk": { - "name": "custom_widget_v2_secret_definition_id_source_id_kind_pk", - "columns": ["definition_id", "source_id", "kind"] - } - }, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.groupMember": { - "name": "groupMember", - "schema": "", - "columns": { - "group_id": { - "name": "group_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "groupMember_group_id_group_id_fk": { - "name": "groupMember_group_id_group_id_fk", - "tableFrom": "groupMember", - "tableTo": "group", - "columnsFrom": ["group_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "groupMember_user_id_user_id_fk": { - "name": "groupMember_user_id_user_id_fk", - "tableFrom": "groupMember", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "groupMember_group_id_user_id_pk": { - "name": "groupMember_group_id_user_id_pk", - "columns": ["group_id", "user_id"] - } - }, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.groupPermission": { - "name": "groupPermission", - "schema": "", - "columns": { - "group_id": { - "name": "group_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "permission": { - "name": "permission", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "groupPermission_group_id_group_id_fk": { - "name": "groupPermission_group_id_group_id_fk", - "tableFrom": "groupPermission", - "tableTo": "group", - "columnsFrom": ["group_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.group": { - "name": "group", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "owner_id": { - "name": "owner_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false - }, - "home_board_id": { - "name": "home_board_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false - }, - "mobile_home_board_id": { - "name": "mobile_home_board_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false - }, - "position": { - "name": "position", - "type": "smallint", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "group_owner_id_user_id_fk": { - "name": "group_owner_id_user_id_fk", - "tableFrom": "group", - "tableTo": "user", - "columnsFrom": ["owner_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - }, - "group_home_board_id_board_id_fk": { - "name": "group_home_board_id_board_id_fk", - "tableFrom": "group", - "tableTo": "board", - "columnsFrom": ["home_board_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - }, - "group_mobile_home_board_id_board_id_fk": { - "name": "group_mobile_home_board_id_board_id_fk", - "tableFrom": "group", - "tableTo": "board", - "columnsFrom": ["mobile_home_board_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "group_name_unique": { - "name": "group_name_unique", - "nullsNotDistinct": false, - "columns": ["name"] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.iconRepository": { - "name": "iconRepository", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": true, - "notNull": true - }, - "slug": { - "name": "slug", - "type": "varchar(150)", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.icon": { - "name": "icon", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(250)", - "primaryKey": false, - "notNull": true - }, - "url": { - "name": "url", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "checksum": { - "name": "checksum", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "icon_repository_id": { - "name": "icon_repository_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "icon_icon_repository_id_iconRepository_id_fk": { - "name": "icon_icon_repository_id_iconRepository_id_fk", - "tableFrom": "icon", - "tableTo": "iconRepository", - "columnsFrom": ["icon_repository_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.integrationGroupPermissions": { - "name": "integrationGroupPermissions", - "schema": "", - "columns": { - "integration_id": { - "name": "integration_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "group_id": { - "name": "group_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "permission": { - "name": "permission", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "integrationGroupPermissions_integration_id_integration_id_fk": { - "name": "integrationGroupPermissions_integration_id_integration_id_fk", - "tableFrom": "integrationGroupPermissions", - "tableTo": "integration", - "columnsFrom": ["integration_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "integrationGroupPermissions_group_id_group_id_fk": { - "name": "integrationGroupPermissions_group_id_group_id_fk", - "tableFrom": "integrationGroupPermissions", - "tableTo": "group", - "columnsFrom": ["group_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "integration_group_permission__pk": { - "name": "integration_group_permission__pk", - "columns": ["integration_id", "group_id", "permission"] - } - }, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.integration_item": { - "name": "integration_item", - "schema": "", - "columns": { - "item_id": { - "name": "item_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "integration_id": { - "name": "integration_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "integration_item_item_id_item_id_fk": { - "name": "integration_item_item_id_item_id_fk", - "tableFrom": "integration_item", - "tableTo": "item", - "columnsFrom": ["item_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "integration_item_integration_id_integration_id_fk": { - "name": "integration_item_integration_id_integration_id_fk", - "tableFrom": "integration_item", - "tableTo": "integration", - "columnsFrom": ["integration_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "integration_item_item_id_integration_id_pk": { - "name": "integration_item_item_id_integration_id_pk", - "columns": ["item_id", "integration_id"] - } - }, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.integrationSecret": { - "name": "integrationSecret", - "schema": "", - "columns": { - "kind": { - "name": "kind", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "value": { - "name": "value", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true - }, - "integration_id": { - "name": "integration_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "integration_secret__kind_idx": { - "name": "integration_secret__kind_idx", - "columns": [ - { - "expression": "kind", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "integration_secret__updated_at_idx": { - "name": "integration_secret__updated_at_idx", - "columns": [ - { - "expression": "updated_at", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "integrationSecret_integration_id_integration_id_fk": { - "name": "integrationSecret_integration_id_integration_id_fk", - "tableFrom": "integrationSecret", - "tableTo": "integration", - "columnsFrom": ["integration_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "integrationSecret_integration_id_kind_pk": { - "name": "integrationSecret_integration_id_kind_pk", - "columns": ["integration_id", "kind"] - } - }, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.integrationUserPermission": { - "name": "integrationUserPermission", - "schema": "", - "columns": { - "integration_id": { - "name": "integration_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "permission": { - "name": "permission", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "integrationUserPermission_integration_id_integration_id_fk": { - "name": "integrationUserPermission_integration_id_integration_id_fk", - "tableFrom": "integrationUserPermission", - "tableTo": "integration", - "columnsFrom": ["integration_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "integrationUserPermission_user_id_user_id_fk": { - "name": "integrationUserPermission_user_id_user_id_fk", - "tableFrom": "integrationUserPermission", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "integrationUserPermission_integration_id_user_id_permission_pk": { - "name": "integrationUserPermission_integration_id_user_id_permission_pk", - "columns": ["integration_id", "user_id", "permission"] - } - }, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.integration": { - "name": "integration", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "url": { - "name": "url", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "kind": { - "name": "kind", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - }, - "app_id": { - "name": "app_id", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "integration__kind_idx": { - "name": "integration__kind_idx", - "columns": [ - { - "expression": "kind", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "integration_app_id_app_id_fk": { - "name": "integration_app_id_app_id_fk", - "tableFrom": "integration", - "tableTo": "app", - "columnsFrom": ["app_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.invite": { - "name": "invite", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": true, - "notNull": true - }, - "token": { - "name": "token", - "type": "varchar(512)", - "primaryKey": false, - "notNull": true - }, - "expiration_date": { - "name": "expiration_date", - "type": "timestamp", - "primaryKey": false, - "notNull": true - }, - "creator_id": { - "name": "creator_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "invite_creator_id_user_id_fk": { - "name": "invite_creator_id_user_id_fk", - "tableFrom": "invite", - "tableTo": "user", - "columnsFrom": ["creator_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "invite_token_unique": { - "name": "invite_token_unique", - "nullsNotDistinct": false, - "columns": ["token"] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.item_layout": { - "name": "item_layout", - "schema": "", - "columns": { - "item_id": { - "name": "item_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "section_id": { - "name": "section_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "layout_id": { - "name": "layout_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "x_offset": { - "name": "x_offset", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "y_offset": { - "name": "y_offset", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "width": { - "name": "width", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "height": { - "name": "height", - "type": "integer", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "item_layout_item_id_item_id_fk": { - "name": "item_layout_item_id_item_id_fk", - "tableFrom": "item_layout", - "tableTo": "item", - "columnsFrom": ["item_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "item_layout_section_id_section_id_fk": { - "name": "item_layout_section_id_section_id_fk", - "tableFrom": "item_layout", - "tableTo": "section", - "columnsFrom": ["section_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "item_layout_layout_id_layout_id_fk": { - "name": "item_layout_layout_id_layout_id_fk", - "tableFrom": "item_layout", - "tableTo": "layout", - "columnsFrom": ["layout_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "item_layout_item_id_section_id_layout_id_pk": { - "name": "item_layout_item_id_section_id_layout_id_pk", - "columns": ["item_id", "section_id", "layout_id"] - } - }, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.item": { - "name": "item", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": true, - "notNull": true - }, - "board_id": { - "name": "board_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "kind": { - "name": "kind", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "options": { - "name": "options", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'{\"json\": {}}'" - }, - "advanced_options": { - "name": "advanced_options", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'{\"json\": {}}'" - } - }, - "indexes": {}, - "foreignKeys": { - "item_board_id_board_id_fk": { - "name": "item_board_id_board_id_fk", - "tableFrom": "item", - "tableTo": "board", - "columnsFrom": ["board_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.layout": { - "name": "layout", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(32)", - "primaryKey": false, - "notNull": true - }, - "board_id": { - "name": "board_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "column_count": { - "name": "column_count", - "type": "smallint", - "primaryKey": false, - "notNull": true - }, - "breakpoint": { - "name": "breakpoint", - "type": "smallint", - "primaryKey": false, - "notNull": true, - "default": 0 - } - }, - "indexes": {}, - "foreignKeys": { - "layout_board_id_board_id_fk": { - "name": "layout_board_id_board_id_fk", - "tableFrom": "layout", - "tableTo": "board", - "columnsFrom": ["board_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.custom_widget_definition": { - "name": "custom_widget_definition", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(256)", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "icon_url": { - "name": "icon_url", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "url": { - "name": "url", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "auth_type": { - "name": "auth_type", - "type": "varchar(32)", - "primaryKey": false, - "notNull": true, - "default": "'none'" - }, - "header_name": { - "name": "header_name", - "type": "varchar(256)", - "primaryKey": false, - "notNull": false - }, - "method": { - "name": "method", - "type": "varchar(16)", - "primaryKey": false, - "notNull": true, - "default": "'GET'" - }, - "request_body": { - "name": "request_body", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "display_type": { - "name": "display_type", - "type": "varchar(32)", - "primaryKey": false, - "notNull": true, - "default": "'singleValue'" - }, - "display_config": { - "name": "display_config", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'{\"json\": {}}'" - }, - "enabled": { - "name": "enabled", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "creator_id": { - "name": "creator_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "custom_widget_definition_creator_id_user_id_fk": { - "name": "custom_widget_definition_creator_id_user_id_fk", - "tableFrom": "custom_widget_definition", - "tableTo": "user", - "columnsFrom": ["creator_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.custom_widget_secret": { - "name": "custom_widget_secret", - "schema": "", - "columns": { - "kind": { - "name": "kind", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "value": { - "name": "value", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true - }, - "definition_id": { - "name": "definition_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "custom_widget_secret_definition_id_custom_widget_definition_id_fk": { - "name": "custom_widget_secret_definition_id_custom_widget_definition_id_fk", - "tableFrom": "custom_widget_secret", - "tableTo": "custom_widget_definition", - "columnsFrom": ["definition_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "custom_widget_secret_definition_id_kind_pk": { - "name": "custom_widget_secret_definition_id_kind_pk", - "columns": ["definition_id", "kind"] - } - }, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.media": { - "name": "media", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(512)", - "primaryKey": false, - "notNull": true - }, - "content": { - "name": "content", - "type": "bytea", - "primaryKey": false, - "notNull": true - }, - "content_type": { - "name": "content_type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "size": { - "name": "size", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "creator_id": { - "name": "creator_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "media_creator_id_user_id_fk": { - "name": "media_creator_id_user_id_fk", - "tableFrom": "media", - "tableTo": "user", - "columnsFrom": ["creator_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.onboarding": { - "name": "onboarding", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": true, - "notNull": true - }, - "step": { - "name": "step", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "previous_step": { - "name": "previous_step", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.search_engine": { - "name": "search_engine", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": true, - "notNull": true - }, - "icon_url": { - "name": "icon_url", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "short": { - "name": "short", - "type": "varchar(8)", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "url_template": { - "name": "url_template", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "type": { - "name": "type", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "default": "'generic'" - }, - "integration_id": { - "name": "integration_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "search_engine_integration_id_integration_id_fk": { - "name": "search_engine_integration_id_integration_id_fk", - "tableFrom": "search_engine", - "tableTo": "integration", - "columnsFrom": ["integration_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "search_engine_short_unique": { - "name": "search_engine_short_unique", - "nullsNotDistinct": false, - "columns": ["short"] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.section_collapse_state": { - "name": "section_collapse_state", - "schema": "", - "columns": { - "user_id": { - "name": "user_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "section_id": { - "name": "section_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "collapsed": { - "name": "collapsed", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - } - }, - "indexes": {}, - "foreignKeys": { - "section_collapse_state_user_id_user_id_fk": { - "name": "section_collapse_state_user_id_user_id_fk", - "tableFrom": "section_collapse_state", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "section_collapse_state_section_id_section_id_fk": { - "name": "section_collapse_state_section_id_section_id_fk", - "tableFrom": "section_collapse_state", - "tableTo": "section", - "columnsFrom": ["section_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "section_collapse_state_user_id_section_id_pk": { - "name": "section_collapse_state_user_id_section_id_pk", - "columns": ["user_id", "section_id"] - } - }, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.section_layout": { - "name": "section_layout", - "schema": "", - "columns": { - "section_id": { - "name": "section_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "layout_id": { - "name": "layout_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "parent_section_id": { - "name": "parent_section_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false - }, - "x_offset": { - "name": "x_offset", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "y_offset": { - "name": "y_offset", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "width": { - "name": "width", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "height": { - "name": "height", - "type": "integer", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "section_layout_section_id_section_id_fk": { - "name": "section_layout_section_id_section_id_fk", - "tableFrom": "section_layout", - "tableTo": "section", - "columnsFrom": ["section_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "section_layout_layout_id_layout_id_fk": { - "name": "section_layout_layout_id_layout_id_fk", - "tableFrom": "section_layout", - "tableTo": "layout", - "columnsFrom": ["layout_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "section_layout_parent_section_id_section_id_fk": { - "name": "section_layout_parent_section_id_section_id_fk", - "tableFrom": "section_layout", - "tableTo": "section", - "columnsFrom": ["parent_section_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "section_layout_section_id_layout_id_pk": { - "name": "section_layout_section_id_layout_id_pk", - "columns": ["section_id", "layout_id"] - } - }, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.section": { - "name": "section", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": true, - "notNull": true - }, - "board_id": { - "name": "board_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "kind": { - "name": "kind", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "x_offset": { - "name": "x_offset", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "y_offset": { - "name": "y_offset", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "options": { - "name": "options", - "type": "text", - "primaryKey": false, - "notNull": false, - "default": "'{\"json\": {}}'" - } - }, - "indexes": {}, - "foreignKeys": { - "section_board_id_board_id_fk": { - "name": "section_board_id_board_id_fk", - "tableFrom": "section", - "tableTo": "board", - "columnsFrom": ["board_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.serverSetting": { - "name": "serverSetting", - "schema": "", - "columns": { - "setting_key": { - "name": "setting_key", - "type": "varchar(64)", - "primaryKey": true, - "notNull": true - }, - "value": { - "name": "value", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'{\"json\": {}}'" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "serverSetting_settingKey_unique": { - "name": "serverSetting_settingKey_unique", - "nullsNotDistinct": false, - "columns": ["setting_key"] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.session": { - "name": "session", - "schema": "", - "columns": { - "session_token": { - "name": "session_token", - "type": "varchar(512)", - "primaryKey": true, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "expires": { - "name": "expires", - "type": "timestamp", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "user_id_idx": { - "name": "user_id_idx", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "session_user_id_user_id_fk": { - "name": "session_user_id_user_id_fk", - "tableFrom": "session", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.trusted_certificate_hostname": { - "name": "trusted_certificate_hostname", - "schema": "", - "columns": { - "hostname": { - "name": "hostname", - "type": "varchar(256)", - "primaryKey": false, - "notNull": true - }, - "thumbprint": { - "name": "thumbprint", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - }, - "certificate": { - "name": "certificate", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": { - "trusted_certificate_hostname_hostname_thumbprint_pk": { - "name": "trusted_certificate_hostname_hostname_thumbprint_pk", - "columns": ["hostname", "thumbprint"] - } - }, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.user": { - "name": "user", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(64)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "email": { - "name": "email", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "email_verified": { - "name": "email_verified", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "image": { - "name": "image", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "password": { - "name": "password", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "provider": { - "name": "provider", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true, - "default": "'credentials'" - }, - "home_board_id": { - "name": "home_board_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false - }, - "mobile_home_board_id": { - "name": "mobile_home_board_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false - }, - "default_search_engine_id": { - "name": "default_search_engine_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false - }, - "open_search_in_new_tab": { - "name": "open_search_in_new_tab", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "ddg_bangs": { - "name": "ddg_bangs", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": true - }, - "color_scheme": { - "name": "color_scheme", - "type": "varchar(5)", - "primaryKey": false, - "notNull": true, - "default": "'dark'" - }, - "first_day_of_week": { - "name": "first_day_of_week", - "type": "smallint", - "primaryKey": false, - "notNull": true, - "default": 1 - }, - "ping_icons_enabled": { - "name": "ping_icons_enabled", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "enable_right_click_on_widgets": { - "name": "enable_right_click_on_widgets", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": true - }, - "completed_manage_tour": { - "name": "completed_manage_tour", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "completed_board_tour": { - "name": "completed_board_tour", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - } - }, - "indexes": {}, - "foreignKeys": { - "user_home_board_id_board_id_fk": { - "name": "user_home_board_id_board_id_fk", - "tableFrom": "user", - "tableTo": "board", - "columnsFrom": ["home_board_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - }, - "user_mobile_home_board_id_board_id_fk": { - "name": "user_mobile_home_board_id_board_id_fk", - "tableFrom": "user", - "tableTo": "board", - "columnsFrom": ["mobile_home_board_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - }, - "user_default_search_engine_id_search_engine_id_fk": { - "name": "user_default_search_engine_id_search_engine_id_fk", - "tableFrom": "user", - "tableTo": "search_engine", - "columnsFrom": ["default_search_engine_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.verificationToken": { - "name": "verificationToken", - "schema": "", - "columns": { - "identifier": { - "name": "identifier", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "token": { - "name": "token", - "type": "varchar(512)", - "primaryKey": false, - "notNull": true - }, - "expires": { - "name": "expires", - "type": "timestamp", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": { - "verificationToken_identifier_token_pk": { - "name": "verificationToken_identifier_token_pk", - "columns": ["identifier", "token"] - } - }, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.widget_secret": { - "name": "widget_secret", - "schema": "", - "columns": { - "item_id": { - "name": "item_id", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "kind": { - "name": "kind", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "value": { - "name": "value", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "widget_secret_item_id_item_id_fk": { - "name": "widget_secret_item_id_item_id_fk", - "tableFrom": "widget_secret", - "tableTo": "item", - "columnsFrom": ["item_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "widget_secret_item_id_kind_pk": { - "name": "widget_secret_item_id_kind_pk", - "columns": ["item_id", "kind"] - } - }, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - } - }, - "enums": {}, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} diff --git a/packages/db/migrations/postgresql/meta/_journal.json b/packages/db/migrations/postgresql/meta/_journal.json index 9a06391b2..42b4e6a2e 100644 --- a/packages/db/migrations/postgresql/meta/_journal.json +++ b/packages/db/migrations/postgresql/meta/_journal.json @@ -76,14 +76,7 @@ "idx": 10, "version": "7", "when": 1784305412862, - "tag": "0010_custom_widget_v2_reset", - "breakpoints": true - }, - { - "idx": 11, - "version": "7", - "when": 1785225823345, - "tag": "0011_custom_widget_v1_compatibility", + "tag": "0010_custom_widget_v2_tables", "breakpoints": true } ] diff --git a/packages/db/migrations/sqlite/0042_custom_widget_v2_reset.sql b/packages/db/migrations/sqlite/0042_custom_widget_v2_tables.sql similarity index 60% rename from packages/db/migrations/sqlite/0042_custom_widget_v2_reset.sql rename to packages/db/migrations/sqlite/0042_custom_widget_v2_tables.sql index b28b18b1c..da2e3b558 100644 --- a/packages/db/migrations/sqlite/0042_custom_widget_v2_reset.sql +++ b/packages/db/migrations/sqlite/0042_custom_widget_v2_tables.sql @@ -1,7 +1,4 @@ -PRAGMA foreign_keys=OFF;--> statement-breakpoint -ALTER TABLE `custom_widget_definition` RENAME TO `legacy_custom_widget_definition`;--> statement-breakpoint -ALTER TABLE `custom_widget_secret` RENAME TO `legacy_custom_widget_secret`;--> statement-breakpoint -CREATE TABLE `custom_widget_definition` ( +CREATE TABLE `custom_widget_v2_definition` ( `id` text PRIMARY KEY NOT NULL, `name` text NOT NULL, `description` text, @@ -16,13 +13,13 @@ CREATE TABLE `custom_widget_definition` ( `creator_id` text, FOREIGN KEY (`creator_id`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE set null );--> statement-breakpoint -CREATE TABLE `custom_widget_secret` ( +CREATE TABLE `custom_widget_v2_secret` ( `source_id` text NOT NULL, `kind` text NOT NULL, `encrypted_value` text NOT NULL, `updated_at` integer NOT NULL, `definition_id` text NOT NULL, PRIMARY KEY(`definition_id`, `source_id`, `kind`), - FOREIGN KEY (`definition_id`) REFERENCES `custom_widget_definition`(`id`) ON UPDATE no action ON DELETE cascade + FOREIGN KEY (`definition_id`) REFERENCES `custom_widget_v2_definition`(`id`) ON UPDATE no action ON DELETE cascade );--> statement-breakpoint -PRAGMA foreign_keys=ON; +DELETE FROM `groupPermission` WHERE `permission` IN ('custom-widget-manage', 'custom-widget-secret-write'); diff --git a/packages/db/migrations/sqlite/0043_custom_widget_v1_compatibility.sql b/packages/db/migrations/sqlite/0043_custom_widget_v1_compatibility.sql deleted file mode 100644 index 2e20704d2..000000000 --- a/packages/db/migrations/sqlite/0043_custom_widget_v1_compatibility.sql +++ /dev/null @@ -1,5 +0,0 @@ -ALTER TABLE `custom_widget_secret` RENAME TO `custom_widget_v2_secret`;--> statement-breakpoint -ALTER TABLE `custom_widget_definition` RENAME TO `custom_widget_v2_definition`;--> statement-breakpoint -ALTER TABLE `legacy_custom_widget_secret` RENAME TO `custom_widget_secret`;--> statement-breakpoint -ALTER TABLE `legacy_custom_widget_definition` RENAME TO `custom_widget_definition`;--> statement-breakpoint -DELETE FROM `groupPermission` WHERE `permission` IN ('custom-widget-manage', 'custom-widget-secret-write'); diff --git a/packages/db/migrations/sqlite/meta/0042_snapshot.json b/packages/db/migrations/sqlite/meta/0042_snapshot.json index 7864ccd81..035c92837 100644 --- a/packages/db/migrations/sqlite/meta/0042_snapshot.json +++ b/packages/db/migrations/sqlite/meta/0042_snapshot.json @@ -1,7 +1,7 @@ { "version": "6", "dialect": "sqlite", - "id": "30bbf6f8-3a3c-4cb0-994e-9d8494e4fcd0", + "id": "51923913-fdc0-4ae7-9127-e86587e0b51f", "prevId": "852e049b-72cc-4d7f-8be9-931c042fe019", "tables": { "account": { @@ -515,193 +515,8 @@ "uniqueConstraints": {}, "checkConstraints": {} }, - "legacy_custom_widget_definition": { - "name": "legacy_custom_widget_definition", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "icon_url": { - "name": "icon_url", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "url": { - "name": "url", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "auth_type": { - "name": "auth_type", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'none'" - }, - "header_name": { - "name": "header_name", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "method": { - "name": "method", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'GET'" - }, - "request_body": { - "name": "request_body", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "display_type": { - "name": "display_type", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'singleValue'" - }, - "display_config": { - "name": "display_config", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'{\"json\": {}}'" - }, - "enabled": { - "name": "enabled", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": true - }, - "created_at": { - "name": "created_at", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "(unixepoch())" - }, - "updated_at": { - "name": "updated_at", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "(unixepoch())" - }, - "creator_id": { - "name": "creator_id", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "legacy_cw_definition_creator_id_user_id_fk": { - "name": "legacy_cw_definition_creator_id_user_id_fk", - "tableFrom": "legacy_custom_widget_definition", - "tableTo": "user", - "columnsFrom": ["creator_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "legacy_custom_widget_secret": { - "name": "legacy_custom_widget_secret", - "columns": { - "kind": { - "name": "kind", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "value": { - "name": "value", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "updated_at": { - "name": "updated_at", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "definition_id": { - "name": "definition_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "legacy_cw_secret_definition_id_fk": { - "name": "legacy_cw_secret_definition_id_fk", - "tableFrom": "legacy_custom_widget_secret", - "tableTo": "legacy_custom_widget_definition", - "columnsFrom": ["definition_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "legacy_custom_widget_secret_definition_id_kind_pk": { - "columns": ["definition_id", "kind"], - "name": "legacy_custom_widget_secret_definition_id_kind_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "custom_widget_definition": { - "name": "custom_widget_definition", + "custom_widget_v2_definition": { + "name": "custom_widget_v2_definition", "columns": { "id": { "name": "id", @@ -793,9 +608,9 @@ }, "indexes": {}, "foreignKeys": { - "custom_widget_definition_creator_id_user_id_fk": { - "name": "custom_widget_definition_creator_id_user_id_fk", - "tableFrom": "custom_widget_definition", + "custom_widget_v2_definition_creator_id_user_id_fk": { + "name": "custom_widget_v2_definition_creator_id_user_id_fk", + "tableFrom": "custom_widget_v2_definition", "tableTo": "user", "columnsFrom": ["creator_id"], "columnsTo": ["id"], @@ -807,8 +622,8 @@ "uniqueConstraints": {}, "checkConstraints": {} }, - "custom_widget_secret": { - "name": "custom_widget_secret", + "custom_widget_v2_secret": { + "name": "custom_widget_v2_secret", "columns": { "source_id": { "name": "source_id", @@ -848,10 +663,10 @@ }, "indexes": {}, "foreignKeys": { - "cw_secret_definition_id_fk": { - "name": "cw_secret_definition_id_fk", - "tableFrom": "custom_widget_secret", - "tableTo": "custom_widget_definition", + "custom_widget_v2_secret_definition_id_fk": { + "name": "custom_widget_v2_secret_definition_id_fk", + "tableFrom": "custom_widget_v2_secret", + "tableTo": "custom_widget_v2_definition", "columnsFrom": ["definition_id"], "columnsTo": ["id"], "onDelete": "cascade", @@ -859,9 +674,9 @@ } }, "compositePrimaryKeys": { - "custom_widget_secret_definition_id_source_id_kind_pk": { + "custom_widget_v2_secret_definition_id_source_id_kind_pk": { "columns": ["definition_id", "source_id", "kind"], - "name": "custom_widget_secret_definition_id_source_id_kind_pk" + "name": "custom_widget_v2_secret_definition_id_source_id_kind_pk" } }, "uniqueConstraints": {}, @@ -1656,6 +1471,191 @@ "uniqueConstraints": {}, "checkConstraints": {} }, + "custom_widget_definition": { + "name": "custom_widget_definition", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "icon_url": { + "name": "icon_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "auth_type": { + "name": "auth_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'none'" + }, + "header_name": { + "name": "header_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "method": { + "name": "method", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'GET'" + }, + "request_body": { + "name": "request_body", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "display_type": { + "name": "display_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'singleValue'" + }, + "display_config": { + "name": "display_config", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'{\"json\": {}}'" + }, + "enabled": { + "name": "enabled", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(unixepoch())" + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(unixepoch())" + }, + "creator_id": { + "name": "creator_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "custom_widget_definition_creator_id_user_id_fk": { + "name": "custom_widget_definition_creator_id_user_id_fk", + "tableFrom": "custom_widget_definition", + "tableTo": "user", + "columnsFrom": ["creator_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "custom_widget_secret": { + "name": "custom_widget_secret", + "columns": { + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "definition_id": { + "name": "definition_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "custom_widget_secret_definition_id_custom_widget_definition_id_fk": { + "name": "custom_widget_secret_definition_id_custom_widget_definition_id_fk", + "tableFrom": "custom_widget_secret", + "tableTo": "custom_widget_definition", + "columnsFrom": ["definition_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "custom_widget_secret_definition_id_kind_pk": { + "columns": ["definition_id", "kind"], + "name": "custom_widget_secret_definition_id_kind_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, "media": { "name": "media", "columns": { diff --git a/packages/db/migrations/sqlite/meta/0043_snapshot.json b/packages/db/migrations/sqlite/meta/0043_snapshot.json deleted file mode 100644 index ffd8c29ec..000000000 --- a/packages/db/migrations/sqlite/meta/0043_snapshot.json +++ /dev/null @@ -1,2448 +0,0 @@ -{ - "version": "6", - "dialect": "sqlite", - "id": "51923913-fdc0-4ae7-9127-e86587e0b51f", - "prevId": "30bbf6f8-3a3c-4cb0-994e-9d8494e4fcd0", - "tables": { - "account": { - "name": "account", - "columns": { - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "type": { - "name": "type", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "provider": { - "name": "provider", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "provider_account_id": { - "name": "provider_account_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "refresh_token": { - "name": "refresh_token", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "access_token": { - "name": "access_token", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "expires_at": { - "name": "expires_at", - "type": "integer", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "token_type": { - "name": "token_type", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "scope": { - "name": "scope", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "id_token": { - "name": "id_token", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "session_state": { - "name": "session_state", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": { - "userId_idx": { - "name": "userId_idx", - "columns": ["user_id"], - "isUnique": false - } - }, - "foreignKeys": { - "account_user_id_user_id_fk": { - "name": "account_user_id_user_id_fk", - "tableFrom": "account", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "account_provider_provider_account_id_pk": { - "columns": ["provider", "provider_account_id"], - "name": "account_provider_provider_account_id_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "apiKey": { - "name": "apiKey", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "api_key": { - "name": "api_key", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "apiKey_user_id_user_id_fk": { - "name": "apiKey_user_id_user_id_fk", - "tableFrom": "apiKey", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "app": { - "name": "app", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "icon_url": { - "name": "icon_url", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "href": { - "name": "href", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "ping_url": { - "name": "ping_url", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "boardGroupPermission": { - "name": "boardGroupPermission", - "columns": { - "board_id": { - "name": "board_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "group_id": { - "name": "group_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "permission": { - "name": "permission", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "boardGroupPermission_board_id_board_id_fk": { - "name": "boardGroupPermission_board_id_board_id_fk", - "tableFrom": "boardGroupPermission", - "tableTo": "board", - "columnsFrom": ["board_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "boardGroupPermission_group_id_group_id_fk": { - "name": "boardGroupPermission_group_id_group_id_fk", - "tableFrom": "boardGroupPermission", - "tableTo": "group", - "columnsFrom": ["group_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "boardGroupPermission_board_id_group_id_permission_pk": { - "columns": ["board_id", "group_id", "permission"], - "name": "boardGroupPermission_board_id_group_id_permission_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "boardUserPermission": { - "name": "boardUserPermission", - "columns": { - "board_id": { - "name": "board_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "permission": { - "name": "permission", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "boardUserPermission_board_id_board_id_fk": { - "name": "boardUserPermission_board_id_board_id_fk", - "tableFrom": "boardUserPermission", - "tableTo": "board", - "columnsFrom": ["board_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "boardUserPermission_user_id_user_id_fk": { - "name": "boardUserPermission_user_id_user_id_fk", - "tableFrom": "boardUserPermission", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "boardUserPermission_board_id_user_id_permission_pk": { - "columns": ["board_id", "user_id", "permission"], - "name": "boardUserPermission_board_id_user_id_permission_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "board": { - "name": "board", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "is_public": { - "name": "is_public", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": false - }, - "creator_id": { - "name": "creator_id", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "page_title": { - "name": "page_title", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "meta_title": { - "name": "meta_title", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "logo_image_url": { - "name": "logo_image_url", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "favicon_image_url": { - "name": "favicon_image_url", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "background_image_url": { - "name": "background_image_url", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "background_image_attachment": { - "name": "background_image_attachment", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'fixed'" - }, - "background_image_repeat": { - "name": "background_image_repeat", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'no-repeat'" - }, - "background_image_size": { - "name": "background_image_size", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'cover'" - }, - "primary_color": { - "name": "primary_color", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'#fa5252'" - }, - "secondary_color": { - "name": "secondary_color", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'#fd7e14'" - }, - "opacity": { - "name": "opacity", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": 100 - }, - "custom_css": { - "name": "custom_css", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "icon_color": { - "name": "icon_color", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "item_radius": { - "name": "item_radius", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'lg'" - }, - "disable_status": { - "name": "disable_status", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": false - } - }, - "indexes": { - "board_name_unique": { - "name": "board_name_unique", - "columns": ["name"], - "isUnique": true - } - }, - "foreignKeys": { - "board_creator_id_user_id_fk": { - "name": "board_creator_id_user_id_fk", - "tableFrom": "board", - "tableTo": "user", - "columnsFrom": ["creator_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "cron_job_configuration": { - "name": "cron_job_configuration", - "columns": { - "name": { - "name": "name", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "cron_expression": { - "name": "cron_expression", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "is_enabled": { - "name": "is_enabled", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": true - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "custom_widget_v2_definition": { - "name": "custom_widget_v2_definition", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "icon_url": { - "name": "icon_url", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "sources": { - "name": "sources", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "requests": { - "name": "requests", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "options": { - "name": "options", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "template": { - "name": "template", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "enabled": { - "name": "enabled", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": true - }, - "created_at": { - "name": "created_at", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "(unixepoch())" - }, - "updated_at": { - "name": "updated_at", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "(unixepoch())" - }, - "creator_id": { - "name": "creator_id", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "custom_widget_v2_definition_creator_id_user_id_fk": { - "name": "custom_widget_v2_definition_creator_id_user_id_fk", - "tableFrom": "custom_widget_v2_definition", - "tableTo": "user", - "columnsFrom": ["creator_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "custom_widget_v2_secret": { - "name": "custom_widget_v2_secret", - "columns": { - "source_id": { - "name": "source_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "kind": { - "name": "kind", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "encrypted_value": { - "name": "encrypted_value", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "updated_at": { - "name": "updated_at", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "definition_id": { - "name": "definition_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "custom_widget_v2_secret_definition_id_fk": { - "name": "custom_widget_v2_secret_definition_id_fk", - "tableFrom": "custom_widget_v2_secret", - "tableTo": "custom_widget_v2_definition", - "columnsFrom": ["definition_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "custom_widget_v2_secret_definition_id_source_id_kind_pk": { - "columns": ["definition_id", "source_id", "kind"], - "name": "custom_widget_v2_secret_definition_id_source_id_kind_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "groupMember": { - "name": "groupMember", - "columns": { - "group_id": { - "name": "group_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "groupMember_group_id_group_id_fk": { - "name": "groupMember_group_id_group_id_fk", - "tableFrom": "groupMember", - "tableTo": "group", - "columnsFrom": ["group_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "groupMember_user_id_user_id_fk": { - "name": "groupMember_user_id_user_id_fk", - "tableFrom": "groupMember", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "groupMember_group_id_user_id_pk": { - "columns": ["group_id", "user_id"], - "name": "groupMember_group_id_user_id_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "groupPermission": { - "name": "groupPermission", - "columns": { - "group_id": { - "name": "group_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "permission": { - "name": "permission", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "groupPermission_group_id_group_id_fk": { - "name": "groupPermission_group_id_group_id_fk", - "tableFrom": "groupPermission", - "tableTo": "group", - "columnsFrom": ["group_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "group": { - "name": "group", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "owner_id": { - "name": "owner_id", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "home_board_id": { - "name": "home_board_id", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "mobile_home_board_id": { - "name": "mobile_home_board_id", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "position": { - "name": "position", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": { - "group_name_unique": { - "name": "group_name_unique", - "columns": ["name"], - "isUnique": true - } - }, - "foreignKeys": { - "group_owner_id_user_id_fk": { - "name": "group_owner_id_user_id_fk", - "tableFrom": "group", - "tableTo": "user", - "columnsFrom": ["owner_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - }, - "group_home_board_id_board_id_fk": { - "name": "group_home_board_id_board_id_fk", - "tableFrom": "group", - "tableTo": "board", - "columnsFrom": ["home_board_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - }, - "group_mobile_home_board_id_board_id_fk": { - "name": "group_mobile_home_board_id_board_id_fk", - "tableFrom": "group", - "tableTo": "board", - "columnsFrom": ["mobile_home_board_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "iconRepository": { - "name": "iconRepository", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "slug": { - "name": "slug", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "icon": { - "name": "icon", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "url": { - "name": "url", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "checksum": { - "name": "checksum", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "icon_repository_id": { - "name": "icon_repository_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "icon_icon_repository_id_iconRepository_id_fk": { - "name": "icon_icon_repository_id_iconRepository_id_fk", - "tableFrom": "icon", - "tableTo": "iconRepository", - "columnsFrom": ["icon_repository_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "integrationGroupPermissions": { - "name": "integrationGroupPermissions", - "columns": { - "integration_id": { - "name": "integration_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "group_id": { - "name": "group_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "permission": { - "name": "permission", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "integrationGroupPermissions_integration_id_integration_id_fk": { - "name": "integrationGroupPermissions_integration_id_integration_id_fk", - "tableFrom": "integrationGroupPermissions", - "tableTo": "integration", - "columnsFrom": ["integration_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "integrationGroupPermissions_group_id_group_id_fk": { - "name": "integrationGroupPermissions_group_id_group_id_fk", - "tableFrom": "integrationGroupPermissions", - "tableTo": "group", - "columnsFrom": ["group_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "integrationGroupPermissions_integration_id_group_id_permission_pk": { - "columns": ["integration_id", "group_id", "permission"], - "name": "integrationGroupPermissions_integration_id_group_id_permission_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "integration_item": { - "name": "integration_item", - "columns": { - "item_id": { - "name": "item_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "integration_id": { - "name": "integration_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "integration_item_item_id_item_id_fk": { - "name": "integration_item_item_id_item_id_fk", - "tableFrom": "integration_item", - "tableTo": "item", - "columnsFrom": ["item_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "integration_item_integration_id_integration_id_fk": { - "name": "integration_item_integration_id_integration_id_fk", - "tableFrom": "integration_item", - "tableTo": "integration", - "columnsFrom": ["integration_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "integration_item_item_id_integration_id_pk": { - "columns": ["item_id", "integration_id"], - "name": "integration_item_item_id_integration_id_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "integrationSecret": { - "name": "integrationSecret", - "columns": { - "kind": { - "name": "kind", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "value": { - "name": "value", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "updated_at": { - "name": "updated_at", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "integration_id": { - "name": "integration_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": { - "integration_secret__kind_idx": { - "name": "integration_secret__kind_idx", - "columns": ["kind"], - "isUnique": false - }, - "integration_secret__updated_at_idx": { - "name": "integration_secret__updated_at_idx", - "columns": ["updated_at"], - "isUnique": false - } - }, - "foreignKeys": { - "integrationSecret_integration_id_integration_id_fk": { - "name": "integrationSecret_integration_id_integration_id_fk", - "tableFrom": "integrationSecret", - "tableTo": "integration", - "columnsFrom": ["integration_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "integrationSecret_integration_id_kind_pk": { - "columns": ["integration_id", "kind"], - "name": "integrationSecret_integration_id_kind_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "integrationUserPermission": { - "name": "integrationUserPermission", - "columns": { - "integration_id": { - "name": "integration_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "permission": { - "name": "permission", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "integrationUserPermission_integration_id_integration_id_fk": { - "name": "integrationUserPermission_integration_id_integration_id_fk", - "tableFrom": "integrationUserPermission", - "tableTo": "integration", - "columnsFrom": ["integration_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "integrationUserPermission_user_id_user_id_fk": { - "name": "integrationUserPermission_user_id_user_id_fk", - "tableFrom": "integrationUserPermission", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "integrationUserPermission_integration_id_user_id_permission_pk": { - "columns": ["integration_id", "user_id", "permission"], - "name": "integrationUserPermission_integration_id_user_id_permission_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "integration": { - "name": "integration", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "url": { - "name": "url", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "kind": { - "name": "kind", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "app_id": { - "name": "app_id", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": { - "integration__kind_idx": { - "name": "integration__kind_idx", - "columns": ["kind"], - "isUnique": false - } - }, - "foreignKeys": { - "integration_app_id_app_id_fk": { - "name": "integration_app_id_app_id_fk", - "tableFrom": "integration", - "tableTo": "app", - "columnsFrom": ["app_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "invite": { - "name": "invite", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "token": { - "name": "token", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "expiration_date": { - "name": "expiration_date", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "creator_id": { - "name": "creator_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": { - "invite_token_unique": { - "name": "invite_token_unique", - "columns": ["token"], - "isUnique": true - } - }, - "foreignKeys": { - "invite_creator_id_user_id_fk": { - "name": "invite_creator_id_user_id_fk", - "tableFrom": "invite", - "tableTo": "user", - "columnsFrom": ["creator_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "item_layout": { - "name": "item_layout", - "columns": { - "item_id": { - "name": "item_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "section_id": { - "name": "section_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "layout_id": { - "name": "layout_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "x_offset": { - "name": "x_offset", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "y_offset": { - "name": "y_offset", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "width": { - "name": "width", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "height": { - "name": "height", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "item_layout_item_id_item_id_fk": { - "name": "item_layout_item_id_item_id_fk", - "tableFrom": "item_layout", - "tableTo": "item", - "columnsFrom": ["item_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "item_layout_section_id_section_id_fk": { - "name": "item_layout_section_id_section_id_fk", - "tableFrom": "item_layout", - "tableTo": "section", - "columnsFrom": ["section_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "item_layout_layout_id_layout_id_fk": { - "name": "item_layout_layout_id_layout_id_fk", - "tableFrom": "item_layout", - "tableTo": "layout", - "columnsFrom": ["layout_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "item_layout_item_id_section_id_layout_id_pk": { - "columns": ["item_id", "section_id", "layout_id"], - "name": "item_layout_item_id_section_id_layout_id_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "item": { - "name": "item", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "board_id": { - "name": "board_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "kind": { - "name": "kind", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "options": { - "name": "options", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'{\"json\": {}}'" - }, - "advanced_options": { - "name": "advanced_options", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'{\"json\": {}}'" - } - }, - "indexes": {}, - "foreignKeys": { - "item_board_id_board_id_fk": { - "name": "item_board_id_board_id_fk", - "tableFrom": "item", - "tableTo": "board", - "columnsFrom": ["board_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "layout": { - "name": "layout", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "board_id": { - "name": "board_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "column_count": { - "name": "column_count", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "breakpoint": { - "name": "breakpoint", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": 0 - } - }, - "indexes": {}, - "foreignKeys": { - "layout_board_id_board_id_fk": { - "name": "layout_board_id_board_id_fk", - "tableFrom": "layout", - "tableTo": "board", - "columnsFrom": ["board_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "custom_widget_definition": { - "name": "custom_widget_definition", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "icon_url": { - "name": "icon_url", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "url": { - "name": "url", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "auth_type": { - "name": "auth_type", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'none'" - }, - "header_name": { - "name": "header_name", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "method": { - "name": "method", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'GET'" - }, - "request_body": { - "name": "request_body", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "display_type": { - "name": "display_type", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'singleValue'" - }, - "display_config": { - "name": "display_config", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'{\"json\": {}}'" - }, - "enabled": { - "name": "enabled", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": true - }, - "created_at": { - "name": "created_at", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "(unixepoch())" - }, - "updated_at": { - "name": "updated_at", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "(unixepoch())" - }, - "creator_id": { - "name": "creator_id", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "custom_widget_definition_creator_id_user_id_fk": { - "name": "custom_widget_definition_creator_id_user_id_fk", - "tableFrom": "custom_widget_definition", - "tableTo": "user", - "columnsFrom": ["creator_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "custom_widget_secret": { - "name": "custom_widget_secret", - "columns": { - "kind": { - "name": "kind", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "value": { - "name": "value", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "updated_at": { - "name": "updated_at", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "definition_id": { - "name": "definition_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "custom_widget_secret_definition_id_custom_widget_definition_id_fk": { - "name": "custom_widget_secret_definition_id_custom_widget_definition_id_fk", - "tableFrom": "custom_widget_secret", - "tableTo": "custom_widget_definition", - "columnsFrom": ["definition_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "custom_widget_secret_definition_id_kind_pk": { - "columns": ["definition_id", "kind"], - "name": "custom_widget_secret_definition_id_kind_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "media": { - "name": "media", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "content": { - "name": "content", - "type": "blob", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "content_type": { - "name": "content_type", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "size": { - "name": "size", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "created_at": { - "name": "created_at", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "(unixepoch())" - }, - "creator_id": { - "name": "creator_id", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "media_creator_id_user_id_fk": { - "name": "media_creator_id_user_id_fk", - "tableFrom": "media", - "tableTo": "user", - "columnsFrom": ["creator_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "onboarding": { - "name": "onboarding", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "step": { - "name": "step", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "previous_step": { - "name": "previous_step", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "search_engine": { - "name": "search_engine", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "icon_url": { - "name": "icon_url", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "short": { - "name": "short", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "url_template": { - "name": "url_template", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "type": { - "name": "type", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'generic'" - }, - "integration_id": { - "name": "integration_id", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": { - "search_engine_short_unique": { - "name": "search_engine_short_unique", - "columns": ["short"], - "isUnique": true - } - }, - "foreignKeys": { - "search_engine_integration_id_integration_id_fk": { - "name": "search_engine_integration_id_integration_id_fk", - "tableFrom": "search_engine", - "tableTo": "integration", - "columnsFrom": ["integration_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "section_collapse_state": { - "name": "section_collapse_state", - "columns": { - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "section_id": { - "name": "section_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "collapsed": { - "name": "collapsed", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": false - } - }, - "indexes": {}, - "foreignKeys": { - "section_collapse_state_user_id_user_id_fk": { - "name": "section_collapse_state_user_id_user_id_fk", - "tableFrom": "section_collapse_state", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "section_collapse_state_section_id_section_id_fk": { - "name": "section_collapse_state_section_id_section_id_fk", - "tableFrom": "section_collapse_state", - "tableTo": "section", - "columnsFrom": ["section_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "section_collapse_state_user_id_section_id_pk": { - "columns": ["user_id", "section_id"], - "name": "section_collapse_state_user_id_section_id_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "section_layout": { - "name": "section_layout", - "columns": { - "section_id": { - "name": "section_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "layout_id": { - "name": "layout_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "parent_section_id": { - "name": "parent_section_id", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "x_offset": { - "name": "x_offset", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "y_offset": { - "name": "y_offset", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "width": { - "name": "width", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "height": { - "name": "height", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "section_layout_section_id_section_id_fk": { - "name": "section_layout_section_id_section_id_fk", - "tableFrom": "section_layout", - "tableTo": "section", - "columnsFrom": ["section_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "section_layout_layout_id_layout_id_fk": { - "name": "section_layout_layout_id_layout_id_fk", - "tableFrom": "section_layout", - "tableTo": "layout", - "columnsFrom": ["layout_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "section_layout_parent_section_id_section_id_fk": { - "name": "section_layout_parent_section_id_section_id_fk", - "tableFrom": "section_layout", - "tableTo": "section", - "columnsFrom": ["parent_section_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "section_layout_section_id_layout_id_pk": { - "columns": ["section_id", "layout_id"], - "name": "section_layout_section_id_layout_id_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "section": { - "name": "section", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "board_id": { - "name": "board_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "kind": { - "name": "kind", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "x_offset": { - "name": "x_offset", - "type": "integer", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "y_offset": { - "name": "y_offset", - "type": "integer", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "options": { - "name": "options", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false, - "default": "'{\"json\": {}}'" - } - }, - "indexes": {}, - "foreignKeys": { - "section_board_id_board_id_fk": { - "name": "section_board_id_board_id_fk", - "tableFrom": "section", - "tableTo": "board", - "columnsFrom": ["board_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "serverSetting": { - "name": "serverSetting", - "columns": { - "setting_key": { - "name": "setting_key", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "value": { - "name": "value", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'{\"json\": {}}'" - } - }, - "indexes": { - "serverSetting_settingKey_unique": { - "name": "serverSetting_settingKey_unique", - "columns": ["setting_key"], - "isUnique": true - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "session": { - "name": "session", - "columns": { - "session_token": { - "name": "session_token", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "expires": { - "name": "expires", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": { - "user_id_idx": { - "name": "user_id_idx", - "columns": ["user_id"], - "isUnique": false - } - }, - "foreignKeys": { - "session_user_id_user_id_fk": { - "name": "session_user_id_user_id_fk", - "tableFrom": "session", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "trusted_certificate_hostname": { - "name": "trusted_certificate_hostname", - "columns": { - "hostname": { - "name": "hostname", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "thumbprint": { - "name": "thumbprint", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "certificate": { - "name": "certificate", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": { - "trusted_certificate_hostname_hostname_thumbprint_pk": { - "columns": ["hostname", "thumbprint"], - "name": "trusted_certificate_hostname_hostname_thumbprint_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "user": { - "name": "user", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "email": { - "name": "email", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "email_verified": { - "name": "email_verified", - "type": "integer", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "image": { - "name": "image", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "password": { - "name": "password", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "provider": { - "name": "provider", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'credentials'" - }, - "home_board_id": { - "name": "home_board_id", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "mobile_home_board_id": { - "name": "mobile_home_board_id", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "default_search_engine_id": { - "name": "default_search_engine_id", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "open_search_in_new_tab": { - "name": "open_search_in_new_tab", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": true - }, - "ddg_bangs": { - "name": "ddg_bangs", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": true - }, - "color_scheme": { - "name": "color_scheme", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'dark'" - }, - "first_day_of_week": { - "name": "first_day_of_week", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": 1 - }, - "ping_icons_enabled": { - "name": "ping_icons_enabled", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": false - }, - "enable_right_click_on_widgets": { - "name": "enable_right_click_on_widgets", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": true - }, - "completed_manage_tour": { - "name": "completed_manage_tour", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": false - }, - "completed_board_tour": { - "name": "completed_board_tour", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": false - } - }, - "indexes": {}, - "foreignKeys": { - "user_home_board_id_board_id_fk": { - "name": "user_home_board_id_board_id_fk", - "tableFrom": "user", - "tableTo": "board", - "columnsFrom": ["home_board_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - }, - "user_mobile_home_board_id_board_id_fk": { - "name": "user_mobile_home_board_id_board_id_fk", - "tableFrom": "user", - "tableTo": "board", - "columnsFrom": ["mobile_home_board_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - }, - "user_default_search_engine_id_search_engine_id_fk": { - "name": "user_default_search_engine_id_search_engine_id_fk", - "tableFrom": "user", - "tableTo": "search_engine", - "columnsFrom": ["default_search_engine_id"], - "columnsTo": ["id"], - "onDelete": "set null", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "verificationToken": { - "name": "verificationToken", - "columns": { - "identifier": { - "name": "identifier", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "token": { - "name": "token", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "expires": { - "name": "expires", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": { - "verificationToken_identifier_token_pk": { - "columns": ["identifier", "token"], - "name": "verificationToken_identifier_token_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "widget_secret": { - "name": "widget_secret", - "columns": { - "item_id": { - "name": "item_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "kind": { - "name": "kind", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "value": { - "name": "value", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "updated_at": { - "name": "updated_at", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "widget_secret_item_id_item_id_fk": { - "name": "widget_secret_item_id_item_id_fk", - "tableFrom": "widget_secret", - "tableTo": "item", - "columnsFrom": ["item_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "widget_secret_item_id_kind_pk": { - "columns": ["item_id", "kind"], - "name": "widget_secret_item_id_kind_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - } - }, - "views": {}, - "enums": {}, - "_meta": { - "schemas": {}, - "tables": {}, - "columns": {} - }, - "internal": { - "indexes": {} - } -} diff --git a/packages/db/migrations/sqlite/meta/_journal.json b/packages/db/migrations/sqlite/meta/_journal.json index 089a52536..62ec49683 100644 --- a/packages/db/migrations/sqlite/meta/_journal.json +++ b/packages/db/migrations/sqlite/meta/_journal.json @@ -300,14 +300,7 @@ "idx": 42, "version": "6", "when": 1784305283910, - "tag": "0042_custom_widget_v2_reset", - "breakpoints": true - }, - { - "idx": 43, - "version": "6", - "when": 1785225790467, - "tag": "0043_custom_widget_v1_compatibility", + "tag": "0042_custom_widget_v2_tables", "breakpoints": true } ] diff --git a/packages/db/test/mysql-migration.spec.ts b/packages/db/test/mysql-migration.spec.ts index 4c449d409..93115a3e4 100644 --- a/packages/db/test/mysql-migration.spec.ts +++ b/packages/db/test/mysql-migration.spec.ts @@ -60,7 +60,7 @@ describe("Mysql Migration", () => { await mysqlContainer.stop(); }, 90_000); - test("preserves v1 and already-created v2 custom widgets, secrets, and board references", async () => { + test("Custom Widget v2 migration preserves v1 data and board references", async () => { const mysqlContainer = await new MySqlContainer("mysql:latest").start(); const connection = mysql.createConnection({ host: mysqlContainer.getHost(), @@ -132,20 +132,19 @@ describe("Mysql Migration", () => { legacyPlacementOptions, ]); - await applyMigration(connection, "0044_custom_widget_v2_reset.sql"); + await applyMigration(connection, "0044_custom_widget_v2_tables.sql"); await sql.query(` - INSERT INTO \`custom_widget_definition\` ( + INSERT INTO \`custom_widget_v2_definition\` ( \`id\`, \`name\`, \`sources\`, \`requests\`, \`options\`, \`template\`, \`enabled\`, \`created_at\`, \`updated_at\`, \`creator_id\` ) VALUES ( 'legacy-weather', 'Weather v2', '[]', '[]', '[]', 'Weather', true, '2023-11-14 00:00:02', '2023-11-14 00:00:03', 'owner' ); - INSERT INTO \`custom_widget_secret\` ( + INSERT INTO \`custom_widget_v2_secret\` ( \`source_id\`, \`kind\`, \`encrypted_value\`, \`updated_at\`, \`definition_id\` ) VALUES ('weather', 'apiKey', 'encrypted.v2-value', '2023-11-14 00:00:03', 'legacy-weather'); `); - await applyMigration(connection, "0045_custom_widget_v1_compatibility.sql"); const [definitions] = await sql.query( "SELECT id, name, url, enabled, creator_id FROM custom_widget_definition", diff --git a/packages/db/test/postgresql-migration.spec.ts b/packages/db/test/postgresql-migration.spec.ts index 7530dd8d7..de29775c0 100644 --- a/packages/db/test/postgresql-migration.spec.ts +++ b/packages/db/test/postgresql-migration.spec.ts @@ -70,7 +70,7 @@ describe("PostgreSql Migration", () => { await postgreSqlContainer.stop(); }, 40_000); - test("preserves v1 and already-created v2 custom widgets, secrets, and board references", async () => { + test("Custom Widget v2 migration preserves v1 data and board references", async () => { const postgreSqlContainer = await new PostgreSqlContainer("postgres:latest").start(); const pool = new Pool({ user: postgreSqlContainer.getUsername(), @@ -140,20 +140,19 @@ describe("PostgreSql Migration", () => { legacyPlacementOptions, ]); - await applyMigration(pool, "0010_custom_widget_v2_reset.sql"); + await applyMigration(pool, "0010_custom_widget_v2_tables.sql"); await pool.query(` - INSERT INTO "custom_widget_definition" ( + INSERT INTO "custom_widget_v2_definition" ( "id", "name", "sources", "requests", "options", "template", "enabled", "created_at", "updated_at", "creator_id" ) VALUES ( 'legacy-weather', 'Weather v2', '[]', '[]', '[]', 'Weather', true, '2023-11-14 00:00:02', '2023-11-14 00:00:03', 'owner' ); - INSERT INTO "custom_widget_secret" ( + INSERT INTO "custom_widget_v2_secret" ( "source_id", "kind", "encrypted_value", "updated_at", "definition_id" ) VALUES ('weather', 'apiKey', 'encrypted.v2-value', '2023-11-14 00:00:03', 'legacy-weather'); `); - await applyMigration(pool, "0011_custom_widget_v1_compatibility.sql"); expect( (await pool.query("SELECT id, name, url, enabled, creator_id FROM custom_widget_definition")).rows, diff --git a/packages/db/test/sqlite-migration.spec.ts b/packages/db/test/sqlite-migration.spec.ts index 43073017f..ff21bbd9b 100644 --- a/packages/db/test/sqlite-migration.spec.ts +++ b/packages/db/test/sqlite-migration.spec.ts @@ -45,7 +45,7 @@ test("SQLite migrations seed the five disabled bundled custom widgets", async () connection.close(); }); -test("Custom JSX compatibility migration preserves v1 and already-created v2 data", () => { +test("Custom Widget v2 migration preserves v1 data and board references", () => { const connection = new BetterSqlite3(":memory:"); const legacyPlacementOptions = SuperJSON.stringify({ definitionId: "legacy-weather", refreshInterval: 30 }); connection.exec(` @@ -99,18 +99,17 @@ test("Custom JSX compatibility migration preserves v1 and already-created v2 dat .prepare("INSERT INTO item (id, kind, options) VALUES ('weather-item', 'customApi', ?)") .run(legacyPlacementOptions); - applyMigration(connection, "0042_custom_widget_v2_reset.sql"); + applyMigration(connection, "0042_custom_widget_v2_tables.sql"); connection.exec(` - INSERT INTO custom_widget_definition ( + INSERT INTO custom_widget_v2_definition ( id, name, sources, requests, options, template, enabled, created_at, updated_at, creator_id ) VALUES ( 'legacy-weather', 'Weather v2', '[]', '[]', '[]', 'Weather', true, 1700000002, 1700000003, 'owner' ); - INSERT INTO custom_widget_secret (source_id, kind, encrypted_value, updated_at, definition_id) + INSERT INTO custom_widget_v2_secret (source_id, kind, encrypted_value, updated_at, definition_id) VALUES ('weather', 'apiKey', 'encrypted.v2-value', 1700000003, 'legacy-weather'); `); - applyMigration(connection, "0043_custom_widget_v1_compatibility.sql"); expect(connection.prepare("SELECT * FROM custom_widget_definition").get()).toMatchObject({ id: "legacy-weather", diff --git a/packages/workshop/package.json b/packages/workshop/package.json index 8e031bac5..06e595211 100644 --- a/packages/workshop/package.json +++ b/packages/workshop/package.json @@ -29,7 +29,6 @@ "@tanstack/react-query": "catalog:", "pocketbase": "catalog:", "react": "catalog:", - "tr46": "6.0.0", "zod": "catalog:" }, "devDependencies": { diff --git a/packages/workshop/src/pocketbase-url.spec.ts b/packages/workshop/src/pocketbase-url.spec.ts deleted file mode 100644 index 02237e465..000000000 --- a/packages/workshop/src/pocketbase-url.spec.ts +++ /dev/null @@ -1,215 +0,0 @@ -import { describe, expect, test } from "vitest"; - -import { CUSTOM_WIDGET_STARTER, customWidgetDefinitionSchema } from "@homarr/custom-widgets/core"; - -import { PocketBaseUrl } from "./pocketbase-url"; - -describe("PocketBase URL compatibility", () => { - test.each([ - "https://example.com", - "https://example.com.", - "https://münich.example", - "https://xn--mnich-kva.example", - "http://example.com:0", - "http://example.com:", - "http://example.com:80", - "http://[::1]:8090", - "http://[::ffff:192.168.1.1]", - ])("accepts canonical URL %s", (value) => { - expect(URL.canParse(value)).toBe(true); - expect(PocketBaseUrl.canParse(value)).toBe(true); - }); - - test.each([ - "http://", - "https://:", - "http://1.2.3.4.5", - "http://09.0.0.1", - "http://099.0.0.1", - "http://[:::1]", - "http://[:1:2:3:4:5:6:7:8]", - "http://[1:2:3:4:5:6:7:8:]", - "http://[192.168.1.1::]", - "http://[::ffff:192.168.001.001]", - "http://[::ffff:192.168.1.01]", - "http://[fe80::1%25eth0]", - "http://example.com:65536", - "https://xn--a.example", - "https://xn--0.example", - "https://xn--abc.example", - ])("rejects canonical invalid URL %s", (value) => { - expect(URL.canParse(value)).toBe(false); - expect(PocketBaseUrl.canParse(value)).toBe(false); - }); - - test.each([ - "http://127.1", - "http://2130706433", - "http://0x7f000001", - "http://0177.0.0.1", - "http://1.2.3", - "http://%31%32%37.0.0.1", - "https://%65xample.com", - "https://example%2ecom", - "https://example.com\\@attacker.invalid", - "https:\\\\example.com\\api", - "https://-example.com", - "https://example-.com", - "https://example..com", - "https://example.com:00080", - "https://example.com:0000000065535", - "https://example。com", - "https://127.0.0.1", - " https://example.com", - "https://exa\tmple.com", - "https://example.com/path\u00a0", - ])("conservatively rejects WHATWG-normalized URL %s", (value) => { - expect(URL.canParse(value)).toBe(true); - expect(PocketBaseUrl.canParse(value)).toBe(false); - }); - - test("normalizes international hostnames like the native parser", () => { - expect(new PocketBaseUrl("https://münich.example").hostname).toBe("xn--mnich-kva.example"); - expect(new PocketBaseUrl("https://例え.テスト.").hostname).toBe("xn--r8jz45g.xn--zckzah."); - }); - - test("normalizes IPv6 hostnames like the native parser", () => { - expect(new PocketBaseUrl("http://[1:2:3:4:5:6:7::]").hostname).toBe("[1:2:3:4:5:6:7:0]"); - expect(new PocketBaseUrl("http://[::ffff:192.168.1.1]").hostname).toBe("[::ffff:c0a8:101]"); - }); - - test.each([ - "https://example.com", - "https://example.com.", - "https://münich.example", - "https://例え.テスト", - "https://xn--r8jz45g.xn--zckzah", - "http://192.168.1.1:0", - "https://[2001:db8::1]:65535", - "https://[::ffff:192.168.1.1]", - "http://0.0.0.0", - "http://255.255.255.255", - "https://example.com:", - "https://example.com:0", - "https://example.com:65535", - "http://[::]", - "http://[::1]", - "http://[1:2:3:4:5:6:7:8]", - "http://[1:2:3:4:5:6:7::]", - "https://faß.de", - "https://xn--fa-hia.de", - "https://مثال.إختبار", - "https://a_b.example", - "https://example.com/%5c@evil", - "https://example.com/%2f%2fevil", - "https://example.com/icon.svg?next=https%3A%2F%2Fevil#preview", - "http://127.1", - "http://2130706433", - "http://0x7f000001", - "http://0xffffffff", - "http://0x100000000", - "http://0177.0.0.1", - "http://0377.0377.0377.0377", - "http://1.2.3", - "http://1.", - "http://1..2", - "http://256.0.0.1", - "http://00.0.0.0", - "http://%31%32%37.0.0.1", - "https://%65xample.com", - "https://example%2ecom", - "https://example.com\\@attacker.invalid", - "https:\\\\example.com\\api", - " https://example.com", - "https://exa\tmple.com", - "https://example.com\n", - "https://example.com\u00a0", - "https://@example.com", - "https://:@example.com", - "https://example。com", - "https://127.0.0.1", - "https://-example.com", - "https://example-.com", - "https://example..com", - "https://example.com:01", - "https://example.com:00080", - "https://example.com:0000000065535", - "https://example.com:65536", - "https://example.com:655350", - "https://[fe80::1%25eth0]", - "https://[::ffff:192.168.001.001]", - "https://[1:2:3:4:5:6:7:8:9]", - "https://\u200d.example", - "http:example.com", - "https:/example.com", - "https:///example.com", - "ftp://example.com", - "file:///tmp/icon.svg", - "https://user:password@example.com", - ])("keeps canonical source and icon validation in parity for %s", (value) => { - const validate = (UrlImplementation: typeof URL, field: "source" | "icon") => { - const runtime = globalThis as unknown as { URL: typeof URL }; - const originalUrl = runtime.URL; - runtime.URL = UrlImplementation; - try { - const definition = - field === "source" - ? { - ...CUSTOM_WIDGET_STARTER, - sources: { - default: { ...CUSTOM_WIDGET_STARTER.sources.default, baseUrl: value }, - }, - } - : { ...CUSTOM_WIDGET_STARTER, iconUrl: value }; - return customWidgetDefinitionSchema.safeParse(definition).success; - } finally { - runtime.URL = originalUrl; - } - }; - - const nativeUrl = URL; - expect(validate(PocketBaseUrl as unknown as typeof URL, "source")).toBe(validate(nativeUrl, "source")); - expect(validate(PocketBaseUrl as unknown as typeof URL, "icon")).toBe(validate(nativeUrl, "icon")); - }); - - test("exposes the URL fields used by the canonical schema", () => { - const url = new PocketBaseUrl("https://user:password@example.com:8443/icon.svg?token=secret&mode=dark#icon"); - expect(url).toMatchObject({ - protocol: "https:", - username: "user", - password: "password", - hostname: "example.com", - port: "8443", - search: "?token=secret&mode=dark", - hash: "#icon", - }); - expect(url.searchParams.keys()).toEqual(["token", "mode"]); - }); - - test("validates credential queries without iterable URLSearchParams", () => { - const runtime = globalThis as unknown as { URL: typeof URL }; - const originalUrl = runtime.URL; - runtime.URL = PocketBaseUrl as unknown as typeof URL; - try { - expect( - customWidgetDefinitionSchema.safeParse({ - ...CUSTOM_WIDGET_STARTER, - iconUrl: "https://example.com/icon.svg?clientSecret=must-never-be-published", - }).success, - ).toBe(false); - expect( - customWidgetDefinitionSchema.safeParse({ - ...CUSTOM_WIDGET_STARTER, - requests: { - default: { - ...CUSTOM_WIDGET_STARTER.requests.default, - path: "/api/status?key=status&auth=none", - }, - }, - }).success, - ).toBe(true); - } finally { - runtime.URL = originalUrl; - } - }); -}); diff --git a/packages/workshop/src/pocketbase-url.ts b/packages/workshop/src/pocketbase-url.ts deleted file mode 100644 index a6161c41c..000000000 --- a/packages/workshop/src/pocketbase-url.ts +++ /dev/null @@ -1,259 +0,0 @@ -import { toASCII } from "tr46"; - -interface PortableSearchParams { - keys(): string[]; -} - -interface ParsedAuthority { - username: string; - password: string; - hostname: string; - port: string; -} - -/** - * PocketBase's Goja runtime intentionally has no browser URL global. The - * canonical Custom Widget schema uses the small subset implemented here. - */ -export class PocketBaseUrl { - public readonly protocol: string; - public readonly username: string; - public readonly password: string; - public readonly hostname: string; - public readonly port: string; - public readonly search: string; - public readonly hash: string; - public readonly origin: string; - public readonly searchParams: PortableSearchParams; - - public static canParse(value: unknown): boolean { - try { - const parsed = new PocketBaseUrl(value); - void parsed; - return true; - } catch { - return false; - } - } - - public constructor(value: unknown) { - if (typeof value !== "string" || hasForbiddenUrlCharacter(value) || value.includes("\\")) { - throw new TypeError("Invalid URL"); - } - - const scheme = value.match(/^([A-Za-z][A-Za-z0-9+.-]*):/u); - if (!scheme?.[1]) throw new TypeError("Invalid URL"); - this.protocol = `${scheme[1].toLowerCase()}:`; - - const afterScheme = value.slice(scheme[0].length); - const hashIndex = afterScheme.indexOf("#"); - const withoutHash = hashIndex < 0 ? afterScheme : afterScheme.slice(0, hashIndex); - this.hash = hashIndex < 0 ? "" : afterScheme.slice(hashIndex); - const searchIndex = withoutHash.indexOf("?"); - const withoutSearch = searchIndex < 0 ? withoutHash : withoutHash.slice(0, searchIndex); - this.search = searchIndex < 0 ? "" : withoutHash.slice(searchIndex); - this.searchParams = createSearchParams(this.search); - - const requiresAuthority = this.protocol === "http:" || this.protocol === "https:" || this.protocol === "ftp:"; - if (!withoutSearch.startsWith("//")) { - if (requiresAuthority) throw new TypeError("Invalid URL"); - this.username = ""; - this.password = ""; - this.hostname = ""; - this.port = ""; - this.origin = "null"; - return; - } - - const authorityAndPath = withoutSearch.slice(2); - const slashIndex = authorityAndPath.indexOf("/"); - const authority = slashIndex < 0 ? authorityAndPath : authorityAndPath.slice(0, slashIndex); - const parsed = parseAuthority(authority); - this.username = parsed.username; - this.password = parsed.password; - this.hostname = parsed.hostname; - this.port = parsed.port; - this.origin = `${this.protocol}//${this.hostname}${this.port ? `:${this.port}` : ""}`; - } -} - -export function installPocketBaseUrlPolyfill(): void { - const runtime = globalThis as unknown as Record; - if (typeof runtime.URL === "undefined") runtime.URL = PocketBaseUrl; -} - -function parseAuthority(authority: string): ParsedAuthority { - if (!authority || /[。.。]/u.test(authority)) throw new TypeError("Invalid URL"); - const atIndex = authority.lastIndexOf("@"); - const credentials = atIndex < 0 ? "" : authority.slice(0, atIndex); - const hostAndPort = atIndex < 0 ? authority : authority.slice(atIndex + 1); - if (!hostAndPort) throw new TypeError("Invalid URL"); - - const credentialSeparator = credentials.indexOf(":"); - const username = credentialSeparator < 0 ? credentials : credentials.slice(0, credentialSeparator); - const password = credentialSeparator < 0 ? "" : credentials.slice(credentialSeparator + 1); - - let hostname: string; - let port = ""; - if (hostAndPort.startsWith("[")) { - const closeIndex = hostAndPort.indexOf("]"); - if (closeIndex < 0) throw new TypeError("Invalid URL"); - const address = hostAndPort.slice(1, closeIndex); - const normalizedAddress = normalizeIpv6(address); - if (normalizedAddress === null) throw new TypeError("Invalid URL"); - hostname = `[${normalizedAddress}]`; - const suffix = hostAndPort.slice(closeIndex + 1); - if (suffix) { - if (!suffix.startsWith(":")) throw new TypeError("Invalid URL"); - port = suffix.length === 1 ? "" : validatePort(suffix.slice(1)); - } - } else { - const firstColon = hostAndPort.indexOf(":"); - const lastColon = hostAndPort.lastIndexOf(":"); - if (firstColon !== lastColon) throw new TypeError("Invalid URL"); - hostname = firstColon < 0 ? hostAndPort : hostAndPort.slice(0, firstColon); - const portValue = firstColon < 0 ? "" : hostAndPort.slice(firstColon + 1); - port = portValue ? validatePort(portValue) : ""; - const normalizedHostname = normalizeHostname(hostname); - if (!normalizedHostname) throw new TypeError("Invalid URL"); - hostname = normalizedHostname; - } - - return { username, password, hostname: hostname.toLowerCase(), port }; -} - -function validatePort(value: string): string { - if (!/^(?:0|[1-9]\d{0,4})$/u.test(value)) throw new TypeError("Invalid URL"); - const port = Number(value); - if (!Number.isInteger(port) || port > 65_535) throw new TypeError("Invalid URL"); - return String(port); -} - -function normalizeHostname(value: string): string | null { - const ascii = toASCII(value, { - checkHyphens: false, - checkBidi: true, - checkJoiners: true, - useSTD3ASCIIRules: false, - transitionalProcessing: false, - verifyDNSLength: false, - ignoreInvalidPunycode: false, - }); - if (!ascii || hasForbiddenUrlCharacter(ascii) || /[#%/:<>?@[\\\]^|]/u.test(ascii)) return null; - const candidate = ascii.endsWith(".") ? ascii.slice(0, -1) : ascii; - if (!candidate || candidate.length > 253 || !/^[A-Za-z0-9._-]+$/u.test(candidate)) return null; - if (looksNumeric(candidate)) { - const rawCandidate = value.endsWith(".") ? value.slice(0, -1) : value; - return isStrictIpv4(candidate) && rawCandidate === candidate ? ascii.toLowerCase() : null; - } - const isValid = candidate - .split(".") - .every((part) => Boolean(part) && part.length <= 63 && !part.startsWith("-") && !part.endsWith("-")); - return isValid ? ascii.toLowerCase() : null; -} - -function hasForbiddenUrlCharacter(value: string): boolean { - return [...value].some((character) => { - const code = character.codePointAt(0) ?? 0; - return ( - code <= 0x20 || - (code >= 0x7f && code <= 0xa0) || - code === 0x1680 || - (code >= 0x2000 && code <= 0x200f) || - (code >= 0x2028 && code <= 0x202f) || - (code >= 0x205f && code <= 0x206f) || - code === 0x3000 || - code === 0xfeff - ); - }); -} - -function normalizeIpv6(value: string): string | null { - if (value.includes("%")) return null; - const address = value; - if (!address.includes(":") || address.includes(":::") || /[^0-9A-Fa-f:.]/u.test(address)) return null; - if (address.indexOf("::") !== address.lastIndexOf("::")) return null; - if ((address.startsWith(":") && !address.startsWith("::")) || (address.endsWith(":") && !address.endsWith("::"))) { - return null; - } - - const hasCompression = address.includes("::"); - const [left = "", right = ""] = hasCompression ? address.split("::") : [address, ""]; - if (hasCompression && left.includes(".")) return null; - const leftGroups = parseIpv6Groups(left); - const rightGroups = parseIpv6Groups(right); - if (leftGroups === null || rightGroups === null) return null; - - const explicitGroupCount = leftGroups.length + rightGroups.length; - if ((!hasCompression && explicitGroupCount !== 8) || (hasCompression && explicitGroupCount >= 8)) return null; - - const groups = hasCompression - ? [...leftGroups, ...Array.from({ length: 8 - explicitGroupCount }, () => 0), ...rightGroups] - : leftGroups; - let bestStart = -1; - let bestLength = 1; - for (let index = 0; index < groups.length;) { - if (groups[index] !== 0) { - index += 1; - continue; - } - let end = index + 1; - while (end < groups.length && groups[end] === 0) end += 1; - if (end - index > bestLength) { - bestStart = index; - bestLength = end - index; - } - index = end; - } - - const hexadecimalGroups = groups.map((group) => group.toString(16)); - if (bestStart < 0) return hexadecimalGroups.join(":"); - const before = hexadecimalGroups.slice(0, bestStart).join(":"); - const after = hexadecimalGroups.slice(bestStart + bestLength).join(":"); - return `${before}::${after}`; -} - -function parseIpv6Groups(value: string): number[] | null { - if (!value) return []; - const groups = value.split(":"); - const parsed: number[] = []; - for (const [index, group] of groups.entries()) { - if (group.includes(".")) { - if (index !== groups.length - 1 || !isStrictIpv4(group)) return null; - const parts = group.split(".").map(Number); - parsed.push(((parts[0] ?? 0) << 8) | (parts[1] ?? 0), ((parts[2] ?? 0) << 8) | (parts[3] ?? 0)); - } else { - if (!/^[0-9A-Fa-f]{1,4}$/u.test(group)) return null; - parsed.push(Number.parseInt(group, 16)); - } - } - return parsed; -} - -function isStrictIpv4(value: string): boolean { - const parts = value.split("."); - return parts.length === 4 && parts.every((part) => /^(?:0|[1-9]\d{0,2})$/u.test(part) && Number(part) <= 255); -} - -function looksNumeric(value: string): boolean { - return value.split(".").every((part) => /^(?:\d+|0[xX][0-9A-Fa-f]+)$/u.test(part)); -} - -function createSearchParams(search: string): PortableSearchParams { - const keys = search - ? search - .slice(1) - .split("&") - .map((entry) => entry.split("=", 1)[0] ?? "") - .map(decodeQueryPart) - : []; - return { keys: () => [...keys] }; -} - -function decodeQueryPart(value: string): string { - try { - return decodeURIComponent(value.replaceAll("+", " ")); - } catch { - return value; - } -} diff --git a/packages/workshop/src/tr46.d.ts b/packages/workshop/src/tr46.d.ts deleted file mode 100644 index 50dc8bd59..000000000 --- a/packages/workshop/src/tr46.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -declare module "tr46" { - interface ToAsciiOptions { - checkHyphens?: boolean; - checkBidi?: boolean; - checkJoiners?: boolean; - useSTD3ASCIIRules?: boolean; - transitionalProcessing?: boolean; - verifyDNSLength?: boolean; - ignoreInvalidPunycode?: boolean; - } - - export function toASCII(value: string, options?: ToAsciiOptions): string | null; -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 80f18ac9a..14ee90a53 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2949,9 +2949,6 @@ importers: pocketbase: specifier: 'catalog:' version: 0.26.9 - tr46: - specifier: 6.0.0 - version: 6.0.0 react: specifier: 'catalog:' version: 19.2.7